[SCM] Samba Shared Repository - branch v3-2-stable updated - release-3-2-4-70-gfd93db7

Karolin Seeger kseeger at samba.org
Thu Oct 23 10:05:24 GMT 2008


The branch, v3-2-stable has been updated
       via  fd93db7084fdb5899fb823046b9d6ed1d05221c7 (commit)
       via  96b35c32ae99d74608ad95d063629554fee77979 (commit)
       via  b339f17132b18edad52b4c2f6b348e4b8d789bcb (commit)
       via  ae01a98d49be39c258e479d610fa2e58ea2b6c62 (commit)
       via  61046225de8a4cd77e94d8c5c4a8f510bc11b79e (commit)
       via  369fecaeb2470a1f7e68417ccdddb61334e37d92 (commit)
       via  042e50f8709cfbe45d5b184cb3c4fe1b16bdc3b0 (commit)
       via  ddba89d7713923bfbf1c8492c5dc6c6d5b220f1e (commit)
      from  1d86b5e003effb4bb56ef9b0444da63a909fbc3c (commit)

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


- Log -----------------------------------------------------------------
commit fd93db7084fdb5899fb823046b9d6ed1d05221c7
Author: Karolin Seeger <kseeger at samba.org>
Date:   Thu Oct 23 12:04:02 2008 +0200

    WHATSNEW: Update changes since 3.2.4.
    
    Karolin
    (cherry picked from commit 71de4d58bb2aea6a98e94055387ef6671aa64410)

commit 96b35c32ae99d74608ad95d063629554fee77979
Author: Günther Deschner <gd at samba.org>
Date:   Wed Oct 22 23:16:19 2008 +0200

    s3-samr-server: fix access check in _samr_QuerySecurity().
    
    Guenther
    (cherry picked from commit 25cb282f7042e8192c0bc6d720df0646b74e9a47)

commit b339f17132b18edad52b4c2f6b348e4b8d789bcb
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Oct 20 16:53:05 2008 -0700

    Remove the requirement for ldap call made as root. Add in security
    checks for all SAMR calls.
    Jeremy.
    (cherry picked from commit b848f96d747fb41c074dd073f24f186539257d71)

commit ae01a98d49be39c258e479d610fa2e58ea2b6c62
Author: Günther Deschner <gd at samba.org>
Date:   Thu Oct 23 01:42:27 2008 +0200

    s3-samr-server: _samr_DeleteUser needs to wipe out the user_handle on success.
    
    Guenther
    (cherry picked from commit 8a0054c6d273049bea235803db25912f6cf03610)
    (cherry picked from commit 40a904ee021e4c9390235f1d476bc37b87ac9b70)

commit 61046225de8a4cd77e94d8c5c4a8f510bc11b79e
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Oct 22 13:18:58 2008 -0700

    Fix net rpc vampire, based on an *amazing* piece of debugging work by "Cooper S. Blake" <the_analogkid at yahoo.com>.
    
    "I believe I have found two bugs in the 3.2 code and one bug that
    carried on to the 3.3 branch.  In the 3.2 code, everything is
    located in the utils/net_rpc_samsync.c file.  What I believe is the
    first problem is that fetch_database() is calling
    samsync_fix_delta_array() with rid_crypt set to true, which means
    the password hashes are unencrypted from the RID encryption.
    However, I believe this call is redundant, and the corresponding
    call for samdump has rid_crypt set to false.  So I think the
    rid_crypt param should be false in fetch_database().
    
    If you follow the code, it makes its way to sam_account_from_delta()
    where the password hashes are decrypted a second time by calling
    sam_pwd_hash().  I believe this is what is scrambling my passwords.
    
    These methods were refactored somewhere in the 3.3 branch.  Now the
    net_rpc_samsync.c class calls rpc_vampire_internals, which calls
    libnet/libnet_samsync.c, which calls samsync_fix_delta_array() with
    rid_crypt always set to false.  I think that's correct.  But the
    second bug has carried through in the sam_account_from_delta()
    function:
    
     208         if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
     209                 sam_pwd_hash(r->rid, r->ntpassword.hash, lm_passwd, 0);
     210                 pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
     211         }
     212
     213         if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
     214                 sam_pwd_hash(r->rid, r->lmpassword.hash, nt_passwd, 0);
     215                 pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
    
    If you look closely you'll see that the nt hash is going into the
    lm_passwd variable and the decrypted value is being set in the lanman
    hash, and the lanman hash is being decrypted and put into the nt hash
    field.  So the LanMan and NT hashes look like they're being put in
    the opposite fields."
    
    Fix this by removing the rid_crypt parameter.
    Jeremy.
    (cherry picked from commit e38436f731ff09333588cc0751c79029a569f390)

