From 78348cb8f8afe6454bd0e3a9f0b93b8c9c0b85b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Oct 1997 09:15:58 +0000 Subject: add become_root()/unbecome_root() calls. These should be used around regions of the code that need root privilages but which normally don't have them (ie. when processing most SMBs). These functions can optionally save/restore the current working directory as well updated several places in the code that previously used unbecome_user() to achieve the same thing to now use become_root() and unbecome_root() changed close_file() to take an additional argument which says whether this is a normal SMBclose type call or a close that resulted from some other action, such as the close of a connection. If it is a abnormal close then don't use magic scripts or print files. changed sys_utime() to ignore any attempt to set the modification time to 0 or -1. We've had reports that files have had their time set to 0 so this should catch those. --- source/smbd/uid.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'source/smbd/uid.c') diff --git a/source/smbd/uid.c b/source/smbd/uid.c index cdc4e474c61..fe2cb5a652d 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -258,6 +258,8 @@ BOOL become_user(int cnum, uint16 vuid) if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) DEBUG(0,("setgroups call failed!\n")); + } else { + current_user.ngroups = 0; } #endif @@ -318,7 +320,8 @@ BOOL unbecome_user(void ) current_user.uid = initial_uid; current_user.gid = initial_gid; - + current_user.ngroups = 0; + if (ChDir(OriginalDir) != 0) DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", timestring(),OriginalDir)); @@ -476,3 +479,82 @@ int smbrun(char *cmd,char *outfile,BOOL shared) #endif return 1; } + + + +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 privilaged 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 +****************************************************************************/ +void become_root(int save_dir) +{ + if (become_root_depth) { + DEBUG(0,("ERROR: become root depth is non zero\n")); + } + if (save_dir) + GetWd(become_root_dir); + + current_user_saved = current_user; + become_root_depth = 1; + + become_gid(0); + become_uid(0); +} + +/**************************************************************************** +When the privilaged operation is over call this + +Set save_dir if you also need to save/restore the CWD +****************************************************************************/ +void unbecome_root(int restore_dir) +{ + 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"); + } + +#ifndef NO_SETGROUPS + if (current_user_saved.ngroups > 0) { + if (setgroups(current_user_saved.ngroups, + current_user_saved.groups)<0) + DEBUG(0,("ERROR: 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) + ChDir(become_root_dir); + + current_user = current_user_saved; + + become_root_depth = 0; +} + + + -- cgit From 51b435abde1e7a30f9d1fa4b8c41b7935b86f90c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Oct 1997 11:57:13 +0000 Subject: fix the order of become_uid() and become_gid() in become_root(). This was a harmless bug but left log entries --- source/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/smbd/uid.c') diff --git a/source/smbd/uid.c b/source/smbd/uid.c index fe2cb5a652d..db1e5e94c3b 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -505,8 +505,8 @@ void become_root(int save_dir) current_user_saved = current_user; become_root_depth = 1; - become_gid(0); become_uid(0); + become_gid(0); } /**************************************************************************** -- cgit