summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/uid.c252
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