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 <[email protected]>
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 <[email protected]>
    
    Autobuild-User: Jeremy Allison <[email protected]>
    Autobuild-Date: Mon Apr 11 22:56:12 CEST 2011 on sn-devel-104

commit b137156acbf7c39c86f306100cccc65b441a3209
Author: Andreas Schneider <[email protected]>
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 <[email protected]>

commit 27cb378283f2cf072151f1c624837741f40c298a
Author: Andreas Schneider <[email protected]>
Date:   Tue Apr 5 13:54:31 2011 +0200

    s3-smbd: Added a change_to_user_by_session() function.
    
    Signed-off-by: Jeremy Allison <[email protected]>

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

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

Reply via email to