commit 369fecaeb2470a1f7e68417ccdddb61334e37d92
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 22 14:26:05 2008 +0200

    Fix bug 5840: Segfault in "rpcclient lsaaddacctrights"
    (cherry picked from commit 79222e476edbccf81e70cf1c0d1f40db0b88e20b)

commit 042e50f8709cfbe45d5b184cb3c4fe1b16bdc3b0
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 21 17:06:53 2008 -0700

    Cope with MAXIMUM_ALLOWED_ACCESS requests when opening handles.
    Jeremy.
    (cherry picked from commit 82ec832f7edffe2fcfd1bb067e092c159bed2973)

commit ddba89d7713923bfbf1c8492c5dc6c6d5b220f1e
Author: Andreas Schneider <mail at cynapses.org>
Date:   Mon Oct 20 17:35:42 2008 +0200

    Delete the krb5 ccname variable from the PAM environment if set.
    
    If winbind sets the KRB5CCNAME variable it should unset it when
    the cache gets destroyed.
    (cherry picked from commit e7b0d1c984a37600a234c1f4c95b06e9b5898f30)

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

Summary of changes:
 WHATSNEW.txt                    |   13 ++++
 source/lib/smbldap.c            |    7 --
 source/lib/util_sid.c           |   11 +++
 source/libnet/libnet_samsync.c  |   48 +++++++++-----
 source/nsswitch/pam_winbind.c   |    7 ++
 source/rpc_server/srv_samr_nt.c |  133 ++++++++++++++++++++++++++++++++++++---
 source/rpcclient/cmd_lsarpc.c   |    2 +-
 source/utils/net_rpc.c          |   11 ---
 source/utils/net_rpc_samsync.c  |   39 +++++-------
 9 files changed, 202 insertions(+), 69 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 7011594..a9c4b6f 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -36,6 +36,10 @@ o   Jeremy Allison <jra at samba.org>
     * Restructure VFS SMB traffic analyzer VFS module.
     * Correctly fix smbclient to terminate on eof from server.
     * Unify access checks for lsa server functions.
+    * Remove the requirement for ldap call made as root.
+    * Cope with MAXIMUM_ALLOWED_ACCESS requests when opening handles.
+    * Fix net rpc vampire, based on an *amazing* piece of debugging work by
+      "Cooper S. Blake" <the_analogkid at yahoo.com>.
 
 
 o   Gerald (Jerry) Carter <jerry at samba.org>
@@ -47,6 +51,10 @@ o   Guenther Deschner <gd at samba.org>
     * Fix duplicate installation of cifs.upcall.
     * Fix _srvsvc_NetShareAdd segfault.
     * Ensure consistency when reporting password complexity.
+    * Fix _lsa_GetUserName.
+    * Fix access check in _samr_QuerySecurity().
+    * _samr_DeleteUser needs to wipe out the user_handle on success.
+    * NetGroupEnum_r needs to handle servers with no groups.
 
 
 o   Holger Hetterich <hhetter at novell.com>
@@ -61,6 +69,7 @@ o   Jeff Layton <jlayton at redhat.com>
 o   Volker Lendecke <vl at samba.org>
     * BUG 5691: Fig smbd panic on Solaris.
     * BUG 5778: Check if strlcpy and strlcat are already defined.
+    * BUG 5840: Fix segfault in "rpcclient lsaaddacctrights".
     * Fix a potential NULL deref in found by the IBM Checker.
     * Fix an uninitialized variable found by the IBM Checker.
     * Fix an unlikely memleak found by the IBM Checker.
@@ -81,6 +90,10 @@ o   Tim Prouty <tim.prouty at isilon.com>
     * Fix several build warnings.
 
 
