[SCM] Samba Shared Repository - branch v4-0-test updated

Karolin Seeger kseeger at samba.org
Mon Apr 7 03:56:06 MDT 2014


The branch, v4-0-test has been updated
       via  e6ff129 s3: messages: Implement cleanup of dead records.
       via  b649fdb s3: smbd: Ensure we always go via getgroups_unix_user() when creating an NT token.
      from  fc185a5 tevent: fix crash bug in tevent_queue_immediate_trigger()

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


- Log -----------------------------------------------------------------
commit e6ff1291fa940294689d46bd2795281d45fbc07e
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Apr 2 16:45:25 2014 -0700

    s3: messages: Implement cleanup of dead records.
    
    When a smbd process dies, pending messages.tdb records for this process
    might not get cleaned up. Implement a cleanup for dead records that is
    triggered after a smbd dies uncleanly; the records for that PID are
    deleted.
    
    Based on a patchset from Christof Schmitt <cs at samba.org>.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Christof Schmitt <cs at samba.org>
    
    (cherry picked from commit 837671f47670b16726aa96ba7a0902974a1037eb)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10534
    Cleanup messages.tdb record after unclean smbd shutdown
    
    Autobuild-User(v4-0-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-0-test): Mon Apr  7 11:55:50 CEST 2014 on sn-devel-104

commit b649fdb8d63a5b14bb9dc567de1ddd640ae165f3
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Mar 25 08:47:39 2014 -0700

    s3: smbd: Ensure we always go via getgroups_unix_user() when creating an NT token.
    
    This has to be done in every code path that creates
    an NT token, as remote users may have been added to
    the local /etc/group database. Tokens created merely
    from the info3 structs (via the DC or via the krb5 PAC)
    won't have these local groups.
    
    This code needs to special-case the guest user, as
    this token can have the token_sid[0] set to the Guest
    SID, not the mapping of UNIX uid -> SID.
    
    Other users that may have a well-known SID
    set in token_sid[0] (like SYSTEM) are usually
    not mappable to UNIX users and can be ignored
    when adding local groups from /etc/group.
    
    Combined back-port of fixes
    6034ab521c47fc5f4732398652c9c6847ff92035 and
    a9fa09723bee3588db2168ac13f7ad0334452c11 from
    master.
    
    https://bugzilla.samba.org/show_bug.cgi?id=10508
    
    Signed-off-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 source3/auth/token_util.c    |  101 ++++++++++++++++++++++++++++++++++++++++++
 source3/include/messages.h   |    6 +++
 source3/lib/messages.c       |   17 +++++++
 source3/lib/messages_local.c |   38 ++++++++++++++++
 source3/smbd/server.c        |    7 +++
 5 files changed, 169 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c
index 841bc52..09959f4 100644
--- a/source3/auth/token_util.c
+++ b/source3/auth/token_util.c
@@ -389,6 +389,100 @@ struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
 	return result;
 }
 
