[SCM] Samba Shared Repository - branch v3-4-test updated - release-4-0-0alpha7-1022-gc79ceb3

Jeremy Allison jra at samba.org
Mon May 18 21:29:43 GMT 2009


The branch, v3-4-test has been updated
       via  c79ceb3345c56cff28b5e828188611c5fc80b1a7 (commit)
       via  5c3c7f6921c9cff58cf4f85c0b691566bf4cd02e (commit)
       via  72f90581a78443efd6cf24bac635fe9032df18fd (commit)
       via  361caafeebb37f6247f7ede38a50a70323fdd107 (commit)
       via  c0ff7e5459bdf1351f6cb69e58a1f8105bcfd3dc (commit)
       via  6d0981845ec005a48a82280e2ebfe85ac9b72537 (commit)
       via  c7e6db566ad2bd5ea6473753a720a9ccc9772b59 (commit)
       via  42ad75c9d31f6101103870e1055a7cd4b7f149fd (commit)
       via  bdc797135151d4f85e6368d016bfb26389c6f055 (commit)
      from  9db1fc45786872d938939bd33b3b867ee599c9a2 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit c79ceb3345c56cff28b5e828188611c5fc80b1a7
Author: Guenther Deschner <gd at samba.org>
Date:   Fri May 15 18:11:30 2009 -0700

    s3-samr: Fix samr access checks in _samr_SetUserInfo().
    
    Guenther

commit 5c3c7f6921c9cff58cf4f85c0b691566bf4cd02e
Author: Guenther Deschner <gd at samba.org>
Date:   Fri May 15 18:03:34 2009 -0700

    s3-samr: Fix samr access checks in _samr_QueryUserInfo().
    
    Guenther

commit 72f90581a78443efd6cf24bac635fe9032df18fd
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 15 17:55:41 2009 -0700

    Ensure users with SeAddUser privs get full access to
    groups/aliases when opening.
    Jeremy.

commit 361caafeebb37f6247f7ede38a50a70323fdd107
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 15 17:54:27 2009 -0700

    Add extra abilities for a user with SeAddUsers, so they
    can manipulate groups and aliases.
    Jeremy.

commit c0ff7e5459bdf1351f6cb69e58a1f8105bcfd3dc
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 15 17:52:40 2009 -0700

    DeleteUser doesn't need the priv checks, this is done at OpenUser time.
    Jeremy.

commit 6d0981845ec005a48a82280e2ebfe85ac9b72537
Author: Guenther Deschner <gd at samba.org>
Date:   Fri May 15 17:50:49 2009 -0700

    s3-samr: Fix samr access checks in _samr_RemoveMemberFromForeignDomain().
    
    Guenther

commit c7e6db566ad2bd5ea6473753a720a9ccc9772b59
Author: Guenther Deschner <gd at samba.org>
Date:   Fri May 15 17:49:02 2009 -0700

    s3-samr: Fix samr access checks in _samr_SetDomainInfo().
    
    Guenther

commit 42ad75c9d31f6101103870e1055a7cd4b7f149fd
Author: Guenther Deschner <gd at samba.org>
Date:   Fri May 15 17:47:16 2009 -0700

    s3-samr: Fix samr access checks in _samr_QueryDomainInfo().
    
    Guenther

commit bdc797135151d4f85e6368d016bfb26389c6f055
Author: Jeremy Allison <jra at samba.org>
Date:   Fri May 15 17:43:41 2009 -0700

    Fix the core of the SAMR access functions. This passes make test, but
    usrmgr fails against it. The core of this patch is to move all the
    access mask setup into the _samr_OpenXXX functions, and then have
    each specific function check the attached access_mask against the
    required bits. We can then go through the MS-SAMR doc and match
    things up. Signed off by Guenther, and writespace cleanup removal
    by Volker.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source3/rpc_server/srv_samr_nt.c |  608 ++++++++++++++++++++++++--------------
 1 files changed, 384 insertions(+), 224 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 24cf8a7..d73c25d 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -176,7 +176,8 @@ static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
 	   by privileges (mostly having to do with creating/modifying/deleting
 	   users and groups) */
 
