[SCM] Samba Shared Repository - branch master updated
Günther Deschner
gd at samba.org
Mon May 31 07:31:24 MDT 2010
The branch, master has been updated
via 9864164... s3-netlogon: use LSA in _netr_NetrEnumerateTrustedDomains.
via 4bb7e91... s3-netlogon: use SAMR in _netr_ServerAuthenticate3.
via db5730c... s3-samr: give the system user a free pass for _samr_QueryUserInfo{2} level 18.
via 3f24f8d... s3-auth: add "system" bool flag to auth_serversupplied_info.
via a780581... s3-netlogon: use SAMR in _netr_ServerPasswordSet{2}.
from 62708fb... s3:ntlmssp Move ntlmssp_sign.c from source3 to common code.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 98641648d8ec66a0c3e07a73e4275005bfa25811
Author: Günther Deschner <gd at samba.org>
Date: Fri May 28 15:31:35 2010 +0200
s3-netlogon: use LSA in _netr_NetrEnumerateTrustedDomains.
Guenther
commit 4bb7e91cfd9071e570c56bca36d35202d01ca80d
Author: Günther Deschner <gd at samba.org>
Date: Fri May 28 14:22:08 2010 +0200
s3-netlogon: use SAMR in _netr_ServerAuthenticate3.
Guenther
commit db5730cac4d6e0b64913bce21147352344077e2b
Author: Günther Deschner <gd at samba.org>
Date: Fri May 28 14:21:15 2010 +0200
s3-samr: give the system user a free pass for _samr_QueryUserInfo{2} level 18.
Guenther
commit 3f24f8d2c69be1db28cb1ffb866d45b520d9544d
Author: Günther Deschner <gd at samba.org>
Date: Fri May 28 14:19:28 2010 +0200
s3-auth: add "system" bool flag to auth_serversupplied_info.
Guenther
commit a7805811c432adb9b0e82039858269c2154521ae
Author: Günther Deschner <gd at samba.org>
Date: Fri May 28 12:39:12 2010 +0200
s3-netlogon: use SAMR in _netr_ServerPasswordSet{2}.
Guenther
-----------------------------------------------------------------------
Summary of changes:
source3/auth/auth_util.c | 11 +-
source3/include/auth.h | 1 +
source3/rpc_server/srv_netlog_nt.c | 466 +++++++++++++++++++++++-------------
source3/rpc_server/srv_samr_nt.c | 5 +
4 files changed, 320 insertions(+), 163 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 1f9bc7b..74d8873 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -765,16 +765,24 @@ static NTSTATUS make_new_server_info_system(TALLOC_CTX *mem_ctx,
struct auth_serversupplied_info **server_info)
{
struct passwd *pwd;
+ NTSTATUS status;
pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
if (pwd == NULL) {
return NT_STATUS_NO_MEMORY;
}
- return make_serverinfo_from_username(mem_ctx,
+ status = make_serverinfo_from_username(mem_ctx,
pwd->pw_name,
false,
server_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ (*server_info)->system = true;
+
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -829,6 +837,7 @@ struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
}
dst->guest = src->guest;
+ dst->system = src->system;
dst->utok.uid = src->utok.uid;
dst->utok.gid = src->utok.gid;
dst->utok.ngroups = src->utok.ngroups;
diff --git a/source3/include/auth.h b/source3/include/auth.h
index ed422c2..69a91d2 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -42,6 +42,7 @@ struct auth_usersupplied_info {
struct auth_serversupplied_info {
bool guest;
+ bool system;
struct dom_sid *sids; /* These SIDs are preliminary between
check_ntlm_password and the token creation. */
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index f0b9bab..4bd176c 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -27,6 +27,11 @@
#include "includes.h"
#include "../libcli/auth/schannel.h"
#include "../librpc/gen_ndr/srv_netlogon.h"
+#include "../librpc/gen_ndr/srv_samr.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/cli_samr.h"
+#include "../librpc/gen_ndr/cli_lsa.h"
+#include "rpc_client/cli_lsarpc.h"
#include "librpc/gen_ndr/messaging.h"
#include "../lib/crypto/md4.h"
@@ -389,39 +394,77 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
{
NTSTATUS status;
DATA_BLOB blob;
- struct trustdom_info **domains;
- uint32_t num_domains;
- const char **trusted_domains;
+ int num_domains = 0;
+ const char **trusted_domains = NULL;
+ struct lsa_DomainList domain_list;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle pol;
+ uint32_t enum_ctx = 0;
int i;
+ uint32_t max_size = (uint32_t)-1;
DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
- /* set up the Trusted Domain List response */
-
- become_root();
- status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
- unbecome_root();
-
+ status = rpc_pipe_open_internal(p->mem_ctx, &ndr_table_lsarpc.syntax_id,
+ rpc_lsarpc_dispatch, p->server_info,
+ &cli);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- trusted_domains = talloc_zero_array(p->mem_ctx, const char *, num_domains + 1);
+ trusted_domains = talloc_zero_array(p->mem_ctx, const char *, num_domains);
if (!trusted_domains) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
- for (i = 0; i < num_domains; i++) {
- trusted_domains[i] = talloc_strdup(trusted_domains, domains[i]->name);
- if (!trusted_domains[i]) {
- TALLOC_FREE(trusted_domains);
- return NT_STATUS_NO_MEMORY;
+ status = rpccli_lsa_open_policy2(cli, p->mem_ctx,
+ true,
+ LSA_POLICY_VIEW_LOCAL_INFORMATION,
+ &pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = STATUS_MORE_ENTRIES;
+
+ while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
+
+ /* Lookup list of trusted domains */
+
+ status = rpccli_lsa_EnumTrustDom(cli, p->mem_ctx,
+ &pol,
+ &enum_ctx,
+ &domain_list,
+ max_size);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES) &&
+ !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
+ goto out;
+ }
+
+ for (i = 0; i < domain_list.count; i++) {
+ if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
+ &trusted_domains, &num_domains)) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
}
}
+ /* multi sz terminate */
+ trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
+ if (trusted_domains == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ trusted_domains[num_domains+1] = NULL;
+
if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
TALLOC_FREE(trusted_domains);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
r->out.trusted_domains_blob->data = blob.data;
@@ -429,7 +472,118 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
- return NT_STATUS_OK;
+ status = NT_STATUS_OK;
+
+ out:
+ if (cli && is_valid_policy_hnd(&pol)) {
+ rpccli_lsa_Close(cli, p->mem_ctx, &pol);
+ }
+
+ return status;
+}
+
+/*************************************************************************
+ *************************************************************************/
+
+static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *cli,
+ const char *account_name,
+ uint32_t access_mask,
+ struct dom_sid2 **domain_sid_p,
+ uint32_t *user_rid_p,
+ struct policy_handle *user_handle)
+{
+ NTSTATUS status;
+ struct policy_handle connect_handle, domain_handle;
+ struct lsa_String domain_name;
+ struct dom_sid2 *domain_sid;
+ struct lsa_String names;
+ struct samr_Ids rids;
+ struct samr_Ids types;
+ uint32_t rid;
+
+ status = rpccli_samr_Connect2(cli, mem_ctx,
+ global_myname(),
+ SAMR_ACCESS_CONNECT_TO_SERVER |
+ SAMR_ACCESS_ENUM_DOMAINS |
+ SAMR_ACCESS_LOOKUP_DOMAIN,
+ &connect_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ init_lsa_String(&domain_name, get_global_sam_name());
+
+ status = rpccli_samr_LookupDomain(cli, mem_ctx,
+ &connect_handle,
+ &domain_name,
+ &domain_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = rpccli_samr_OpenDomain(cli, mem_ctx,
+ &connect_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+ domain_sid,
+ &domain_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ init_lsa_String(&names, account_name);
+
+ status = rpccli_samr_LookupNames(cli, mem_ctx,
+ &domain_handle,
+ 1,
+ &names,
+ &rids,
+ &types);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ if (rids.count != 1) {
+ status = NT_STATUS_NO_SUCH_USER;
+ goto out;
+ }
+ if (rids.count != types.count) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ if (types.ids[0] != SID_NAME_USER) {
+ status = NT_STATUS_NO_SUCH_USER;
+ goto out;
+ }
+
+ rid = rids.ids[0];
+
+ status = rpccli_samr_OpenUser(cli, mem_ctx,
+ &domain_handle,
+ access_mask,
+ rid,
+ user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ if (user_rid_p) {
+ *user_rid_p = rid;
+ }
+
+ if (domain_sid_p) {
+ *domain_sid_p = domain_sid;
+ }
+
+ out:
+ if (cli && is_valid_policy_hnd(&domain_handle)) {
+ rpccli_samr_Close(cli, mem_ctx, &domain_handle);
+ }
+ if (cli && is_valid_policy_hnd(&connect_handle)) {
+ rpccli_samr_Close(cli, mem_ctx, &connect_handle);
+ }
+
+ return status;
}
/******************************************************************
@@ -439,11 +593,15 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
enum netr_SchannelType sec_chan_type, struct dom_sid *sid)
{
- struct samu *sampass = NULL;
- const uint8 *pass;
- bool ret;
- uint32 acct_ctrl;
-
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle user_handle;
+ uint32_t user_rid;
+ struct dom_sid *domain_sid;
+ uint32_t acct_ctrl;
+ union samr_UserInfo *info;
+ struct auth_serversupplied_info *server_info;
#if 0
char addr[INET6_ADDRSTRLEN];
@@ -464,26 +622,50 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
}
#endif /* 0 */
- if ( !(sampass = samu_new( NULL )) ) {
- return NT_STATUS_NO_MEMORY;
+ mem_ctx = talloc_new(talloc_tos());
+ if (mem_ctx == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ status = make_server_info_system(mem_ctx, &server_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ ZERO_STRUCT(user_handle);
+
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ rpc_samr_dispatch, server_info,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- /* JRA. This is ok as it is only used for generating the challenge. */
become_root();
- ret = pdb_getsampwnam(sampass, mach_acct);
+ status = samr_find_machine_account(mem_ctx, cli, mach_acct,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &domain_sid, &user_rid,
+ &user_handle);
unbecome_root();
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- if (!ret) {
- DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_ACCESS_DENIED;
+ status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
+ &user_handle,
+ UserControlInformation,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- acct_ctrl = pdb_get_acct_ctrl(sampass);
+ acct_ctrl = info->info16.acct_flags;
+
if (acct_ctrl & ACB_DISABLED) {
DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_ACCOUNT_DISABLED;
+ status = NT_STATUS_ACCOUNT_DISABLED;
+ goto out;
}
if (!(acct_ctrl & ACB_SVRTRUST) &&
@@ -491,8 +673,8 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
!(acct_ctrl & ACB_DOMTRUST))
{
DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ goto out;
}
switch (sec_chan_type) {
@@ -500,46 +682,58 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
if (!(acct_ctrl & ACB_SVRTRUST)) {
DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
"but not a server trust account\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ goto out;
}
break;
case SEC_CHAN_WKSTA:
if (!(acct_ctrl & ACB_WSTRUST)) {
DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
"but not a workstation trust account\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ goto out;
}
break;
case SEC_CHAN_DOMAIN:
if (!(acct_ctrl & ACB_DOMTRUST)) {
DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
"but not a interdomain trust account\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+ goto out;
}
break;
default:
break;
}
- if ((pass = pdb_get_nt_passwd(sampass)) == NULL) {
+ become_root();
+ status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
+ &user_handle,
+ UserInternal1Information,
+ &info);
+ unbecome_root();
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ if (info->info18.nt_pwd_active == 0) {
DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
- TALLOC_FREE(sampass);
- return NT_STATUS_LOGON_FAILURE;
+ status = NT_STATUS_LOGON_FAILURE;
+ goto out;
}
- memcpy(md4pw->hash, pass, 16);
- dump_data(5, md4pw->hash, 16);
+ /* samr gives out nthash unencrypted (!) */
+ memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
- sid_copy(sid, pdb_get_user_sid(sampass));
+ sid_compose(sid, domain_sid, user_rid);
- TALLOC_FREE(sampass);
-
- return NT_STATUS_OK;
+ out:
+ if (cli && is_valid_policy_hnd(&user_handle)) {
+ rpccli_samr_Close(cli, mem_ctx, &user_handle);
+ }
+ talloc_free(mem_ctx);
+ return status;
}
/*************************************************************************
@@ -829,114 +1023,82 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
/*************************************************************************
*************************************************************************/
-static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
- const char *account_name,
- struct samu **sampassp)
+static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ const char *account_name,
+ struct samr_Password *nt_hash)
{
- struct samu *sampass;
- bool ret = false;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle user_handle;
uint32_t acct_ctrl;
+ union samr_UserInfo *info;
+ struct samr_UserInfo18 info18;
+ DATA_BLOB in,out;
- sampass = samu_new(mem_ctx);
- if (!sampass) {
- return NT_STATUS_NO_MEMORY;
- }
+ ZERO_STRUCT(user_handle);
- become_root();
- ret = pdb_getsampwnam(sampass, account_name);
- unbecome_root();
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ rpc_samr_dispatch, server_info,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- if (!ret) {
- TALLOC_FREE(sampass);
- return NT_STATUS_ACCESS_DENIED;
+ status = samr_find_machine_account(mem_ctx, cli, account_name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ NULL, NULL,
+ &user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- /* Ensure the account exists and is a machine account. */
+ status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
--
Samba Shared Repository
More information about the samba-cvs
mailing list