[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Apr 11 14:57:02 MDT 2011


The branch, master has been updated
       via  e3c3b4d s3-printing: Use become_user_by_session() function.
       via  b137156 s3-smbd: Added a become_user_by_session() function.
       via  27cb378 s3-smbd: Added a change_to_user_by_session() function.
      from  d1ded27 s3: Wrap creating the svcctl keys in a transaction

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


- Log -----------------------------------------------------------------
commit e3c3b4daa425fede17203b474fa35493afbda2a9
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Apr 1 11:55:27 2011 +0200

    s3-printing: Use become_user_by_session() function.
    
    We create a fake connection here and don't have an vuid. So work with
    the session_info directly here.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Mon Apr 11 22:56:12 CEST 2011 on sn-devel-104

commit b137156acbf7c39c86f306100cccc65b441a3209
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Apr 1 11:54:49 2011 +0200

    s3-smbd: Added a become_user_by_session() function.
    
    This uses the provided session_info instead of searching the user via
    the vuid. This is useful to work with fake connnection you need to
    create if someone connects directly to a rpc service.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>

commit 27cb378283f2cf072151f1c624837741f40c298a
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Apr 5 13:54:31 2011 +0200

    s3-smbd: Added a change_to_user_by_session() function.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 source3/printing/nt_printing.c |    6 +-
 source3/smbd/proto.h           |    4 +
 source3/smbd/uid.c             |  187 ++++++++++++++++++++++++----------------
 3 files changed, 120 insertions(+), 77 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 46cfdb3..a7539f6 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -636,7 +636,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
 		goto error_free_conn;
 	}
 
-	if (!become_user(conn, get_current_vuid(conn))) {
+	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
 		*perr = WERR_ACCESS_DENIED;
 		goto error_free_conn;
@@ -1019,7 +1019,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 		goto err_free_conn;
 	}
 