+o   Andreas Schneider <mail at cynapses.org>
+    * Delete the krb5 ccname variable from the PAM environment if set.
+
+
 o   Andrew Tridgell <tridge at samba.org>
     * Fix segfault on startup with trusted domains.
     * Re-add "winbind:ignore domains" parameter.
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index bcde53c..315b1e3 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -1023,13 +1023,6 @@ static int smbldap_open(struct smbldap_state *ldap_state)
 	int rc, opt_rc;
 	bool reopen = False;
 	SMB_ASSERT(ldap_state);
-		
-#ifndef NO_LDAP_SECURITY
-	if (geteuid() != 0) {
-		DEBUG(0, ("smbldap_open: cannot access LDAP when not root\n"));
-		return  LDAP_INSUFFICIENT_ACCESS;
-	}
-#endif
 
 	if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
 
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 53614ed..f656bb1 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -664,6 +664,17 @@ bool is_null_sid(const DOM_SID *sid)
 	return sid_equal(sid, &null_sid);
 }
 
+bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
+{
+        int i;
+
+        for (i=0; i<token->num_sids; i++) {
+                if (sid_compare(sid, &token->user_sids[i]) == 0)
+                        return true;
+        }
+        return false;
+}
+
 NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
 			      const struct netr_SamInfo3 *info3,
 			      DOM_SID **user_sids,
diff --git a/source/libnet/libnet_samsync.c b/source/libnet/libnet_samsync.c
index 61d53c3..8a14338 100644
--- a/source/libnet/libnet_samsync.c
+++ b/source/libnet/libnet_samsync.c
@@ -32,7 +32,6 @@
 
 static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
 			 DATA_BLOB *session_key,
