[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-557-gd380c49

Andrew Tridgell tridge at samba.org
Thu Mar 19 00:39:18 GMT 2009


The branch, master has been updated
       via  d380c49791d1010d759369cab12d93b6fbd48dc7 (commit)
       via  13b6663e23a424473d14324ac229a21e1e90580a (commit)
      from  710948c7885b228afe5e1b3bed005f50c57d519b (commit)

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


- Log -----------------------------------------------------------------
commit d380c49791d1010d759369cab12d93b6fbd48dc7
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Mar 19 11:23:49 2009 +1100

    use the tevent nesting code to avoid the uid problem in the VFS
    backend
    
    The vfs_unixuid module changes the uid of the process when executing
    operations on behalf of the user. Within the VFS backend we may rely
    on semi-async calls, such as winbind calls, which will call the event
    loop again. To cope with this we need to ensure that while inside
    those calls we revert the uid to root, then revert back to the
    connected user when we have finished with the semi-async calls.

commit 13b6663e23a424473d14324ac229a21e1e90580a
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Mar 19 11:21:36 2009 +1100

    fixed a logic bug in the tevent nesting code
    
    The event nesting code never triggered as nesting.level was never
    greater than 1. The main event loop needs to increase the nesting
    level by 1.
    
    I also added a paranoia check to the nesting setup call. The API as
    currently written cannot support multiple nesting hooks, so we need to
    abort if multiple hooks are tried.

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

Summary of changes:
 lib/tevent/tevent.c                 |   14 +++++++-
 source4/ntvfs/unixuid/vfs_unixuid.c |   66 +++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index ba2d93f..56fd6ae 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -427,6 +427,14 @@ void tevent_loop_set_nesting_hook(struct tevent_context *ev,
 				  tevent_nesting_hook hook,
 				  void *private_data)
 {
+	if (ev->nesting.hook_fn && 
+	    (ev->nesting.hook_fn != hook ||
+	     ev->nesting.hook_private != private_data)) {
+		/* the way the nesting hook code is currently written
+		   we cannot support two different nesting hooks at the
+		   same time. */
+		tevent_abort(ev, "tevent: Violation of nesting hook rules\n");
+	}
 	ev->nesting.hook_fn = hook;
 	ev->nesting.hook_private = private_data;
 }
@@ -593,5 +601,9 @@ int tevent_common_loop_wait(struct tevent_context *ev,
 */
 int _tevent_loop_wait(struct tevent_context *ev, const char *location)
 {
-	return ev->ops->loop_wait(ev, location);
+	int ret;
+	ev->nesting.level++;
+	ret = ev->ops->loop_wait(ev, location);
+	ev->nesting.level--;
+	return ret;
 }
diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c
index db22a85..062fa41 100644
--- a/source4/ntvfs/unixuid/vfs_unixuid.c
+++ b/source4/ntvfs/unixuid/vfs_unixuid.c
@@ -26,6 +26,8 @@
 #include "auth/auth.h"
 #include "ntvfs/ntvfs.h"
 #include "libcli/wbclient/wbclient.h"
+#define TEVENT_DEPRECATED
+#include <tevent.h>
 
 struct unixuid_private {
 	struct wbc_context *wbc_ctx;
@@ -91,6 +93,64 @@ static NTSTATUS set_unix_security(struct unix_sec_ctx *sec)
 	return NT_STATUS_OK;
 }
 
+static int unixuid_nesting_level;
+
+/*
+  called at the start and end of a tevent nesting loop. Needs to save/restore
+  unix security context
+ */
+static int unixuid_event_nesting_hook(struct tevent_context *ev,
+				      void *private_data,
+				      uint32_t level,
+				      bool begin,
+				      void *stack_ptr,
+				      const char *location)
+{
+	struct unix_sec_ctx *sec_ctx;
+
+	if (unixuid_nesting_level == 0) {
+		/* we don't need to do anything unless we are nested
+		   inside of a call in this module */
+		return 0;
+	}
+
+	if (begin) {
+		sec_ctx = save_unix_security(ev);
+		if (sec_ctx == NULL) {
+			DEBUG(0,("%s: Failed to save security context\n", location));
+			return -1;
+		}
+		*(struct unix_sec_ctx **)stack_ptr = sec_ctx;
+		if (seteuid(0) != 0 || setegid(0) != 0) {
+			DEBUG(0,("%s: Failed to change to root\n", location));
+			return -1;			
+		}
+	} else {
+		/* called when we come out of a nesting level */
+		NTSTATUS status;
+
+		sec_ctx = *(struct unix_sec_ctx **)stack_ptr;
+		if (sec_ctx == NULL) {
+			/* this happens the first time this function
+			   is called, as we install the hook while
+			   inside an event in unixuid_connect() */
+			return 0;
+		}
+
+		sec_ctx = talloc_get_type_abort(sec_ctx, struct unix_sec_ctx);
+		status = set_unix_security(sec_ctx);
+		talloc_free(sec_ctx);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,("%s: Failed to revert security context (%s)\n", 
+				 location, nt_errstr(status)));
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
 /*
   form a unix_sec_ctx from the current security_token
 */
@@ -219,7 +279,9 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs,
 	struct unix_sec_ctx *sec; \
 	status = unixuid_setup_security(ntvfs, req, &sec); \
 	NT_STATUS_NOT_OK_RETURN(status); \
+	unixuid_nesting_level++; \
 	status = ntvfs_next_##op args; \
+	unixuid_nesting_level--; \
 	status2 = set_unix_security(sec); \
 	talloc_free(sec); \
 	if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \
@@ -252,6 +314,10 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
 	priv->last_sec_ctx = NULL;
 	priv->last_token = NULL;
 
+	tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx, 
+				     unixuid_event_nesting_hook,
+				     &unixuid_nesting_level);
+
 	/* we don't use PASS_THRU_REQ here, as the connect operation runs with 
 	   root privileges. This allows the backends to setup any database
 	   links they might need during the connect. */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list