-	if (!become_user(conn, get_current_vuid(conn))) {
+	if (!become_user_by_session(conn, p->session_info)) {
 		DEBUG(0, ("failed to become user\n"));
 		err = WERR_ACCESS_DENIED;
 		goto err_free_conn;
@@ -1948,7 +1948,7 @@ bool delete_driver_files(const struct auth_serversupplied_info *session_info,
 		goto err_free_conn;
 	}
 
-	if (!become_user(conn, get_current_vuid(conn))) {
+	if (!become_user_by_session(conn, session_info)) {
 		DEBUG(0, ("failed to become user\n"));
 		ret = false;
 		goto err_free_conn;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index f4b2e5e..a0c94b4 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1050,12 +1050,16 @@ void reply_transs2(struct smb_request *req);
 bool change_to_guest(void);
 void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid);
 bool change_to_user(connection_struct *conn, uint16 vuid);
+bool change_to_user_by_session(connection_struct *conn,
+			       const struct auth_serversupplied_info *session_info);
 bool change_to_root_user(void);
 bool become_authenticated_pipe_user(struct pipes_struct *p);
 bool unbecome_authenticated_pipe_user(void);
 void become_root(void);
 void unbecome_root(void);
 bool become_user(connection_struct *conn, uint16 vuid);
+bool become_user_by_session(connection_struct *conn,
+			    const struct auth_serversupplied_info *session_info);
 bool unbecome_user(void);
 uid_t get_current_uid(connection_struct *conn);
 gid_t get_current_gid(connection_struct *conn);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 7938cc4..b554b36 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -231,104 +231,54 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
  stack, but modify the current_user entries.
 ****************************************************************************/
 
-bool change_to_user(connection_struct *conn, uint16 vuid)
+static bool change_to_user_internal(connection_struct *conn,
+				    const struct auth_serversupplied_info *session_info,
+				    uint16_t vuid)
 {
-	const struct auth_serversupplied_info *session_info = NULL;
-	user_struct *vuser;
 	int snum;
 	gid_t gid;
 	uid_t uid;
 	char group_c;
 	int num_groups = 0;
 	gid_t *group_list = NULL;
-
-	if (!conn) {
-		DEBUG(2,("change_to_user: Connection not open\n"));
-		return(False);
-	}
-
-	vuser = get_valid_user_struct(conn->sconn, vuid);
-
-	/*
-	 * We need a separate check in security=share mode due to vuid
-	 * always being UID_FIELD_INVALID. If we don't do this then
-	 * in share mode security we are *always* changing uid's between
-	 * SMB's - this hurts performance - Badly.
-	 */
-
-	if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
-	   (current_user.ut.uid == conn->session_info->utok.uid)) {
-		DEBUG(4,("change_to_user: Skipping user change - already "
-			 "user\n"));
-		return(True);
-	} else if ((current_user.conn == conn) && 
-		   (vuser != NULL) && (current_user.vuid == vuid) &&
-		   (current_user.ut.uid == vuser->session_info->utok.uid)) {
-		DEBUG(4,("change_to_user: Skipping user change - already "
-			 "user\n"));
-		return(True);
-	}
+	bool ok;
 
 	snum = SNUM(conn);
 
-	session_info = vuser ? vuser->session_info : conn->session_info;
-
-	if (!session_info) {
-		/* Invalid vuid sent - even with security = share. */
-		DEBUG(2,("change_to_user: Invalid vuid %d used on "
-			 "share %s.\n",vuid, lp_servicename(snum) ));
-		return false;
-	}
-
-	if (!check_user_ok(conn, vuid, session_info, snum)) {
-		DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) "
+	ok = check_user_ok(conn, vuid, session_info, snum);
+	if (!ok) {
+		DEBUG(2,("SMB user %s (unix user %s) "
 			 "not permitted access to share %s.\n",
 			 session_info->sanitized_username,
-			 session_info->unix_name, vuid,
+			 session_info->unix_name,
 			 lp_servicename(snum)));
 		return false;
 	}
 
-	/* security = share sets force_user. */
-	if (!conn->force_user && !vuser) {
-		DEBUG(2,("change_to_user: Invalid vuid used %d in accessing "
-			"share %s.\n",vuid, lp_servicename(snum) ));
-		return False;
-	}
-
-	/*
-	 * conn->session_info is now correctly set up with a copy we can mess
-	 * with for force_group etc.
-	 */
-
 	uid = conn->session_info->utok.uid;
 	gid = conn->session_info->utok.gid;
 	num_groups = conn->session_info->utok.ngroups;
 	group_list  = conn->session_info->utok.groups;
 
 	/*
-	 * See if we should force group for this service.
-	 * If so this overrides any group set in the force
-	 * user code.
+	 * See if we should force group for this service. If so this overrides
+	 * any group set in the force user code.
 	 */
-
 	if((group_c = *lp_force_group(snum))) {
 
 		SMB_ASSERT(conn->force_group_gid != (gid_t)-1);
 
-		if(group_c == '+') {
+		if (group_c == '+') {
+			int i;
 
 			/*
-			 * Only force group if the user is a member of
-			 * the service group. Check the group memberships for
-			 * this user (we already have this) to
-			 * see if we should force the group.
+			 * Only force group if the user is a member of the
+			 * service group. Check the group memberships for this
+			 * user (we already have this) to see if we should force
+			 * the group.
 			 */
-
-			int i;
 			for (i = 0; i < num_groups; i++) {
-				if (group_list[i]
-				    == conn->force_group_gid) {
+				if (group_list[i] == conn->force_group_gid) {
 					conn->session_info->utok.gid =
 						conn->force_group_gid;
 					gid = conn->force_group_gid;
@@ -345,22 +295,94 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
 		}
 	}
 
-	/* Now set current_user since we will immediately also call
-	   set_sec_ctx() */
-
+	/*Set current_user since we will immediately also call set_sec_ctx() */
 	current_user.ut.ngroups = num_groups;
 	current_user.ut.groups  = group_list;
 
-	set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups,
+	set_sec_ctx(uid,
+		    gid,
+		    current_user.ut.ngroups,
+		    current_user.ut.groups,
 		    conn->session_info->security_token);
 
 	current_user.conn = conn;
 	current_user.vuid = vuid;
 
-	DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
-		 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
+	DEBUG(5, ("Impersonated user: uid=(%d,%d), gid=(%d,%d)\n",
+		 (int)getuid(),
+		 (int)geteuid(),
+		 (int)getgid(),
+		 (int)getegid()));
 
-	return(True);
+	return true;
+}
+
+bool change_to_user(connection_struct *conn, uint16_t vuid)
+{
+	const struct auth_serversupplied_info *session_info = NULL;
+	user_struct *vuser;
+	int snum = SNUM(conn);
+
+	if (!conn) {
+		DEBUG(2,("Connection not open\n"));
+		return(False);
+	}
+
+	vuser = get_valid_user_struct(conn->sconn, vuid);
+
+	/*
+	 * We need a separate check in security=share mode due to vuid
+	 * always being UID_FIELD_INVALID. If we don't do this then
+	 * in share mode security we are *always* changing uid's between
+	 * SMB's - this hurts performance - Badly.
+	 */
+
+	if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
+	   (current_user.ut.uid == conn->session_info->utok.uid)) {
+		DEBUG(4,("Skipping user change - already "
+			 "user\n"));
+		return(True);
+	} else if ((current_user.conn == conn) &&
+		   (vuser != NULL) && (current_user.vuid == vuid) &&
+		   (current_user.ut.uid == vuser->session_info->utok.uid)) {
+		DEBUG(4,("Skipping user change - already "
+			 "user\n"));
+		return(True);
+	}
+
+	session_info = vuser ? vuser->session_info : conn->session_info;
+
+	if (session_info == NULL) {
+		/* Invalid vuid sent - even with security = share. */
+		DEBUG(2,("Invalid vuid %d used on "
+			 "share %s.\n", vuid, lp_servicename(snum) ));
+		return false;
+	}
+
+	/* security = share sets force_user. */
+	if (!conn->force_user && vuser == NULL) {
+		DEBUG(2,("Invalid vuid used %d in accessing "
+			"share %s.\n", vuid, lp_servicename(snum) ));
+		return False;
+	}
+
+	return change_to_user_internal(conn, session_info, vuid);
+}
+
+bool change_to_user_by_session(connection_struct *conn,
+			       const struct auth_serversupplied_info *session_info)
+{
+	SMB_ASSERT(conn != NULL);
+	SMB_ASSERT(session_info != NULL);
+
+	if ((current_user.conn == conn) &&
+	    (current_user.ut.uid == session_info->utok.uid)) {
+		DEBUG(7, ("Skipping user change - already user\n"));
+
+		return true;
+	}
+
+	return change_to_user_internal(conn, session_info, UID_FIELD_INVALID);
 }
 
 /****************************************************************************
@@ -506,6 +528,23 @@ bool become_user(connection_struct *conn, uint16 vuid)
 	return True;
 }
 
+bool become_user_by_session(connection_struct *conn,
+			    const struct auth_serversupplied_info *session_info)
+{
+	if (!push_sec_ctx())
+		return false;
+
+	push_conn_ctx();
+
+	if (!change_to_user_by_session(conn, session_info)) {
+		pop_sec_ctx();
+		pop_conn_ctx();
+		return false;
+	}
+
+	return true;
+}
+
 bool unbecome_user(void)
 {
 	pop_sec_ctx();


-- 
Samba Shared Repository


More information about the samba-cvs mailing list