-			 bool rid_crypt,
 			 enum netr_SamDatabaseID database_id,
 			 struct netr_DELTA_ENUM *delta)
 {
@@ -41,17 +40,29 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
 	struct netr_DELTA_USER *user = delta->delta_union.user;
 	struct samr_Password lm_hash;
 	struct samr_Password nt_hash;
+	unsigned char zero_buf[16];
 
-	if (rid_crypt) {
-		if (user->lm_password_present) {
+	memset(zero_buf, '\0', sizeof(zero_buf));
+
+	/* Note that win2000 may send us all zeros
+	 * for the hashes if it doesn't
+	 * think this channel is secure enough. */
+	if (user->lm_password_present) {
+		if (memcmp(user->lmpassword.hash, zero_buf, 16) != 0) {
 			sam_pwd_hash(rid, user->lmpassword.hash, lm_hash.hash, 0);
-			user->lmpassword = lm_hash;
+		} else {
+			memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
 		}
+		user->lmpassword = lm_hash;
+	}
 
-		if (user->nt_password_present) {
+	if (user->nt_password_present) {
+		if (memcmp(user->ntpassword.hash, zero_buf, 16) != 0) {
 			sam_pwd_hash(rid, user->ntpassword.hash, nt_hash.hash, 0);
-			user->ntpassword = nt_hash;
+		} else {
+			memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
 		}
+		user->ntpassword = nt_hash;
 	}
 
 	if (user->user_private_info.SensitiveData) {
@@ -71,26 +82,31 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
 			return ndr_map_error2ntstatus(ndr_err);
 		}
 
+		/* Note that win2000 may send us all zeros
+		 * for the hashes if it doesn't
+		 * think this channel is secure enough. */
 		if (keys.keys.keys2.lmpassword.length == 16) {
-			if (rid_crypt) {
+			if (memcmp(keys.keys.keys2.lmpassword.pwd.hash,
+						zero_buf, 16) != 0) {
 				sam_pwd_hash(rid,
 					     keys.keys.keys2.lmpassword.pwd.hash,
 					     lm_hash.hash, 0);
-				user->lmpassword = lm_hash;
 			} else {
-				user->lmpassword = keys.keys.keys2.lmpassword.pwd;
+				memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
 			}
+			user->lmpassword = lm_hash;
 			user->lm_password_present = true;
 		}
 		if (keys.keys.keys2.ntpassword.length == 16) {
-			if (rid_crypt) {
+			if (memcmp(keys.keys.keys2.ntpassword.pwd.hash,
+						zero_buf, 16) != 0) {
 				sam_pwd_hash(rid,
-					     keys.keys.keys2.ntpassword.pwd.hash,
-					     nt_hash.hash, 0);
-				user->ntpassword = nt_hash;
+					keys.keys.keys2.ntpassword.pwd.hash,
+					nt_hash.hash, 0);
 			} else {
-				user->ntpassword = keys.keys.keys2.ntpassword.pwd;
+				memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
 			}
+			user->ntpassword = nt_hash;
 			user->nt_password_present = true;
 		}
 		/* TODO: rid decrypt history fields */
@@ -128,7 +144,6 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
 
 static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
 				  DATA_BLOB *session_key,
-				  bool rid_crypt,
 				  enum netr_SamDatabaseID database_id,
 				  struct netr_DELTA_ENUM *delta)
 {
@@ -139,7 +154,6 @@ static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
 
 			status = fix_user(mem_ctx,
 					  session_key,
-					  rid_crypt,
 					  database_id,
 					  delta);
 			break;
@@ -164,7 +178,6 @@ static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
 
 NTSTATUS samsync_fix_delta_array(TALLOC_CTX *mem_ctx,
 				 DATA_BLOB *session_key,
-				 bool rid_crypt,
 				 enum netr_SamDatabaseID database_id,
 				 struct netr_DELTA_ENUM_ARRAY *r)
 {
@@ -175,7 +188,6 @@ NTSTATUS samsync_fix_delta_array(TALLOC_CTX *mem_ctx,
 
 		status = samsync_fix_delta(mem_ctx,
 					   session_key,
-					   rid_crypt,
 					   database_id,
 					   &r->delta_enum[i]);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index 95b3d23..15b33e3 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -2358,6 +2358,13 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags,
 	}
 
 out:
+	/*
+	 * Delete the krb5 ccname variable from the PAM environment
+	 * if it was set by winbind.
+	 */
+	if (ctx->ctrl & WINBIND_KRB5_AUTH) {
+		pam_putenv(pamh, "KRB5CCNAME");
+	}
 
 	_PAM_LOG_FUNCTION_LEAVE("pam_sm_close_session", ctx, retval);
 
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index c59a46c..ac3cdfa 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -5,7 +5,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
  *  Copyright (C) Paul Ashton                       1997,
  *  Copyright (C) Marc Jacobsen			    1999,
- *  Copyright (C) Jeremy Allison                    2001-2005,
+ *  Copyright (C) Jeremy Allison                    2001-2008,
  *  Copyright (C) Jean François Micouleau           1998-2001,
  *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>   2002,
  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
@@ -249,6 +249,48 @@ static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_requir
 }
 
 /*******************************************************************
+ Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
+********************************************************************/
+
+static void map_max_allowed_access(const NT_USER_TOKEN *token,
+					uint32_t *pacc_requested)
+{
+	if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
+		return;
+	}
+	*pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
+
+	/* At least try for generic read. */
+	*pacc_requested = GENERIC_READ_ACCESS;
+
+	/* root gets anything. */
+	if (geteuid() == sec_initial_uid()) {
+		*pacc_requested |= GENERIC_ALL_ACCESS;
+		return;
+	}
+
+	/* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
+
+	if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
+			is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
+		*pacc_requested |= GENERIC_ALL_ACCESS;
+		return;
+	}
+
+	/* Full access for DOMAIN\Domain Admins. */
+	if ( IS_DC ) {
+		DOM_SID domadmin_sid;
+		sid_copy( &domadmin_sid, get_global_sam_sid() );
+		sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+		if (is_sid_in_token(token, &domadmin_sid)) {
+			*pacc_requested |= GENERIC_ALL_ACCESS;
+			return;
+		}
+	}
+	/* TODO ! Check privileges. */
+}
+
+/*******************************************************************
  Fetch or create a dispinfo struct.
 ********************************************************************/
 
@@ -586,6 +628,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
 		return status;
 
 	/*check if access can be granted as requested by client. */
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
 
 	make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
 	se_map_generic( &des_access, &dom_generic_mapping );
@@ -826,6 +869,13 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
 	DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
 		  sid_string_dbg(&pol_sid)));
 
+	status = access_check_samr_function(acc_granted,
+					    STD_RIGHT_READ_CONTROL_ACCESS,
+					    "_samr_QuerySecurity");
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
 
 	/* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
@@ -1154,6 +1204,9 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
 	if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
+		 sid_string_dbg(&info->sid)));
+
 	status = access_check_samr_function(info->acc_granted,
 					    SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
 					    "_samr_EnumDomainAliases");
@@ -1161,9 +1214,6 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
 		return status;
 	}
 
-	DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
-		 sid_string_dbg(&info->sid)));
-
 	samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
 	if (!samr_array) {
 		return NT_STATUS_NO_MEMORY;
@@ -1430,6 +1480,13 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
 	if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	status = access_check_samr_function(info->acc_granted,
+					    SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+					    "_samr_QueryDisplayInfo");
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/*
 	 * calculate how many entries we will return.
 	 * based on
@@ -2063,6 +2120,13 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
 	if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
 		return NT_STATUS_INVALID_HANDLE;
 
+	status = access_check_samr_function(acc_granted,
+					    SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+					    "_samr__LookupRids");
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	if (num_rids > 1000) {
 		DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
 			  "to samba4 idl this is not possible\n", num_rids));
@@ -2158,6 +2222,8 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 
 	/* check if access can be granted as requested by client. */
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	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);
 
@@ -2633,6 +2699,13 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
 	if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	status = access_check_samr_function(info->acc_granted,
+					    SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
+					    "_samr_QueryUserInfo");
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	domain_sid = info->sid;
 
 	sid_split_rid(&domain_sid, &rid);
@@ -2881,6 +2954,13 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
+	status = access_check_samr_function(info->acc_granted,
+					    SA_RIGHT_SAM_OPEN_DOMAIN,
+					    "_samr_QueryDomainInfo_internal" );
+
+	if ( !NT_STATUS_IS_OK(status) )
+		return status;
+
 	switch (level) {
 		case 0x01:
 
@@ -3221,6 +3301,8 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 
 	sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	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);
@@ -3282,10 +3364,7 @@ NTSTATUS _samr_Connect(pipes_struct *p,
 	   was observed from a win98 client trying to enumerate users (when configured
 	   user level access control on shares)   --jerry */
 
-	if (des_access == MAXIMUM_ALLOWED_ACCESS) {
-		/* Map to max possible knowing we're filtered below. */
-		des_access = GENERIC_ALL_ACCESS;
-	}
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
 
 	se_map_generic( &des_access, &sam_generic_mapping );
 	info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
@@ -3321,6 +3400,8 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
 	se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3370,6 +3451,8 @@ NTSTATUS _samr_Connect4(pipes_struct *p,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
 	se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3419,6 +3502,8 @@ NTSTATUS _samr_Connect5(pipes_struct *p,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
 	se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3586,6 +3671,8 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
 
 	/*check if access can be granted as requested by client. */
 
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
 	se_map_generic(&des_access,&ali_generic_mapping);
 
@@ -4820,6 +4907,8 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p,
 	if (!close_policy_hnd(p, r->in.user_handle))
 		return NT_STATUS_OBJECT_NAME_INVALID;
 
+	ZERO_STRUCTP(r->out.user_handle);
+
 	force_flush_samr_cache(disp_info);
 
 	return NT_STATUS_OK;
@@ -5478,6 +5567,8 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
 		return status;
 
 	/*check if access can be granted as requested by client. */
+	map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
 	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
 	se_map_generic(&des_access,&grp_generic_mapping);
 
@@ -5604,16 +5695,32 @@ NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
 			     struct samr_SetDomainInfo *r)
 {
+	struct samr_info *info = NULL;
 	time_t u_expire, u_min_age;
 	time_t u_logout;
 	time_t u_lock_duration, u_reset_time;
+	NTSTATUS result;
 
 	DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
 
 	/* find the policy handle.  open a policy on it. */
-	if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
+	if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
+	/* We do have different access bits for info
+	 * levels here, but we're really just looking for
+	 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
+	 * this maps to different specific bits. So
+	 * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
+	 * set we are ok. */
+
+	result = access_check_samr_function(info->acc_granted,
+					    SA_RIGHT_DOMAIN_SET_INFO_1,
+					    "_samr_SetDomainInfo");
+
+	if (!NT_STATUS_IS_OK(result))
+		return result;
+
 	DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
 
 	switch (r->in.level) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list