[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Mon Jun 7 06:51:01 MDT 2010


The branch, master has been updated
       via  00089fd... s3:auth make sure the primary group sid is usable
       via  048575d... s3:auth return the full passwd struct from check_account
       via  0a7ff14... s3:passdb Export function to calculate the proper primary group sid
       via  aaf45cd... s3:auth remove unused structure member
       via  aa1a3cb... s3:auth create nt token from info3 directly
       via  e6456df... s3:auth handle unix domain sids in samu
       via  61823fb... s3:auth set the resolved user sid in the fake sam account
       via  ef94217... s3:auth check the user is valid first
       via  1bb0afa... s3:auth make sure we set the right username
      from  aa32725... s4:ldap.py - add some "objectclass" behaviour tests

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 00089fd74af740f832573d904312854e494a869e
Author: Simo Sorce <ssorce at redhat.com>
Date:   Sat May 29 11:29:29 2010 -0400

    s3:auth make sure the primary group sid is usable
    
    This function was previously performed under the cover by converting
    back and forth from info3 to samu and then later from samu to info3.
    
    Since we now shortcircuit that in some cases, check explicitly using
    get_primary_group_sid()
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 048575defba064a8d9f0e4eb542a299dc8730327
Author: Simo Sorce <ssorce at redhat.com>
Date:   Sat May 29 11:02:47 2010 -0400

    s3:auth return the full passwd struct from check_account
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 0a7ff146171abd2dee4aac44e4f2c6c812f1027e
Author: Simo Sorce <ssorce at redhat.com>
Date:   Sat May 29 10:51:40 2010 -0400

    s3:passdb Export function to calculate the proper primary group sid
    
    Don't keep it buried in passdb, this function need to be available
    for use in places where we do not want to construct an artificial
    samu struct just to play tricks.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit aaf45cd48ecf8e9f640a6f487b66785d47b8154a
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 17:03:18 2010 -0400

    s3:auth remove unused structure member
    
    sids are now completely handled using info3, remove dead code that fills
    server info sids and the structure members themselves
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit aa1a3cbad2ed62d5b59c48a6e7726eef4776f461
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 16:16:53 2010 -0400

    s3:auth create nt token from info3 directly
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit e6456df1489ec964445dfd6f009f9f75377b3d11
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 13:18:13 2010 -0400

    s3:auth handle unix domain sids in samu
    
    When we generate a user out of thin air we may end up adding sids
    that are not part of the sam domain (unix domain sids).
    Handle the case and preserve these sids as extra sids.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 61823fb8852cb8d66c341ecd54e7fb96abc4363a
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 13:22:41 2010 -0400

    s3:auth set the resolved user sid in the fake sam account
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit ef942172b9dfe3c30b86161445c7d6290579b6f2
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 11:14:01 2010 -0400

    s3:auth check the user is valid first
    
    It makes no sense to go through all the hoops to build samu and
    convert it to info3, just to discard them later if the user was
    not valid.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 1bb0afa662cb65ad8eeec59d40008c6604b791bc
Author: Simo Sorce <ssorce at redhat.com>
Date:   Fri May 28 11:07:49 2010 -0400

    s3:auth make sure we set the right username
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 source3/auth/auth_util.c       |  219 ++++++++++++++--------------------------
 source3/auth/server_info.c     |  158 +++++++++++++++++++++++------
 source3/auth/server_info_sam.c |   36 +------
 source3/auth/token_util.c      |  183 ++++++++++++++++++++++++++++-----
 source3/include/auth.h         |   16 ++-
 source3/include/proto.h        |   12 ++-
 source3/passdb/lookup_sid.c    |  124 +++++++++++++++++++++++
 source3/passdb/pdb_get_set.c   |   94 ++----------------
 8 files changed, 516 insertions(+), 326 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index a64fd33..a93d44f 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -30,34 +30,6 @@
 #define DBGC_CLASS DBGC_AUTH
 
 /****************************************************************************
- Ensure primary group SID is always at position 0 in a 
- auth_serversupplied_info struct.
-****************************************************************************/
-
-static void sort_sid_array_for_smbd(struct auth_serversupplied_info *result,
-				const struct dom_sid *pgroup_sid)
-{
-	unsigned int i;
-
-	if (!result->sids) {
-		return;
-	}
-
-	if (sid_compare(&result->sids[0], pgroup_sid)==0) {
-		return;
-	}
-
-	for (i = 1; i < result->num_sids; i++) {
-		if (sid_compare(pgroup_sid,
-				&result->sids[i]) == 0) {
-			sid_copy(&result->sids[i], &result->sids[0]);
-			sid_copy(&result->sids[0], pgroup_sid);
-			return;
-		}
-	}
-}
-
-/****************************************************************************
  Create a UNIX user on demand.
 ****************************************************************************/
 
@@ -463,7 +435,6 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
 	NTSTATUS status;
 	size_t i;
 	struct dom_sid tmp_sid;
-	struct dom_sid user_sid;
 
 	/*
 	 * If winbind is not around, we can not make much use of the SIDs the
@@ -482,17 +453,11 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
 						    &server_info->ptok);
 
 	} else {
-		sid_compose(&user_sid,
-			    server_info->info3->base.domain_sid,
-			    server_info->info3->base.rid);
-
-		server_info->ptok = create_local_nt_token(
-			server_info,
-			&user_sid,
-			server_info->guest,
-			server_info->num_sids, server_info->sids);
-		status = server_info->ptok ?
-			NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
+		status = create_local_nt_token_from_info3(server_info,
+							  server_info->guest,
+							  server_info->info3,
+							  &server_info->extra,
+							  &server_info->ptok);
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -574,66 +539,12 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
 {
 	NTSTATUS status;
 	struct samu *sampass = NULL;
-	gid_t *gids;
 	char *qualified_name = NULL;
 	TALLOC_CTX *mem_ctx = NULL;
 	struct dom_sid u_sid;
 	enum lsa_SidType type;
 	struct auth_serversupplied_info *result;
 
-	if ( !(sampass = samu_new( NULL )) ) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	status = samu_set_unix( sampass, pwd );
-	if (!NT_STATUS_IS_OK(status)) {
-		return status;
-	}
-
-	result = make_server_info(NULL);
-	if (result == NULL) {
-		TALLOC_FREE(sampass);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	status = samu_to_SamInfo3(result, sampass,
-				  global_myname(), &result->info3);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("Failed to convert samu to info3: %s\n",
-			   nt_errstr(status)));
-		TALLOC_FREE(sampass);
-		TALLOC_FREE(result);
-		return status;
-	}
-
-
-	result->unix_name = talloc_strdup(result, unix_username);
-	result->sanitized_username = sanitize_username(result, unix_username);
-
-	if ((result->unix_name == NULL)
-	    || (result->sanitized_username == NULL)) {
-		TALLOC_FREE(sampass);
-		TALLOC_FREE(result);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	result->utok.uid = pwd->pw_uid;
-	result->utok.gid = pwd->pw_gid;
-
-	status = pdb_enum_group_memberships(result, sampass,
-					    &result->sids, &gids,
-					    &result->num_sids);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
-			   nt_errstr(status)));
-		TALLOC_FREE(sampass);
-		TALLOC_FREE(result);
-		return status;
-	}
-
-	TALLOC_FREE(sampass);
-
 	/*
 	 * The SID returned in server_info->sam_account is based
 	 * on our SAM sid even though for a pure UNIX account this should
@@ -649,7 +560,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
 
 	mem_ctx = talloc_init("make_server_info_pw_tmp");
 	if (!mem_ctx) {
-		TALLOC_FREE(result);
 		return NT_STATUS_NO_MEMORY;
 	}
 
@@ -657,7 +567,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
 					unix_users_domain_name(),
 					unix_username );
 	if (!qualified_name) {
-		TALLOC_FREE(result);
 		TALLOC_FREE(mem_ctx);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -665,7 +574,6 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
 	if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
 						NULL, NULL,
 						&u_sid, &type)) {
-		TALLOC_FREE(result);
 		TALLOC_FREE(mem_ctx);
 		return NT_STATUS_NO_SUCH_USER;
 	}
@@ -673,23 +581,55 @@ NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
 	TALLOC_FREE(mem_ctx);
 
 	if (type != SID_NAME_USER) {
-		TALLOC_FREE(result);
 		return NT_STATUS_NO_SUCH_USER;
 	}
 
-	/* FIXME: add to info3 too ? */
-	status = add_sid_to_array_unique(result, &u_sid,
-					 &result->sids,
-					 &result->num_sids);
+	if ( !(sampass = samu_new( NULL )) ) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = samu_set_unix( sampass, pwd );
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* In pathological cases the above call can set the account
+	 * name to the DOMAIN\username form. Reset the account name
+	 * using unix_username */
+	pdb_set_username(sampass, unix_username, PDB_SET);
+
+	/* set the user sid to be the calculated u_sid */
+	pdb_set_user_sid(sampass, &u_sid, PDB_SET);
+
+	result = make_server_info(NULL);
+	if (result == NULL) {
+		TALLOC_FREE(sampass);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = samu_to_SamInfo3(result, sampass, global_myname(),
+				  &result->info3, &result->extra);
 	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("Failed to convert samu to info3: %s\n",
+			   nt_errstr(status)));
+		TALLOC_FREE(sampass);
 		TALLOC_FREE(result);
 		return status;
 	}
 