-	if ( rights && user_has_any_privilege( token, rights ) ) {
+	if (rights && !se_priv_equal(rights, &se_priv_none) &&
+			user_has_any_privilege(token, rights)) {
 
 		saved_mask = (des_access & rights_mask);
 		des_access &= ~saved_mask;
@@ -604,6 +605,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
 	uint32    des_access = r->in.access_mask;
 	NTSTATUS  status;
 	size_t    sd_size;
+	uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
 	SE_PRIV se_rights;
 
 	/* find the connection policy handle. */
@@ -617,11 +619,27 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
 	make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
 	se_map_generic( &des_access, &dom_generic_mapping );
 
+	/*
+	 * Users with SeMachineAccount or SeAddUser get additional
+	 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
+	 */
 	se_priv_copy( &se_rights, &se_machine_account );
 	se_priv_add( &se_rights, &se_add_users );
 
+	/*
+	 * Users with SeAddUser get the ability to manipulate groups
+	 * and aliases.
+	 */
+	if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
+		extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
+				SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
+				SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
+				SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
+				SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
+	}
+
 	status = access_check_samr_object( psd, p->server_info->ptok,
-		&se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
+		&se_rights, extra_access, des_access,
 		&acc_granted, "_samr_OpenDomain" );
 
 	if ( !NT_STATUS_IS_OK(status) )
@@ -2301,6 +2319,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 	SEC_DESC *psd = NULL;
 	uint32    acc_granted;
 	uint32    des_access = r->in.access_mask;
+	uint32_t extra_access = 0;
 	size_t    sd_size;
 	bool ret;
 	NTSTATUS nt_status;
@@ -2334,8 +2353,70 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
 	se_map_generic(&des_access, &usr_generic_mapping);
 
-	se_priv_copy( &se_rights, &se_machine_account );
-	se_priv_add( &se_rights, &se_add_users );
+	/*
+	 * Get the sampass first as we need to check privilages
+	 * based on what kind of user object this is.
+	 * But don't reveal info too early if it didn't exist.
+	 */
+
+	become_root();
+	ret=pdb_getsampwsid(sampass, &sid);
+	unbecome_root();
+
+	se_priv_copy(&se_rights, &se_priv_none);
+
+	/*
+	 * We do the override access checks on *open*, not at
+	 * SetUserInfo time.
+	 */
+	if (ret) {
+		uint32_t acb_info = pdb_get_acct_ctrl(sampass);
+
+		if ((acb_info & ACB_WSTRUST) &&
+			user_has_any_privilege(p->server_info->ptok,
+					&se_machine_account)) {
+			/*
+			 * SeMachineAccount is needed to add
+			 * GENERIC_RIGHTS_USER_WRITE to a machine
+			 * account.
+			 */
+			se_priv_add(&se_rights, &se_machine_account);
+			DEBUG(10,("_samr_OpenUser: adding machine account "
+				"rights to handle for user %s\n",
+				pdb_get_username(sampass) ));
+		}
+		if ((acb_info & ACB_NORMAL) &&
+				user_has_any_privilege(p->server_info->ptok,
+					&se_add_users)) {
+			/*
+			 * SeAddUsers is needed to add
+ 			 * GENERIC_RIGHTS_USER_WRITE to a normal
+			 * account.
+			 */
+			se_priv_add(&se_rights, &se_add_users);
+			DEBUG(10,("_samr_OpenUser: adding add user "
+				"rights to handle for user %s\n",
+				pdb_get_username(sampass) ));
+		}
+		/*
+		 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
+		 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
+		 * what Windows does but is a hack for people who haven't
+		 * set up privilages on groups in Samba.
+		 */
+		if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
+			if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
+					DOMAIN_GROUP_RID_ADMINS)) {
+				des_access &= ~GENERIC_RIGHTS_USER_WRITE;
+				extra_access = GENERIC_RIGHTS_USER_WRITE;
+				DEBUG(4,("_samr_OpenUser: Allowing "
+					"GENERIC_RIGHTS_USER_WRITE for "
+					"rid admins\n"));
+			}
+		}
+	}
+
+	TALLOC_FREE(sampass);
 
 	nt_status = access_check_samr_object(psd, p->server_info->ptok,
 		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
@@ -2344,16 +2425,13 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 	if ( !NT_STATUS_IS_OK(nt_status) )
 		return nt_status;
 
-	become_root();
-	ret=pdb_getsampwsid(sampass, &sid);
-	unbecome_root();
-
 	/* check that the SID exists in our domain. */
 	if (ret == False) {
         	return NT_STATUS_NO_SUCH_USER;
 	}
 
-	TALLOC_FREE(sampass);
+	/* If we did the rid admins hack above, allow access. */
+	acc_granted |= extra_access;
 
 	/* associate the user's SID and access bits with the new handle. */
 	if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
@@ -2765,7 +2843,7 @@ static NTSTATUS get_user_info_18(pipes_struct *p,
 	if (ret == False) {
 		DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
 		TALLOC_FREE(smbpass);
-		return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
+		return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
 	}
 
 	DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
@@ -2831,7 +2909,8 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
 				 struct samr_UserInfo21 *r,
 				 struct samu *pw,
-				 DOM_SID *domain_sid)
+				 DOM_SID *domain_sid,
+				 uint32_t acc_granted)
 {
 	NTSTATUS status;
 	const DOM_SID *sid_user, *sid_group;
@@ -2951,13 +3030,80 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
 	uint32 rid;
 	bool ret = false;
 	struct samu *pwd = NULL;
+	uint32_t acc_required, acc_granted;
 
 	/* search for the handle */
 	if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	switch (r->in.level) {
+	case 1: /* UserGeneralInformation */
+		/* USER_READ_GENERAL */
+		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
+		break;
+	case 2: /* UserPreferencesInformation */
+		/* USER_READ_PREFERENCES | USER_READ_GENERAL */
+		acc_required = SAMR_USER_ACCESS_GET_LOCALE |
+				SAMR_USER_ACCESS_GET_NAME_ETC;
+		break;
+	case 3: /* UserLogonInformation */
+		/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
+		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
+				SAMR_USER_ACCESS_GET_LOCALE |
+				SAMR_USER_ACCESS_GET_LOGONINFO |
+				SAMR_USER_ACCESS_GET_ATTRIBUTES;
+		break;
+	case 4: /* UserLogonHoursInformation */
+		/* USER_READ_LOGON */
+		acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
+		break;
+	case 5: /* UserAccountInformation */
+		/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
+		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
+				SAMR_USER_ACCESS_GET_LOCALE |
+				SAMR_USER_ACCESS_GET_LOGONINFO |
+				SAMR_USER_ACCESS_GET_ATTRIBUTES;
+		break;
+	case 6: /* UserNameInformation */
+	case 7: /* UserAccountNameInformation */
+	case 8: /* UserFullNameInformation */
+	case 9: /* UserPrimaryGroupInformation */
+	case 13: /* UserAdminCommentInformation */
+		/* USER_READ_GENERAL */
+		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
+		break;
+	case 10: /* UserHomeInformation */
+	case 11: /* UserScriptInformation */
+	case 12: /* UserProfileInformation */
+	case 14: /* UserWorkStationsInformation */
+		 /* USER_READ_LOGON */
+		acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
+		break;
+	case 16: /* UserControlInformation */
+	case 17: /* UserExpiresInformation */
+	case 20: /* UserParametersInformation */
+		/* USER_READ_ACCOUNT */
+		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
+		break;
+	case 21: /* UserAllInformation */
+		/* FIXME! - gd */
+		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
+		break;
+	case 18: /* UserInternal1Information */
+		/* FIXME! - gd */
+		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
+		break;
+	case 23: /* UserInternal4Information */
+	case 24: /* UserInternal4InformationNew */
+	case 25: /* UserInternal4InformationNew */
+	case 26: /* UserInternal5InformationNew */
+	default:
+		return NT_STATUS_INVALID_INFO_CLASS;
+		break;
+	}
+
 	status = access_check_samr_function(info->acc_granted,
-					    SAMR_USER_ACCESS_GET_ATTRIBUTES,
+					    acc_required,
 					    "_samr_QueryUserInfo");
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
@@ -3055,7 +3201,7 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
 		status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
 		break;
 	case 21:
-		status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
+		status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
 		break;
 	default:
 		status = NT_STATUS_INVALID_INFO_CLASS;
@@ -3244,9 +3390,39 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
 
 	time_t seq_num;
 	uint32 server_role;
+	uint32_t acc_required;
 
 	DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
 
+	switch (r->in.level) {
+	case 1: /* DomainPasswordInformation */
+	case 12: /* DomainLockoutInformation */
+		 /* DOMAIN_READ_PASSWORD_PARAMETERS */
+		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
+		break;
+	case 11: /* DomainGeneralInformation2 */
+		 /* DOMAIN_READ_PASSWORD_PARAMETERS |
+		 * DOMAIN_READ_OTHER_PARAMETERS */
+		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
+				SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
+		break;
+	case 2: /* DomainGeneralInformation */
+	case 3: /* DomainLogoffInformation */
+	case 4: /* DomainOemInformation */
+	case 5: /* DomainReplicationInformation */
+	case 6: /* DomainReplicationInformation */
+	case 7: /* DomainServerRoleInformation */
+	case 8: /* DomainModifiedInformation */
+	case 9: /* DomainStateInformation */
+	case 10: /* DomainUasInformation */
+	case 13: /* DomainModifiedInformation2 */
+		 /* DOMAIN_READ_OTHER_PARAMETERS */
+		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
+		break;
+	default:
+		return NT_STATUS_INVALID_INFO_CLASS;
+	}
+
 	dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
 	if (!dom_info) {
 		return NT_STATUS_NO_MEMORY;
@@ -3258,7 +3434,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
 	}
 
 	status = access_check_samr_function(info->acc_granted,
-					    SAMR_ACCESS_LOOKUP_DOMAIN,
+					    acc_required,
 					    "_samr_QueryDomainInfo" );
 
 	if ( !NT_STATUS_IS_OK(status) )
@@ -3603,47 +3779,44 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 
 	/* determine which user right we need to check based on the acb_info */
 
-	if ( acb_info & ACB_WSTRUST )
-	{
-		se_priv_copy( &se_rights, &se_machine_account );
+	if (geteuid() == sec_initial_uid()) {
+		se_priv_copy(&se_rights, &se_priv_none);
+		can_add_account = true;
+	} else if (acb_info & ACB_WSTRUST) {
+		se_priv_copy(&se_rights, &se_machine_account);
 		can_add_account = user_has_privileges(
 			p->server_info->ptok, &se_rights );
-	}
-	/* usrmgr.exe (and net rpc trustdom grant) creates a normal user
-	   account for domain trusts and changes the ACB flags later */
-	else if ( acb_info & ACB_NORMAL &&
-		  (account[strlen(account)-1] != '$') )
-	{
-		se_priv_copy( &se_rights, &se_add_users );
+	} else if (acb_info & ACB_NORMAL &&
+		(account[strlen(account)-1] != '$')) {
+		/* usrmgr.exe (and net rpc trustdom grant) creates a normal user
+		   account for domain trusts and changes the ACB flags later */
+		se_priv_copy(&se_rights, &se_add_users);
 		can_add_account = user_has_privileges(
 			p->server_info->ptok, &se_rights );
-	}
-	else 	/* implicit assumption of a BDC or domain trust account here
+	} else if (lp_enable_privileges()) {
+		/* implicit assumption of a BDC or domain trust account here
 		 * (we already check the flags earlier) */
-	{
-		if ( lp_enable_privileges() ) {
-			/* only Domain Admins can add a BDC or domain trust */
-			se_priv_copy( &se_rights, &se_priv_none );
-			can_add_account = nt_token_check_domain_rid(
-				p->server_info->ptok,
-				DOMAIN_GROUP_RID_ADMINS );
-		}
+		/* only Domain Admins can add a BDC or domain trust */
+		se_priv_copy(&se_rights, &se_priv_none);
+		can_add_account = nt_token_check_domain_rid(
+			p->server_info->ptok,
+			DOMAIN_GROUP_RID_ADMINS );
 	}
 
 	DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
 		  uidtoname(p->server_info->utok.uid),
 		  can_add_account ? "True":"False" ));
 