+/***************************************************
+ Merge in any groups from /etc/group.
+***************************************************/
+
+static NTSTATUS add_local_groups(struct security_token *result,
+				 bool is_guest)
+{
+	gid_t *gids = NULL;
+	uint32_t getgroups_num_group_sids = 0;
+	struct passwd *pass = NULL;
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
+	int i;
+
+	if (is_guest) {
+		/*
+		 * Guest is a special case. It's always
+		 * a user that can be looked up, but
+		 * result->sids[0] is set to DOMAIN\Guest.
+		 * Lookup by account name instead.
+		 */
+		pass = Get_Pwnam_alloc(tmp_ctx, lp_guestaccount());
+	} else {
+		uid_t uid;
+
+		/* For non-guest result->sids[0] is always the user sid. */
+		if (!sid_to_uid(&result->sids[0], &uid)) {
+			/*
+			 * Non-mappable SID like SYSTEM.
+			 * Can't be in any /etc/group groups.
+			 */
+			TALLOC_FREE(tmp_ctx);
+			return NT_STATUS_OK;
+		}
+
+		pass = getpwuid_alloc(tmp_ctx, uid);
+		if (pass == NULL) {
+			DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
+				sid_string_dbg(&result->sids[0]),
+				(unsigned int)uid));
+		}
+	}
+
+	if (!pass) {
+		TALLOC_FREE(tmp_ctx);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	/*
+	 * Now we must get any groups this user has been
+	 * added to in /etc/group and merge them in.
+	 * This has to be done in every code path
+	 * that creates an NT token, as remote users
+	 * may have been added to the local /etc/group
+	 * database. Tokens created merely from the
+	 * info3 structs (via the DC or via the krb5 PAC)
+	 * won't have these local groups. Note the
+	 * groups added here will only be UNIX groups
+	 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
+	 * turns off winbindd before calling getgroups().
+	 *
+	 * NB. This is duplicating work already
+	 * done in the 'unix_user:' case of
+	 * create_token_from_sid() but won't
+	 * do anything other than be inefficient
+	 * in that case.
+	 */
+
+	if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
+			&gids, &getgroups_num_group_sids)) {
+		DEBUG(1, ("getgroups_unix_user for user %s failed\n",
+			pass->pw_name));
+		TALLOC_FREE(tmp_ctx);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	for (i=0; i<getgroups_num_group_sids; i++) {
+		NTSTATUS status;
+		struct dom_sid grp_sid;
+		gid_to_sid(&grp_sid, gids[i]);
+
+		status = add_sid_to_array_unique(result,
+					 &grp_sid,
+					 &result->sids,
+					 &result->num_sids);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
+			TALLOC_FREE(tmp_ctx);
+			return status;
+		}
+	}
+	TALLOC_FREE(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
 static NTSTATUS finalize_local_nt_token(struct security_token *result,
 					bool is_guest)
 {
@@ -396,6 +490,13 @@ static NTSTATUS finalize_local_nt_token(struct security_token *result,
 	gid_t gid;
 	NTSTATUS status;
 
+	/* Add any local groups. */
+
+	status = add_local_groups(result, is_guest);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/* Add in BUILTIN sids */
 
 	status = add_sid_to_array(result, &global_sid_World,
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 4b45901..a45f5a5 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -101,6 +101,9 @@ bool messaging_tdb_parent_init(TALLOC_CTX *mem_ctx);
 void *messaging_tdb_event(TALLOC_CTX *mem_ctx, struct messaging_context *msg,
 			  struct tevent_context *ev);
 
+NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx,
+			struct server_id pid);
+
 NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx,
 			      TALLOC_CTX *mem_ctx,
 			      struct messaging_backend **presult);
@@ -140,6 +143,9 @@ NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx,
 void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 			    struct messaging_rec *rec);
 
+void messaging_cleanup_server(struct messaging_context *msg_ctx,
+				struct server_id pid);
+
 #include "librpc/gen_ndr/ndr_messaging.h"
 
 #endif
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index cd763e7..5e738c7 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -397,4 +397,21 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx,
 	return;
 }
 
+/*
+  Call when a process has terminated abnormally.
+*/
+void messaging_cleanup_server(struct messaging_context *msg_ctx,
+				struct server_id server)
+{
+	if (server_id_is_disconnected(&server)) {
+		return;
+	}
+
+	if (!procid_is_local(&server)) {
+		return;
+	}
+
+	(void)messaging_tdb_cleanup(msg_ctx, server);
+
+}
 /** @} **/
diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c
index 6b63d72..859eeb8 100644
--- a/source3/lib/messages_local.c
+++ b/source3/lib/messages_local.c
@@ -45,6 +45,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "messages.h"
+#include "serverid.h"
 #include "lib/tdb_wrap/tdb_wrap.h"
 #include "lib/param/param.h"
 
@@ -200,6 +201,43 @@ static TDB_DATA message_key_pid(TALLOC_CTX *mem_ctx, struct server_id pid)
 	return kbuf;
 }
 
+/*******************************************************************
+ Called when a process has terminated abnormally. Remove all messages
+ pending for it.
+******************************************************************/
+
+NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx,
+				struct server_id pid)
+{
+	struct messaging_tdb_context *ctx = talloc_get_type(
+					msg_ctx->local->private_data,
+					struct messaging_tdb_context);
+	struct tdb_wrap *tdb = ctx->tdb;
+	TDB_DATA key;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	key = message_key_pid(frame, pid);
+	/*
+	 * We have to lock the key to avoid
+	 * races in case the server_id was
+	 * re-used and is active (a remote
+	 * possibility, true). We only
+	 * clean up the database if we
+	 * know server_id doesn't exist
+	 * while checked under the chainlock.
+	 */
+	if (tdb_chainlock(tdb->tdb, key) != 0) {
+		TALLOC_FREE(frame);
+		return NT_STATUS_LOCK_NOT_GRANTED;
+	}
+	if (!serverid_exists(&pid)) {
+		(void)tdb_delete(tdb->tdb, key);
+	}
+	tdb_chainunlock(tdb->tdb, key);
+	TALLOC_FREE(frame);
+	return NT_STATUS_OK;
+}
+
 /*
   Fetch the messaging array for a process
  */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index a86fa48..86c20ba 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -455,6 +455,13 @@ static void remove_child_pid(struct smbd_parent_context *parent,
 						parent);
 			DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n"));
 		}
+
+		/*
+		 * Ensure we flush any stored messages
+		 * queued for the child process that
+		 * terminated uncleanly.
+		 */
+		messaging_cleanup_server(parent->msg_ctx, child_id);
 	}
 
 	if (!serverid_deregister(child_id)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list