-	/* For now we throw away the gids and convert via sid_to_gid
-	 * later. This needs fixing, but I'd like to get the code straight and
-	 * simple first. */
-	TALLOC_FREE(gids);
+	TALLOC_FREE(sampass);
+
+	result->unix_name = talloc_strdup(result, unix_username);
+	result->sanitized_username = sanitize_username(result, unix_username);
+
+	if ((result->unix_name == NULL)
+	    || (result->sanitized_username == NULL)) {
+		TALLOC_FREE(result);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	result->utok.uid = pwd->pw_uid;
+	result->utok.gid = pwd->pw_gid;
 
 	*server_info = result;
 
@@ -867,6 +807,7 @@ struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
 		TALLOC_FREE(dst);
 		return NULL;
 	}
+	dst->extra = src->extra;
 
 	dst->pam_handle = NULL;
 	dst->unix_name = talloc_strdup(dst, src->unix_name);
@@ -968,7 +909,7 @@ bool copy_current_user(struct current_user *dst, struct current_user *src)
 
 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
 			      const char *username, char **found_username,
-			      uid_t *uid, gid_t *gid,
+			      struct passwd **pwd,
 			      bool *username_was_mapped)
 {
 	fstring dom_user, lower_username;
@@ -992,8 +933,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
 		return NT_STATUS_NO_SUCH_USER;
 	}
 