-	/********** BEGIN Admin BLOCK **********/
+	if (!can_add_account) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
 
-	if ( can_add_account )
-		become_root();
+	/********** BEGIN Admin BLOCK **********/
 
+	become_root();
 	nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
 				    r->out.rid);
-
-	if ( can_add_account )
-		unbecome_root();
+	unbecome_root();
 
 	/********** END Admin BLOCK **********/
 
@@ -3662,6 +3835,13 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 			    &sid, SAMR_USR_RIGHTS_WRITE_PW);
 	se_map_generic(&des_access, &usr_generic_mapping);
 
+	/*
+	 * JRA - TESTME. We just created this user so we
+	 * had rights to create them. Do we need to check
+	 * any further access on this object ? Can't we
+	 * just assume we have all the rights we need ?
+	 */
+
 	nt_status = access_check_samr_object(psd, p->server_info->ptok,
 		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
 		&acc_granted, "_samr_CreateUser2");
@@ -4023,10 +4203,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
 
 	se_priv_copy( &se_rights, &se_add_users );
 
-
 	status = access_check_samr_object(psd, p->server_info->ptok,
-		&se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
-		&acc_granted, "_samr_OpenAlias");
+		&se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
+		des_access, &acc_granted, "_samr_OpenAlias");
 
 	if ( !NT_STATUS_IS_OK(status) )
 		return status;
