diff options
-rw-r--r-- | source3/smbd/uid.c | 252 |
1 files changed, 30 insertions, 222 deletions
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d749470793..f3a606a1b1 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -28,108 +28,30 @@ extern int DEBUGLEVEL; /* what user is current? */ extern struct current_user current_user; -pstring OriginalDir; - -/**************************************************************************** - Initialise the uid routines. -****************************************************************************/ - -void init_uid(void) -{ - current_user.uid = geteuid(); - current_user.gid = getegid(); - - if (current_user.gid != 0 && current_user.uid == 0) { - gain_root_group_privilege(); - } - - current_user.conn = NULL; - current_user.vuid = UID_FIELD_INVALID; - - dos_ChDir(OriginalDir); -} - -/**************************************************************************** - Become the specified uid. -****************************************************************************/ - -static BOOL become_uid(uid_t uid) -{ - if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) { - static int done; - if (!done) { - DEBUG(1,("WARNING: using uid %d is a security risk\n",(int)uid)); - done=1; - } - } - - set_effective_uid(uid); - - current_user.uid = uid; - -#ifdef WITH_PROFILE - profile_p->uid_changes++; -#endif - - return(True); -} - - -/**************************************************************************** - Become the specified gid. -****************************************************************************/ - -static BOOL become_gid(gid_t gid) -{ - if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) { - DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid)); - } - - set_effective_gid(gid); - - current_user.gid = gid; - - return(True); -} - - -/**************************************************************************** - Become the specified uid and gid. -****************************************************************************/ - -static BOOL become_id(uid_t uid,gid_t gid) -{ - return(become_gid(gid) && become_uid(uid)); -} - /**************************************************************************** Become the guest user. ****************************************************************************/ BOOL become_guest(void) { - BOOL ret; - static struct passwd *pass=NULL; - - if (!pass) - pass = Get_Pwnam(lp_guestaccount(-1),True); - if (!pass) return(False); - + static struct passwd *pass=NULL; + + if (!pass) + pass = Get_Pwnam(lp_guestaccount(-1),True); + if (!pass) return(False); + #ifdef AIX - /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ - initgroups(pass->pw_name, (gid_t)pass->pw_gid); + /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before + setting IDs */ + initgroups(pass->pw_name, (gid_t)pass->pw_gid); #endif - - ret = become_id(pass->pw_uid,pass->pw_gid); - - if (!ret) { - DEBUG(1,("Failed to become guest. Invalid guest account?\n")); - } - - current_user.conn = NULL; - current_user.vuid = UID_FIELD_INVALID; - - return(ret); + + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL); + + current_user.conn = NULL; + current_user.vuid = UID_FIELD_INVALID; + + return True; } /******************************************************************* @@ -153,7 +75,6 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return(True); } - /**************************************************************************** Become the user of a connection number. ****************************************************************************/ @@ -162,7 +83,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum; - gid_t gid; + gid_t gid; uid_t uid; char group_c; @@ -189,8 +110,6 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return(True); } - unbecome_user(); - snum = SNUM(conn); if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) @@ -242,23 +161,8 @@ BOOL become_user(connection_struct *conn, uint16 vuid) } } - if (!become_gid(gid)) - return(False); + set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups); -#ifdef HAVE_SETGROUPS - if (!(conn && conn->ipc)) { - /* groups stuff added by ih/wreu */ - if (current_user.ngroups > 0) - if (sys_setgroups(current_user.ngroups, - current_user.groups)<0) { - DEBUG(0,("sys_setgroups call failed!\n")); - } - } -#endif - - if (!conn->admin_user && !become_uid(uid)) - return(False); - current_user.conn = conn; current_user.vuid = vuid; @@ -274,26 +178,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) BOOL unbecome_user(void ) { - if (!current_user.conn) - return(False); - - dos_ChDir(OriginalDir); - - set_effective_uid(0); - set_effective_gid(0); - - if (geteuid() != 0) { - DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); - } - if (getegid() != 0) { - DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); - } - - current_user.uid = 0; - current_user.gid = 0; - - if (dos_ChDir(OriginalDir) != 0) - DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) ); + set_root_sec_ctx(); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); @@ -312,24 +197,13 @@ BOOL unbecome_user(void ) BOOL become_authenticated_pipe_user(pipes_struct *p) { - /* - * Go back to root. - */ - - if(!unbecome_user()) - return False; - - /* - * Now become the authenticated user stored in the pipe struct. - */ + BOOL res = push_sec_ctx(); - if(!become_id(p->uid, p->gid)) { - /* Go back to the connection user. */ - become_user(p->conn, p->vuid); + if (!res) { return False; } - return True; + set_sec_ctx(p->uid, p->gid, 0, NULL); /* fix group stuff */ } /**************************************************************************** @@ -340,88 +214,22 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) BOOL unbecome_authenticated_pipe_user(pipes_struct *p) { - if(!become_id(0,0)) { - DEBUG(0,("unbecome_authenticated_pipe_user: Unable to go back to root.\n")); - return False; - } - - return become_user(p->conn, p->vuid); + return pop_sec_ctx(); } -static struct current_user current_user_saved; -static int become_root_depth; -static pstring become_root_dir; - -/**************************************************************************** -This is used when we need to do a privileged operation (such as mucking -with share mode files) and temporarily need root access to do it. This -call should always be paired with an unbecome_root() call immediately -after the operation - -Set save_dir if you also need to save/restore the CWD -****************************************************************************/ +/* Temporarily become a root user. Must match with unbecome_root(). */ -void become_root(BOOL save_dir) +void become_root(void) { - if (become_root_depth) { - DEBUG(0,("ERROR: become root depth is non zero\n")); - } - if (save_dir) - dos_GetWd(become_root_dir); - - current_user_saved = current_user; - become_root_depth = 1; - - become_uid(0); - become_gid(0); + push_sec_ctx(); + set_root_sec_ctx(); } -/**************************************************************************** -When the privileged operation is over call this - -Set save_dir if you also need to save/restore the CWD -****************************************************************************/ +/* Unbecome the root user */ -void unbecome_root(BOOL restore_dir) +void unbecome_root(void) { - if (become_root_depth != 1) { - DEBUG(0,("ERROR: unbecome root depth is %d\n", - become_root_depth)); - } - - /* we might have done a become_user() while running as root, - if we have then become root again in order to become - non root! */ - if (current_user.uid != 0) { - become_uid(0); - } - - /* restore our gid first */ - if (!become_gid(current_user_saved.gid)) { - DEBUG(0,("ERROR: Failed to restore gid\n")); - exit_server("Failed to restore gid"); - } - -#ifdef HAVE_SETGROUPS - if (current_user_saved.ngroups > 0) { - if (sys_setgroups(current_user_saved.ngroups, - current_user_saved.groups)<0) - DEBUG(0,("ERROR: sys_setgroups call failed!\n")); - } -#endif - - /* now restore our uid */ - if (!become_uid(current_user_saved.uid)) { - DEBUG(0,("ERROR: Failed to restore uid\n")); - exit_server("Failed to restore uid"); - } - - if (restore_dir) - dos_ChDir(become_root_dir); - - current_user = current_user_saved; - - become_root_depth = 0; + pop_sec_ctx(); } #undef OLD_NTDOMAIN |