-	*uid = passwd->pw_uid;
-	*gid = passwd->pw_gid;
+	*pwd = passwd;
 
 	/* This is pointless -- there is no suport for differing 
 	   unix and windows names.  Make sure to always store the 
@@ -1003,8 +943,6 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
 
 	*found_username = talloc_strdup( mem_ctx, real_username );
 
-	TALLOC_FREE(passwd);
-
 	return NT_STATUS_OK;
 }
 
@@ -1109,14 +1047,11 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 	char *found_username = NULL;
 	const char *nt_domain;
 	const char *nt_username;
-	struct dom_sid user_sid;
-	struct dom_sid group_sid;
 	bool username_was_mapped;
-
-	uid_t uid = (uid_t)-1;
-	gid_t gid = (gid_t)-1;
-
+	struct passwd *pwd;
 	struct auth_serversupplied_info *result;
+	struct dom_sid *group_sid;
+	struct netr_SamInfo3 *i3;
 
 	/* 
 	   Here is where we should check the list of
@@ -1124,15 +1059,6 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 	   matches.
 	*/
 
-	if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	if (!sid_compose(&group_sid, info3->base.domain_sid,
-			 info3->base.primary_gid)) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
 	nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
 	if (!nt_username) {
 		/* If the server didn't give us one, just use the one we sent
@@ -1161,7 +1087,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 	/* this call will try to create the user if necessary */
 
 	nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
-				     &found_username, &uid, &gid,
+				     &found_username, &pwd,
 				     &username_was_mapped);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1184,29 +1110,38 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 	}
 
 	/* copy in the info3 */
-	result->info3 = copy_netr_SamInfo3(result, info3);
+	result->info3 = i3 = copy_netr_SamInfo3(result, info3);
 
 	/* Fill in the unix info we found on the way */
+	result->utok.uid = pwd->pw_uid;
+	result->utok.gid = pwd->pw_gid;
 
-	result->utok.uid = uid;
-	result->utok.gid = gid;
-
-	/* Create a 'combined' list of all SIDs we might want in the SD */
-
-	result->num_sids = 0;
-	result->sids = NULL;
-
-	nt_status = sid_array_from_info3(result, info3,
-					 &result->sids,
-					 &result->num_sids,
-					 false, false);
+	/* We can't just trust that the primary group sid sent us is something
+	 * we can really use. Obtain the useable sid, and store the original
+	 * one as an additional group if it had to be replaced */
+	nt_status = get_primary_group_sid(mem_ctx, found_username,
+					  &pwd, &group_sid);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		TALLOC_FREE(result);
 		return nt_status;
 	}
 
-	/* Ensure the primary group sid is at position 0. */
-	sort_sid_array_for_smbd(result, &group_sid);
+	/* store and check if it is the same we got originally */
+	sid_peek_rid(group_sid, &i3->base.primary_gid);
+	if (i3->base.primary_gid != info3->base.primary_gid) {
+		uint32_t n = i3->base.groups.count;
+		/* not the same, store the original as an additional group */
+		i3->base.groups.rids =
+			talloc_realloc(i3, i3->base.groups.rids,
+					struct samr_RidWithAttribute, n + 1);
+		if (i3->base.groups.rids == NULL) {
+			TALLOC_FREE(result);
+			return NT_STATUS_NO_MEMORY;
+		}
+		i3->base.groups.rids[n].rid = info3->base.primary_gid;
+		i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
+		i3->base.groups.count = n + 1;
+	}
 
 	/* ensure we are never given NULL session keys */
 
diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index f72cdba..6b43fc6 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -53,6 +53,7 @@ struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
 
 	result->utok.uid = -1;
 	result->utok.gid = -1;
+
 	return result;
 }
 
@@ -215,37 +216,81 @@ NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info,
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS sids_to_samr_RidWithAttributeArray(
-				TALLOC_CTX *mem_ctx,
-				struct samr_RidWithAttributeArray *groups,
-				const struct dom_sid *domain_sid,
-				const struct dom_sid *sids,
-				size_t num_sids)
+static NTSTATUS append_netr_SidAttr(TALLOC_CTX *mem_ctx,
+				    struct netr_SidAttr **sids,
+				    uint32_t *count,
+				    const struct dom_sid2 *asid,
+				    uint32_t attributes)
+{
+	uint32_t t = *count;
+
+	*sids = talloc_realloc(mem_ctx, *sids, struct netr_SidAttr, t + 1);
+	if (*sids == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	(*sids)[t].sid = sid_dup_talloc(*sids, asid);
+	if ((*sids)[t].sid == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	(*sids)[t].attributes = attributes;
+	*count = t + 1;
+
+	return NT_STATUS_OK;
+}
+
+/* Fils the samr_RidWithAttributeArray with the provided sids.
+ * If it happens that we have additional groups that do not belong
+ * to the domain, add their sids as extra sids */
+static NTSTATUS group_sids_to_info3(struct netr_SamInfo3 *info3,
+				    const struct dom_sid *sids,
+				    size_t num_sids)
 {
+	uint32_t attributes = SE_GROUP_MANDATORY |
+				SE_GROUP_ENABLED_BY_DEFAULT |
+				SE_GROUP_ENABLED;
+	struct samr_RidWithAttributeArray *groups;
+	struct dom_sid *domain_sid;
 	unsigned int i;
+	NTSTATUS status;
+	uint32_t rid;
 	bool ok;
 
-	groups->rids = talloc_array(mem_ctx,
+	domain_sid = info3->base.domain_sid;
+	groups = &info3->base.groups;
+
+	groups->rids = talloc_array(info3,
 				    struct samr_RidWithAttribute, num_sids);
 	if (!groups->rids) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
 	for (i = 0; i < num_sids; i++) {
-		ok = sid_peek_check_rid(domain_sid, &sids[i],
-					&groups->rids[i].rid);
-		if (!ok) continue;
+		ok = sid_peek_check_rid(domain_sid, &sids[i], &rid);
+		if (ok) {
+
+			/* if it is the primary gid, skip it, we
+			 * obviously already have it */
+			if (info3->base.primary_gid == rid) continue;
+
+			/* store domain group rid */
+			groups->rids[i].rid = rid;
+			groups->rids[i].attributes = attributes;
+			groups->count++;
+			continue;
+		}
 
-		groups->rids[i].attributes = SE_GROUP_MANDATORY |
-					     SE_GROUP_ENABLED_BY_DEFAULT |
-					     SE_GROUP_ENABLED;
-		groups->count++;
+		/* if this wasn't a domain sid, add it as extra sid */
+		status = append_netr_SidAttr(info3, &info3->sids,
+					     &info3->sidcount,
+					     &sids[i], attributes);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
 	}
 
 	return NT_STATUS_OK;
 }
 
-
 #define RET_NOMEM(ptr) do { \
 	if (!ptr) { \
 		TALLOC_FREE(info3); \
@@ -255,7 +300,8 @@ static NTSTATUS sids_to_samr_RidWithAttributeArray(
 NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
 			  struct samu *samu,
 			  const char *login_server,
-			  struct netr_SamInfo3 **_info3)
+			  struct netr_SamInfo3 **_info3,
+			  struct extra_auth_info *extra)
 {
 	struct netr_SamInfo3 *info3;
 	const struct dom_sid *user_sid;
@@ -281,6 +327,67 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	ZERO_STRUCT(domain_sid);
+
+	/* check if this is a "Unix Users" domain user,
+	 * we need to handle it in a special way if that's the case */
+	if (sid_compare_domain(user_sid, &global_sid_Unix_Users) == 0) {
+		/* in info3 you can only set rids for the user and the
+		 * primary group, and the domain sid must be that of
+		 * the sam domain.
+		 *
+		 * Store a completely bogus value here.
+		 * The real SID is stored in the extra sids.
+		 * Other code will know to look there if (-1) is found
+		 */
+		info3->base.rid = (uint32_t)(-1);
+		sid_copy(&extra->user_sid, user_sid);
+
+		DEBUG(10, ("Unix User found in struct samu. Rid marked as "
+			   "special and sid (%s) saved as extra sid\n",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list