@@ -4782,6 +4961,73 @@ static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
+/*************************************************************
+**************************************************************/
+
+static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
+{
+	uint32_t acc_required = 0;
+
+	/* USER_ALL_USERNAME */
+	if (fields & SAMR_FIELD_ACCOUNT_NAME)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_FULLNAME */
+	if (fields & SAMR_FIELD_FULL_NAME)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_PRIMARYGROUPID */
+	if (fields & SAMR_FIELD_PRIMARY_GID)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_HOMEDIRECTORY */
+	if (fields & SAMR_FIELD_HOME_DIRECTORY)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_HOMEDIRECTORYDRIVE */
+	if (fields & SAMR_FIELD_HOME_DRIVE)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_SCRIPTPATH */
+	if (fields & SAMR_FIELD_LOGON_SCRIPT)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_PROFILEPATH */
+	if (fields & SAMR_FIELD_PROFILE_PATH)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_ADMINCOMMENT */
+	if (fields & SAMR_FIELD_COMMENT)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_WORKSTATIONS */
+	if (fields & SAMR_FIELD_WORKSTATIONS)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_LOGONHOURS */
+	if (fields & SAMR_FIELD_LOGON_HOURS)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_ACCOUNTEXPIRES */
+	if (fields & SAMR_FIELD_ACCT_EXPIRY)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_USERACCOUNTCONTROL */
+	if (fields & SAMR_FIELD_ACCT_FLAGS)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_PARAMETERS */
+	if (fields & SAMR_FIELD_PARAMETERS)
+		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
+	/* USER_ALL_USERCOMMENT */
+	if (fields & SAMR_FIELD_COMMENT)
+		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
+	/* USER_ALL_COUNTRYCODE */
+	if (fields & SAMR_FIELD_COUNTRY_CODE)
+		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
+	/* USER_ALL_CODEPAGE */
+	if (fields & SAMR_FIELD_CODE_PAGE)
+		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
+	/* USER_ALL_NTPASSWORDPRESENT */
+	if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
+		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
+	/* USER_ALL_LMPASSWORDPRESENT */
+	if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
+		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
+	/* USER_ALL_PASSWORDEXPIRED */
+	if (fields & SAMR_FIELD_EXPIRED_FLAG)
+		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
+
+	return acc_required;
+}
 
 /*******************************************************************
  samr_SetUserInfo
@@ -4794,12 +5040,10 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 	struct samu *pwd = NULL;
 	DOM_SID sid;
 	union samr_UserInfo *info = r->in.info;
-	uint16_t switch_value = r->in.level;
-	uint32_t acc_granted;
-	uint32_t acc_required;
+	uint32_t acc_granted = 0;
+	uint32_t acc_required = 0;
+	uint32_t fields = 0;
 	bool ret;
-	bool has_enough_rights = False;
-	uint32_t acb_info;
 	DISP_INFO *disp_info = NULL;
 
 	DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
@@ -4816,21 +5060,49 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 	  This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so


-- 
Samba Shared Repository


More information about the samba-cvs mailing list