From 81e398963dbaed9c6661c336fe98329098576b94 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Jun 1996 15:25:30 +0000 Subject: - moved the uid handling to uid.c - added setfsuid() support (for Linux) - started adding some of Lukes changes, just the loadparm and ipc ones so far (This used to be commit 72543810ce3eb5ea7b141f957edf38b4c46b1ea4) --- source3/smbd/uid.c | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 source3/smbd/uid.c (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c new file mode 100644 index 0000000000..f287c733c4 --- /dev/null +++ b/source3/smbd/uid.c @@ -0,0 +1,364 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + uid/user handling + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" + +extern int DEBUGLEVEL; + +extern connection_struct Connections[]; + +static int initial_uid; +static int initial_gid; +static int old_umask = 022; + +int current_uid; +int current_gid; + +static pstring OriginalDir; + +/* have I done a become_user? */ +static struct { + int cnum, uid; +} last_user; + +/**************************************************************************** +initialise the uid routines +****************************************************************************/ +void init_uid(void) +{ + initial_uid = current_uid = geteuid(); + initial_gid = current_gid = getegid(); + + if (initial_gid != 0 && initial_uid == 0) + { +#ifdef HPUX + setresgid(0,0,0); +#else + setgid(0); + setegid(0); +#endif + } + + initial_uid = geteuid(); + initial_gid = getegid(); + + last_user.cnum = -1; + + GetWd(OriginalDir); +} + + +/**************************************************************************** + become the specified uid +****************************************************************************/ +static BOOL become_uid(int uid) +{ + if (initial_uid != 0) + return(True); + +#ifdef AIX + { + /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */ + priv_t priv; + + priv.pv_priv[0] = 0; + priv.pv_priv[1] = 0; + if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH, + &priv, sizeof(priv_t)) < 0 || + setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 || + seteuid((uid_t)uid) < 0) + DEBUG(1,("Can't set uid (AIX3)")); + } +#endif + +#ifdef USE_SETRES + if (setresuid(-1,uid,-1) != 0) +#elif defined(USE_SETFS) + if (setfsuid(uid) != 0) +#else + if ((seteuid(uid) != 0) && + (setuid(uid) != 0)) +#endif + { + DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n", + uid,getuid(), geteuid())); + if (uid > 32000) + DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); + return(False); + } + + if (((uid == -1) || (uid == 65535)) && geteuid() != uid) { + DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n")); + return(False); + } + + current_uid = uid; + + return(True); +} + + +/**************************************************************************** + become the specified gid +****************************************************************************/ +static BOOL become_gid(int gid) +{ + if (initial_uid != 0) + return(True); + +#ifdef USE_SETRES + if (setresgid(-1,gid,-1) != 0) +#elif defined(USE_SETFS) + if (setfsgid(gid) != 0) +#else + if (setgid(gid) != 0) +#endif + { + DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n", + gid,getgid(),getegid())); + if (gid > 32000) + DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); + return(False); + } + + current_gid = gid; + + return(True); +} + + +/**************************************************************************** + become the specified uid and gid +****************************************************************************/ +static BOOL become_id(int uid,int gid) +{ + return(become_gid(gid) && become_uid(uid)); +} + +/**************************************************************************** +become the guest user +****************************************************************************/ +BOOL become_guest(void) +{ + BOOL ret; + static struct passwd *pass=NULL; + + if (initial_uid != 0) + return(True); + + if (!pass) + pass = Get_Pwnam(lp_guestaccount(-1),True); + if (!pass) return(False); + + ret = become_id(pass->pw_uid,pass->pw_gid); + + if (!ret) + DEBUG(1,("Failed to become guest. Invalid guest account?\n")); + + last_user.cnum = -2; + + return(ret); +} + +/******************************************************************* +check if a username is OK +********************************************************************/ +static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) +{ + int i; + for (i=0;iuid) return(True); + + if (!user_ok(vuser->name,snum)) return(False); + + i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE; + Connections[cnum].uid_cache.list[i] = vuser->uid; + + if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE) + Connections[cnum].uid_cache.entries++; + + return(True); +} + + +/**************************************************************************** + become the user of a connection number +****************************************************************************/ +BOOL become_user(int cnum, int uid) +{ + int new_umask; + user_struct *vuser; + int snum,gid; + int ngroups; + gid_t *groups; + + if (last_user.cnum == cnum && last_user.uid == uid) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } + + unbecome_user(); + + if (!OPEN_CNUM(cnum)) { + DEBUG(2,("Connection %d not open\n",cnum)); + return(False); + } + + snum = Connections[cnum].service; + + if (Connections[cnum].force_user || + lp_security() == SEC_SHARE || + !(vuser = get_valid_user_struct(uid)) || + !check_user_ok(cnum,vuser,snum)) { + uid = Connections[cnum].uid; + gid = Connections[cnum].gid; + groups = Connections[cnum].groups; + ngroups = Connections[cnum].ngroups; + } else { + if (!vuser) { + DEBUG(2,("Invalid vuid used %d\n",uid)); + return(False); + } + uid = vuser->uid; + if(!*lp_force_group(snum)) + gid = vuser->gid; + else + gid = Connections[cnum].gid; + groups = vuser->user_groups; + ngroups = vuser->user_ngroups; + } + + if (initial_uid == 0) + { + if (!become_gid(gid)) return(False); + +#ifndef NO_SETGROUPS + if (!IS_IPC(cnum)) { + /* groups stuff added by ih/wreu */ + if (ngroups > 0) + if (setgroups(ngroups,groups)<0) + DEBUG(0,("setgroups call failed!\n")); + } +#endif + + if (!Connections[cnum].admin_user && !become_uid(uid)) + return(False); + } + + new_umask = 0777 & ~CREATE_MODE(cnum); + old_umask = umask(new_umask); + + last_user.cnum = cnum; + last_user.uid = uid; + + DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n", + getuid(),geteuid(),getgid(),getegid(),new_umask)); + + return(True); +} + +/**************************************************************************** + unbecome the user of a connection number +****************************************************************************/ +BOOL unbecome_user(void ) +{ + if (last_user.cnum == -1) + return(False); + + ChDir(OriginalDir); + + umask(old_umask); + + if (initial_uid == 0) + { +#ifdef USE_SETRES + setresuid(-1,getuid(),-1); + setresgid(-1,getgid(),-1); +#elif defined(USE_SETFS) + setfsuid(initial_uid); + setfsgid(initial_gid); +#else + if (seteuid(initial_uid) != 0) + setuid(initial_uid); + setgid(initial_gid); +#endif + } +#ifdef NO_EID + if (initial_uid == 0) + DEBUG(2,("Running with no EID\n")); + initial_uid = getuid(); + initial_gid = getgid(); +#else + if (geteuid() != initial_uid) + { + DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); + initial_uid = geteuid(); + } + if (getegid() != initial_gid) + { + DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); + initial_gid = getegid(); + } +#endif + + current_uid = initial_uid; + current_gid = initial_gid; + + if (ChDir(OriginalDir) != 0) + DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", + timestring(),OriginalDir)); + + DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", + getuid(),geteuid(),getgid(),getegid())); + + last_user.cnum = -1; + + return(True); +} + + +/**************************************************************************** +run a command via system() using smbrun, being careful about uid/gid handling +****************************************************************************/ +int smbrun(char *cmd,char *outfile) +{ + int ret; + pstring syscmd; + char *path = lp_smbrun(); + + if (!file_exist(path,NULL)) + { + DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path)); + return(1); + } + + sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"", + path,current_uid,current_gid,cmd, + outfile?outfile:"/dev/null"); + + DEBUG(5,("smbrun - running %s ",syscmd)); + ret = system(syscmd); + DEBUG(5,("gave %d\n",ret)); + return(ret); +} + + -- cgit From a2c1623827406667a4f2f058c24f1d971f6627f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 06:42:03 +0000 Subject: a huge pile of changes :-) The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c) --- source3/smbd/uid.c | 54 +++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f287c733c4..625303350a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -30,23 +30,18 @@ static int initial_uid; static int initial_gid; static int old_umask = 022; -int current_uid; -int current_gid; - static pstring OriginalDir; -/* have I done a become_user? */ -static struct { - int cnum, uid; -} last_user; +/* what user is current? */ +struct current_user current_user; /**************************************************************************** initialise the uid routines ****************************************************************************/ void init_uid(void) { - initial_uid = current_uid = geteuid(); - initial_gid = current_gid = getegid(); + initial_uid = current_user.uid = geteuid(); + initial_gid = current_user.gid = getegid(); if (initial_gid != 0 && initial_uid == 0) { @@ -61,7 +56,7 @@ void init_uid(void) initial_uid = geteuid(); initial_gid = getegid(); - last_user.cnum = -1; + current_user.cnum = -1; GetWd(OriginalDir); } @@ -111,7 +106,7 @@ static BOOL become_uid(int uid) return(False); } - current_uid = uid; + current_user.uid = uid; return(True); } @@ -140,7 +135,7 @@ static BOOL become_gid(int gid) return(False); } - current_gid = gid; + current_user.gid = gid; return(True); } @@ -174,7 +169,7 @@ BOOL become_guest(void) if (!ret) DEBUG(1,("Failed to become guest. Invalid guest account?\n")); - last_user.cnum = -2; + current_user.cnum = -2; return(ret); } @@ -208,10 +203,9 @@ BOOL become_user(int cnum, int uid) int new_umask; user_struct *vuser; int snum,gid; - int ngroups; - gid_t *groups; + int id = uid; - if (last_user.cnum == cnum && last_user.uid == uid) { + if (current_user.cnum == cnum && current_user.id == id) { DEBUG(4,("Skipping become_user - already user\n")); return(True); } @@ -231,8 +225,9 @@ BOOL become_user(int cnum, int uid) !check_user_ok(cnum,vuser,snum)) { uid = Connections[cnum].uid; gid = Connections[cnum].gid; - groups = Connections[cnum].groups; - ngroups = Connections[cnum].ngroups; + current_user.groups = Connections[cnum].groups; + current_user.igroups = Connections[cnum].igroups; + current_user.ngroups = Connections[cnum].ngroups; } else { if (!vuser) { DEBUG(2,("Invalid vuid used %d\n",uid)); @@ -243,8 +238,9 @@ BOOL become_user(int cnum, int uid) gid = vuser->gid; else gid = Connections[cnum].gid; - groups = vuser->user_groups; - ngroups = vuser->user_ngroups; + current_user.groups = vuser->user_groups; + current_user.igroups = vuser->user_igroups; + current_user.ngroups = vuser->user_ngroups; } if (initial_uid == 0) @@ -254,8 +250,8 @@ BOOL become_user(int cnum, int uid) #ifndef NO_SETGROUPS if (!IS_IPC(cnum)) { /* groups stuff added by ih/wreu */ - if (ngroups > 0) - if (setgroups(ngroups,groups)<0) + if (current_user.ngroups > 0) + if (setgroups(current_user.ngroups,current_user.groups)<0) DEBUG(0,("setgroups call failed!\n")); } #endif @@ -267,8 +263,8 @@ BOOL become_user(int cnum, int uid) new_umask = 0777 & ~CREATE_MODE(cnum); old_umask = umask(new_umask); - last_user.cnum = cnum; - last_user.uid = uid; + current_user.cnum = cnum; + current_user.id = id; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n", getuid(),geteuid(),getgid(),getegid(),new_umask)); @@ -281,7 +277,7 @@ BOOL become_user(int cnum, int uid) ****************************************************************************/ BOOL unbecome_user(void ) { - if (last_user.cnum == -1) + if (current_user.cnum == -1) return(False); ChDir(OriginalDir); @@ -320,8 +316,8 @@ BOOL unbecome_user(void ) } #endif - current_uid = initial_uid; - current_gid = initial_gid; + current_user.uid = initial_uid; + current_user.gid = initial_gid; if (ChDir(OriginalDir) != 0) DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", @@ -330,7 +326,7 @@ BOOL unbecome_user(void ) DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); - last_user.cnum = -1; + current_user.cnum = -1; return(True); } @@ -352,7 +348,7 @@ int smbrun(char *cmd,char *outfile) } sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"", - path,current_uid,current_gid,cmd, + path,current_user.uid,current_user.gid,cmd, outfile?outfile:"/dev/null"); DEBUG(5,("smbrun - running %s ",syscmd)); -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/smbd/uid.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 625303350a..555cd457e7 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; -- cgit From e23f2b9cef8428bda51b413642d9720ba5c590d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 4 Oct 1996 09:31:07 +0000 Subject: - changed the umask handling. We now set the umask to 0 and explicitly set the mode on all created files. I think this is a better policy. - change the debug levels on some items - fix a charset handling bug which affected foreign and extended charset users - no longer switch back to the original directory when idle, instead switch to / as the original directory may not be readable by ordinary users. - fix some bugs where the create mode of files was not being explicitly set (it was relying on the umask and using fopen). Not a big bug as it only affected obscure commands like the messaging ops. - got rid of the lock code in the lpq cache as its no longer needed - rewrote smbrun to be faster and to remove the security hole. We now don't actually need a external smbrun binary, its all done by smbd. - add a more explicit warning about uids and gids of -1 or 65535 (This used to be commit 5aa735c940ccdb6acae5f28449d484181c912e49) --- source3/smbd/uid.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 128 insertions(+), 18 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 555cd457e7..7274c18478 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -27,9 +27,6 @@ extern connection_struct Connections[]; static int initial_uid; static int initial_gid; -static int old_umask = 022; - -static pstring OriginalDir; /* what user is current? */ struct current_user current_user; @@ -57,7 +54,7 @@ void init_uid(void) current_user.cnum = -1; - GetWd(OriginalDir); + ChDir(IDLE_DIR); } @@ -69,6 +66,10 @@ static BOOL become_uid(int uid) if (initial_uid != 0) return(True); + if (uid == -1 || uid == 65535) { + DEBUG(1,("WARNING: using uid %d is a security risk\n",uid)); + } + #ifdef AIX { /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */ @@ -118,6 +119,10 @@ static BOOL become_gid(int gid) { if (initial_uid != 0) return(True); + + if (gid == -1 || gid == 65535) { + DEBUG(1,("WARNING: using gid %d is a security risk\n",gid)); + } #ifdef USE_SETRES if (setresgid(-1,gid,-1) != 0) @@ -199,7 +204,6 @@ static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) ****************************************************************************/ BOOL become_user(int cnum, int uid) { - int new_umask; user_struct *vuser; int snum,gid; int id = uid; @@ -259,14 +263,11 @@ BOOL become_user(int cnum, int uid) return(False); } - new_umask = 0777 & ~CREATE_MODE(cnum); - old_umask = umask(new_umask); - current_user.cnum = cnum; current_user.id = id; - DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n", - getuid(),geteuid(),getgid(),getegid(),new_umask)); + DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", + getuid(),geteuid(),getgid(),getegid())); return(True); } @@ -279,9 +280,7 @@ BOOL unbecome_user(void ) if (current_user.cnum == -1) return(False); - ChDir(OriginalDir); - - umask(old_umask); + ChDir(IDLE_DIR); if (initial_uid == 0) { @@ -318,9 +317,9 @@ BOOL unbecome_user(void ) current_user.uid = initial_uid; current_user.gid = initial_gid; - if (ChDir(OriginalDir) != 0) + if (ChDir(IDLE_DIR) != 0) DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", - timestring(),OriginalDir)); + timestring(),IDLE_DIR)); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); @@ -332,14 +331,69 @@ BOOL unbecome_user(void ) /**************************************************************************** -run a command via system() using smbrun, being careful about uid/gid handling +This is a utility function of smbrun(). It must be called only from +the child as it may leave the caller in a privilaged state. ****************************************************************************/ -int smbrun(char *cmd,char *outfile) +static BOOL setup_stdout_file(char *outfile,BOOL shared) +{ + int fd; + mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH; + + close(1); + + if (shared) { + /* become root - unprivilaged users can't delete these files */ +#ifdef USE_SETRES + setresgid(0,0,0); + setresuid(0,0,0); +#else + setuid(0); + seteuid(0); +#endif + } + + /* now create the file with O_EXCL set */ + unlink(outfile); + fd = open(outfile,O_RDWR|O_CREAT|O_TRUNC|O_EXCL,mode); + + if (fd == -1) return False; + + if (fd != 1) { + if (dup2(fd,1) != 0) { + DEBUG(2,("Failed to create stdout file descriptor\n")); + close(fd); + return False; + } + close(fd); + } + return True; +} + + +/**************************************************************************** +run a command being careful about uid/gid handling and putting the output in +outfile (or discard it if outfile is NULL). + +if shared is True then ensure the file will be writeable by all users +but created such that its owned by root. This overcomes a security hole. + +if shared is not set then open the file with O_EXCL set +****************************************************************************/ +int smbrun(char *cmd,char *outfile,BOOL shared) { + int fd,pid; + int uid = current_user.uid; + int gid = current_user.gid; + +#if USE_SYSTEM int ret; pstring syscmd; char *path = lp_smbrun(); + /* in the old method we use system() to execute smbrun which then + executes the command (using system() again!). This involves lots + of shell launches and is very slow. It also suffers from a + potential security hole */ if (!file_exist(path,NULL)) { DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path)); @@ -347,13 +401,69 @@ int smbrun(char *cmd,char *outfile) } sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"", - path,current_user.uid,current_user.gid,cmd, + path,uid,gid,cmd, outfile?outfile:"/dev/null"); DEBUG(5,("smbrun - running %s ",syscmd)); ret = system(syscmd); DEBUG(5,("gave %d\n",ret)); return(ret); +#else + /* in this newer method we will exec /bin/sh with the correct + arguments, after first setting stdout to point at the file */ + + if ((pid=fork())) { + int status=0; + /* the parent just waits for the child to exit */ + if (waitpid(pid,&status,0) != pid) { + DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno))); + return -1; + } + return status; + } + + + /* we are in the child. we exec /bin/sh to do the work for us. we + don't directly exec the command we want because it may be a + pipeline or anything else the config file specifies */ + + /* point our stdout at the file we want output to go into */ + if (outfile && !setup_stdout_file(outfile,shared)) { + exit(80); + } + + /* now completely lose our privilages. This is a fairly paranoid + way of doing it, but it does work on all systems that I know of */ +#ifdef USE_SETRES + setresgid(0,0,0); + setresuid(0,0,0); + setresgid(gid,gid,gid); + setresuid(uid,uid,uid); +#else + setuid(0); + seteuid(0); + setgid(gid); + setegid(gid); + setuid(uid); + seteuid(uid); +#endif + + if (getuid() != uid || geteuid() != uid || + getgid() != gid || getegid() != gid) { + /* we failed to lose our privilages - do not execute the command */ + exit(81); /* we can't print stuff at this stage, instead use exit codes + for debugging */ + } + + /* close all other file descriptors, leaving only 0, 1 and 2. 0 and + 2 point to /dev/null from the startup code */ + for (fd=3;fd<256;fd++) close(fd); + + execl("/bin/sh","sh","-c",cmd,NULL); + + /* not reached */ + exit(82); +#endif } -- cgit From 38087ccb4071bfff29801026e2bf5c47565305b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Oct 1996 02:54:37 +0000 Subject: - use workgroup from smb.conf in smbclient - change debug level on clitar stuff - define MAP_FILE if not defined - ensure we never set authoritative on queries in nmbd - fake a positive response to SMBioctl, apparently this is needed for some WfWg printer drivers - deny file access for non-fcbopen queries when (access_allowed == AREAD && flags == O_RDWR) - add sys_waitpid() (This used to be commit 61e3116e573637d6b5a878eeb8db72831e3c5bd1) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7274c18478..9312a447a0 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -415,7 +415,7 @@ int smbrun(char *cmd,char *outfile,BOOL shared) if ((pid=fork())) { int status=0; /* the parent just waits for the child to exit */ - if (waitpid(pid,&status,0) != pid) { + if (sys_waitpid(pid,&status,0) != pid) { DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno))); return -1; } -- cgit From ec85f2e53d18a818440cf716ad6b6892594cae85 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 7 Oct 1996 15:04:48 +0000 Subject: - revert to old idle dir code (marty pointed out a problem with the new code) - handle server level security in the new "detect NT password length stuffups" code (This used to be commit 7c135d499409d4ddedb978f681559dae90ac4288) --- source3/smbd/uid.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9312a447a0..f7005b53cf 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -31,6 +31,8 @@ static int initial_gid; /* what user is current? */ struct current_user current_user; +extern pstring OriginalDir; + /**************************************************************************** initialise the uid routines ****************************************************************************/ @@ -54,7 +56,7 @@ void init_uid(void) current_user.cnum = -1; - ChDir(IDLE_DIR); + ChDir(OriginalDir); } @@ -280,7 +282,7 @@ BOOL unbecome_user(void ) if (current_user.cnum == -1) return(False); - ChDir(IDLE_DIR); + ChDir(OriginalDir); if (initial_uid == 0) { @@ -317,9 +319,9 @@ BOOL unbecome_user(void ) current_user.uid = initial_uid; current_user.gid = initial_gid; - if (ChDir(IDLE_DIR) != 0) + if (ChDir(OriginalDir) != 0) DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", - timestring(),IDLE_DIR)); + timestring(),OriginalDir)); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); -- cgit From 697e46373c8fa7b07234f6611c93cf25fe9733ed Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 25 Oct 1996 20:50:31 +0000 Subject: Changed become_user to take a vuid as second arg. Consistent with other changes to make smb_uid an index+offset into the validated_users table. jra@cygnus.com (This used to be commit 89675f8ae8f136fb587690b137f4413607d30c14) --- source3/smbd/uid.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f7005b53cf..4fa0ed89da 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -204,13 +204,13 @@ static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) /**************************************************************************** become the user of a connection number ****************************************************************************/ -BOOL become_user(int cnum, int uid) +BOOL become_user(int cnum, uint16 vuid) { - user_struct *vuser; + user_struct *vuser = get_valid_user_struct(vuid); int snum,gid; - int id = uid; + int uid; - if (current_user.cnum == cnum && current_user.id == id) { + if (current_user.cnum == cnum && vuser != 0 && current_user.id == vuser->uid) { DEBUG(4,("Skipping become_user - already user\n")); return(True); } @@ -226,7 +226,7 @@ BOOL become_user(int cnum, int uid) if (Connections[cnum].force_user || lp_security() == SEC_SHARE || - !(vuser = get_valid_user_struct(uid)) || + !(vuser) || (vuser->guest) || !check_user_ok(cnum,vuser,snum)) { uid = Connections[cnum].uid; gid = Connections[cnum].gid; @@ -235,7 +235,7 @@ BOOL become_user(int cnum, int uid) current_user.ngroups = Connections[cnum].ngroups; } else { if (!vuser) { - DEBUG(2,("Invalid vuid used %d\n",uid)); + DEBUG(2,("Invalid vuid used %d\n",vuid)); return(False); } uid = vuser->uid; @@ -266,7 +266,7 @@ BOOL become_user(int cnum, int uid) } current_user.cnum = cnum; - current_user.id = id; + current_user.id = uid; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4fa0ed89da..e2c5f590b7 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. uid/user handling - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 3ab97ebe6db1a5a4a0573c7c8482c94876bbce9a Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 30 May 1997 20:40:48 +0000 Subject: charcnv.c: Fixed silly bugs detected on IRIX. client.c: Fixed silly bugs detected on IRIX. namedbname.c: Stopped 1d names from being registered in WINS db. namedbsubnet.c: Only register 1e names on broadcast subnet. nameelect.c: Changed add_my_name entries. Forced host announces if we have less than 10 servers listed. Fixed registering 1b domain name issues. namepacket.c: Added error message when dgram discarded. nameserv.c: Added notion of 'direct' names that are not registered on the network. Needed to get around bugs in earlier nmbd handling of DOMAIN(1b) names. nameservreply.c:Tidied up debug message. nameservresp.c: Added response_name_query_domain() code. Deals with re-registering DOMAIN(1b) name. nmbd.c: Fixed silly bugs detected on IRIX. nmblib.c: Added paranoia debugs. proto.h: Updated remove_name_entry(), add_my_name_entry(). server.c: Fixed silly bugs detected on IRIX. trans2.c: Fixed silly bugs detected on IRIX. uid.c: Fixed silly bugs detected on IRIX. version.h: Updated to alpha3. Jeremy (jallison@whistle.com). (This used to be commit f08222bd8b86a061c52d22015f946a4737eb47fd) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e2c5f590b7..7a903e0551 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -466,6 +466,5 @@ int smbrun(char *cmd,char *outfile,BOOL shared) /* not reached */ exit(82); #endif + return 1; } - - -- cgit From 9e37076f2b8514a010008db44def4355e52379c2 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 27 Jun 1997 00:26:59 +0000 Subject: shmem.c: Changed debug to higher level uid.c: Stop smbrun from deleting device files. util.c: Added EAGAIN to known error list. Jeremy (jallison@whistle.com) (This used to be commit c07db8d8e7e4a421501a08efe999e9ccd7337855) --- source3/smbd/uid.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7a903e0551..0cf1c217a9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -339,7 +339,9 @@ the child as it may leave the caller in a privilaged state. static BOOL setup_stdout_file(char *outfile,BOOL shared) { int fd; + struct stat st; mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH; + int flags = O_RDWR|O_CREAT|O_TRUNC|O_EXCL; close(1); @@ -354,9 +356,15 @@ static BOOL setup_stdout_file(char *outfile,BOOL shared) #endif } - /* now create the file with O_EXCL set */ - unlink(outfile); - fd = open(outfile,O_RDWR|O_CREAT|O_TRUNC|O_EXCL,mode); + if(stat(outfile, &st) == 0) { + /* Check we're not deleting a device file. */ + if(st.st_mode & S_IFREG) + unlink(outfile); + else + flags = O_RDWR; + } + /* now create the file */ + fd = open(outfile,flags,mode); if (fd == -1) return False; -- cgit From 612111c7a1a048d19e24b5e2e4d426247d320d1e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 18 Jul 1997 20:21:32 +0000 Subject: charset.c: Split charset_initialise() into 2 - a charset_initialise() and a codepage_initialise(). Fixes problem with initialising dos map twice. charset.h: Changes to support charset changes. client.c: Changes to support charset changes. loadparm.c: follow symlinks parameter from David Clerc nmbd.c: Changes to support charset changes. nmblookup.c:Changes to support charset changes. proto.h: Changes to support charset changes. reply.c: Don't call security=server with no user/no password guest. Fix from Stefaan A Eeckels server.c: follow symlinks code from David Clerc smbpasswd.c:Changes to support charset changes. status.c: Changes to support charset changes. testparm.c: Changes to support charset changes. testprns.c: Changes to support charset changes. uid.c: Fixed log message with no \n. Jeremy (jallison@whistle.com) (This used to be commit 2a28a6e5e461aca7fe6c19cd01d287010056cffb) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 0cf1c217a9..cdc4e474c6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -83,7 +83,7 @@ static BOOL become_uid(int uid) &priv, sizeof(priv_t)) < 0 || setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 || seteuid((uid_t)uid) < 0) - DEBUG(1,("Can't set uid (AIX3)")); + DEBUG(1,("Can't set uid (AIX3)\n")); } #endif -- cgit From ea4c7557dd7048ba7a266d28de9e43fe0e282a52 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sun, 17 Aug 1997 21:03:12 +0000 Subject: connecting to IPC$ goes under the guest account. the IPC$ share should be treated no differently than any other share (for any security setting: user, server or share). this will clear up a bug where, when clients connect to the IPC$ share, this used to be done under the guest account. the standard_sub_basic() macros will substitute the _guest_ account for %U, causing the samba server to look different from when the client then connects to any other share. lkcl (This used to be commit 38526569608f6eb5f098efee7013037873d140bf) --- source3/smbd/uid.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index cdc4e474c6..4ffdb0923e 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -253,12 +253,10 @@ BOOL become_user(int cnum, uint16 vuid) if (!become_gid(gid)) return(False); #ifndef NO_SETGROUPS - if (!IS_IPC(cnum)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) DEBUG(0,("setgroups call failed!\n")); - } #endif if (!Connections[cnum].admin_user && !become_uid(uid)) -- cgit From e9269c67a59ffa741123cb2ce3ab8dfb97136dec Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 19 Aug 1997 19:22:26 +0000 Subject: Makefile: Changed for HPUX10 tidyup. includes.h: Changed for HPUX10 tidyup. ipc.c: Fixed bug where getting local server list from NT browsers would fail. nmbsync.c: Fixed bug where getting local server list from NT browsers would fail. proto.h: Changed for crash bug on SCO with USE_MMAP. quotas.c: Added OSF quotas (patch from Bret Giddings ). Rolled back solaris uid change - I think it was wrong. reply.c: Changed for crash bug on SCO with USE_MMAP. server.c: Removed Lukes changes. Changed for crash bug on SCO with USE_MMAP. smb.h: Changed for crash bug on SCO with USE_MMAP. smbpasswd.c:Fixed crash bug with Lukes changes. uid.c: Removed Lukes changes. util.c: Fixed I18N bug with extended char filenames and widelinks = no. Jeremy (jallison@whistle.com) (This used to be commit bf1c79f7fd7f9beec4f9f4e58337cadceeb1cb38) --- source3/smbd/uid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4ffdb0923e..cdc4e474c6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -253,10 +253,12 @@ BOOL become_user(int cnum, uint16 vuid) if (!become_gid(gid)) return(False); #ifndef NO_SETGROUPS + if (!IS_IPC(cnum)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) DEBUG(0,("setgroups call failed!\n")); + } #endif if (!Connections[cnum].admin_user && !become_uid(uid)) -- cgit From c5e739febe5ab3bcc5d147fe791c788ec72531a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 14:48:05 +0000 Subject: Makefile: added credentials.c to smbd credentials.c: using credential structures instead of char* password.c uid.c server.c: added sid and attr to user_struct. smbdes.c: smbhash and str_to_key make public instead of private. pipes.c smb.h: lsa structures, sub-functions. proto.h: usual. (This used to be commit 87a0a944855a673d693d934e446bdc231b1c7f02) --- source3/smbd/uid.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index cdc4e474c6..78614a5b5c 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -227,13 +227,17 @@ BOOL become_user(int cnum, uint16 vuid) if (Connections[cnum].force_user || lp_security() == SEC_SHARE || !(vuser) || (vuser->guest) || - !check_user_ok(cnum,vuser,snum)) { + !check_user_ok(cnum,vuser,snum)) + { uid = Connections[cnum].uid; gid = Connections[cnum].gid; current_user.groups = Connections[cnum].groups; current_user.igroups = Connections[cnum].igroups; current_user.ngroups = Connections[cnum].ngroups; - } else { + current_user.attrs = vuser->attrs; + } + else + { if (!vuser) { DEBUG(2,("Invalid vuid used %d\n",vuid)); return(False); @@ -243,9 +247,10 @@ BOOL become_user(int cnum, uint16 vuid) gid = vuser->gid; else gid = Connections[cnum].gid; - current_user.groups = vuser->user_groups; - current_user.igroups = vuser->user_igroups; - current_user.ngroups = vuser->user_ngroups; + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + current_user.igroups = vuser->igroups; + current_user.attrs = vuser->attrs; } if (initial_uid == 0) -- cgit From 359d42c08d012b3e1c1bc6ac1071f8add706ba35 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Oct 1997 21:53:59 +0000 Subject: ipc.c: Adding Andrews become_root code to the main branch. locking.c: Adding Andrews become_root code to the main branch. pipes.c: Fixing the close_file issue. proto.h: The usual. reply.c: Move smb_pass into NTDOMAIN defined code. Fixing the close_file issue. server.c: Fixing the close_file issue. trans2.c: Fixing the close_file issue. uid.c: Adding Andrews become_root code to the main branch. Jeremy (jallison@whistle.com) (This used to be commit 16fd4337f79ce33f91050c96c4a566221c5d9126) --- source3/smbd/uid.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 78614a5b5c..42ade7e4da 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -481,3 +481,77 @@ 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(BOOL 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(BOOL 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 0aa3935917e325afcb72fdab7a95e99bcfb074cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Oct 1997 11:54:57 +0000 Subject: fix the order of become_uid() and become_gid() in become_root(). This was a harmless bug but left log entries code cleanup in reply_lanman2() (This used to be commit 8e90e1ef276c4cc362e32985c2845fc4c5108273) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 42ade7e4da..28bf4b421a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -505,8 +505,8 @@ void become_root(BOOL save_dir) current_user_saved = current_user; become_root_depth = 1; - become_gid(0); become_uid(0); + become_gid(0); } /**************************************************************************** -- cgit From 390c1f3c4d3136b454fa5eb8681fa9ca34eaacc2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 25 Oct 1997 10:58:18 +0000 Subject: Makefile : adding bits for new nt domain code byteorder.h : trying to get macros right, and not to crash on SUNOS5... client.c : added #ifdef NTDOMAIN, and created do_nt_login() function. don't want to have to recompile client.c unless absolutely necessary. credentials.c : moved deal_with_creds() [possibly inappropriately] into credentials.c ipc.c reply.c server.c uid.c : attempting to make (un)become_root() functions calleable from smbclient. this is a little tricky: smbclient might have to be another setuid root program, immediately setuid'ing to non-root, so that we can reset-uid to root to get at the smbpasswd file. or, have a secure pipe mechanism to smbd to grab smbpasswd entries. or the like. smbdes.c smbencrypt.c : created a function to generate lm and nt owf hashes. lsaparse.c ntclient.c smbparse.c : added nt client LSA_AUTH2 code. it works, too! pipenetlog.c pipentlsa.c pipesrvsvc.c : simplification. code-shuffling. getting that damn offset right for the opcode in RPC_HDR. smb.h : changed dcinfo xxx_creds to DOM_CRED structures instead of DOM_CHAL. we might need to store the server times as well. proto.h : the usual. (This used to be commit 82436a3d99d4bdce249ce9ff27fd2ca4b2447e07) --- source3/smbd/uid.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 28bf4b421a..645d078979 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -23,15 +23,13 @@ extern int DEBUGLEVEL; -extern connection_struct Connections[]; - static int initial_uid; static int initial_gid; /* what user is current? */ struct current_user current_user; -extern pstring OriginalDir; +pstring OriginalDir; /**************************************************************************** initialise the uid routines @@ -183,19 +181,19 @@ BOOL become_guest(void) /******************************************************************* check if a username is OK ********************************************************************/ -static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) +static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;iuid) return(True); + for (i=0;iuid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) return(True); if (!user_ok(vuser->name,snum)) return(False); - i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE; - Connections[cnum].uid_cache.list[i] = vuser->uid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE) - Connections[cnum].uid_cache.entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; return(True); } @@ -204,7 +202,7 @@ static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) /**************************************************************************** become the user of a connection number ****************************************************************************/ -BOOL become_user(int cnum, uint16 vuid) +BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum,gid; @@ -217,23 +215,23 @@ BOOL become_user(int cnum, uint16 vuid) unbecome_user(); - if (!OPEN_CNUM(cnum)) { + if (!(VALID_CNUM(cnum) && conn->open)) { DEBUG(2,("Connection %d not open\n",cnum)); return(False); } - snum = Connections[cnum].service; + snum = conn->service; - if (Connections[cnum].force_user || + if (conn->force_user || lp_security() == SEC_SHARE || !(vuser) || (vuser->guest) || - !check_user_ok(cnum,vuser,snum)) + !check_user_ok(conn, vuser, snum)) { - uid = Connections[cnum].uid; - gid = Connections[cnum].gid; - current_user.groups = Connections[cnum].groups; - current_user.igroups = Connections[cnum].igroups; - current_user.ngroups = Connections[cnum].ngroups; + uid = conn->uid; + gid = conn->gid; + current_user.groups = conn->groups; + current_user.igroups = conn->igroups; + current_user.ngroups = conn->ngroups; current_user.attrs = vuser->attrs; } else @@ -246,7 +244,7 @@ BOOL become_user(int cnum, uint16 vuid) if(!*lp_force_group(snum)) gid = vuser->gid; else - gid = Connections[cnum].gid; + gid = conn->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; current_user.igroups = vuser->igroups; @@ -258,7 +256,7 @@ BOOL become_user(int cnum, uint16 vuid) if (!become_gid(gid)) return(False); #ifndef NO_SETGROUPS - if (!IS_IPC(cnum)) { + if (!(VALID_CNUM(cnum) && conn->ipc)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) @@ -266,7 +264,7 @@ BOOL become_user(int cnum, uint16 vuid) } #endif - if (!Connections[cnum].admin_user && !become_uid(uid)) + if (!conn->admin_user && !become_uid(uid)) return(False); } -- cgit From 36e5b646d9d6f40b44a9c851c5f8caa499eb2237 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Nov 1997 23:34:51 +0000 Subject: ipc.c: Changing back arbitrary alignment change until I know *why* luke changed it. proto.h: The usual. uid.c: Fix crash bug when attaching with smbclient -mCORE. A vuid pointer was being used when it was null. Jeremy. (This used to be commit ff94f97cf2b0f62cbbddbfd3d126df7f4d649334) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 645d078979..b36fa4df06 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -232,7 +232,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) current_user.groups = conn->groups; current_user.igroups = conn->igroups; current_user.ngroups = conn->ngroups; - current_user.attrs = vuser->attrs; + current_user.attrs = conn->attrs; } else { -- cgit From d4979e7727ef94de469e66b74a9bee6f9742d4c0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 23 Dec 1997 11:30:58 +0000 Subject: Fixed security bug when 'force user' and 'user only' are set. Reported by Brian McCauley . Jeremy. (This used to be commit 00067800a25d6f5fe11e833a01d5a7a1e76dcc11) --- source3/smbd/uid.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b36fa4df06..46a2de4f17 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -222,10 +222,13 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) snum = conn->service; + if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) + return False; + if (conn->force_user || lp_security() == SEC_SHARE || - !(vuser) || (vuser->guest) || - !check_user_ok(conn, vuser, snum)) + !(vuser) || (vuser->guest) + ) { uid = conn->uid; gid = conn->gid; -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 46a2de4f17..176f6ca240 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. uid/user handling - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 99e11e171e40703271ad2a7934708cee66b0bb82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Feb 1998 11:07:14 +0000 Subject: Makefile: Added AIX 3.2.5. loadparm.c: Added "win95 bug compatibility" parameter. local.h: Replaced MAX_OPEN_FILES back to 100 from 10 (oops). reply.c: Fixed ulogoff check against uid - changed to vuid. server.c: Changed file struct save of uid - changed to vuid. smb.h: Changed id in struct current_user to vuid. Changed file struct uid to vuid. time.c: Added "win95 bug compatibility" atime -> mtime return. trans2.c: Added "win95 bug compatibility" fixes. uid.c: Changed id in struct current_user to vuid - added checks to set/reset it. util.c: Added code to expand environment variables. version.h : still at 1.9.18 (head branch doesn't matter too much at present). Jeremy. (This used to be commit adc903bcf59ad1664babd7f1d43675d3a75bfbc9) --- source3/smbd/uid.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 176f6ca240..14b0000f59 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -53,6 +53,7 @@ void init_uid(void) initial_gid = getegid(); current_user.cnum = -1; + current_user.vuid = UID_FIELD_INVALID; ChDir(OriginalDir); } @@ -174,6 +175,7 @@ BOOL become_guest(void) DEBUG(1,("Failed to become guest. Invalid guest account?\n")); current_user.cnum = -2; + current_user.vuid = UID_FIELD_INVALID; return(ret); } @@ -208,7 +210,8 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) int snum,gid; int uid; - if (current_user.cnum == cnum && vuser != 0 && current_user.id == vuser->uid) { + if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == vuid) && + (current_user.uid == vuser->uid)) { DEBUG(4,("Skipping become_user - already user\n")); return(True); } @@ -272,7 +275,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) } current_user.cnum = cnum; - current_user.id = uid; + current_user.vuid = vuid; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); @@ -333,6 +336,7 @@ BOOL unbecome_user(void ) getuid(),geteuid(),getgid(),getegid())); current_user.cnum = -1; + current_user.vuid = UID_FIELD_INVALID; return(True); } -- cgit From a2bddb20ed078c3e1b9cb60a7420b3d107898f52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 May 1998 01:34:51 +0000 Subject: Fixes for the %U and %G problems people have reported. Essentially, multiple session_setup_and_X's may be done to an smbd. As there is only one global variable containing the requested connection name (sessionsetup_user), then any subsequent sessionsetups overwrite this name (causing %U and %G to get the wrong name). This is particularly common when an NT client does a null session setup to get a browse list after the user has connected, but before a share has been mounted. These changes store the requested_name in the vuid structure (so this only really works for user level and above security) and copies this name back into the global variable before the standard_sub call. Jeremy. (This used to be commit b5187ad6a3b3af9fbbeee8bced0ab16b41e9825b) --- source3/smbd/uid.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 14b0000f59..c01fa1b052 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -28,6 +28,7 @@ static int initial_gid; /* what user is current? */ struct current_user current_user; +extern pstring sesssetup_user; pstring OriginalDir; @@ -276,7 +277,12 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) current_user.cnum = cnum; current_user.vuid = vuid; - + + /* Ensure sesssetup_user is set correctly if we are using + user security. */ + if(vuser != NULL) + pstrcpy( sesssetup_user, vuser->requested_name); + DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); -- cgit From 01df1ed95f880a671ead7bc92b3bcff01a2e2dc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 May 1998 19:04:14 +0000 Subject: This should (hopefully :-) be the final fix for the %U %G substitution problem.... smbpass.c: Removed Luke's dire warning - as some of the functions in here *need* to be called externally :-). Jeremy. (This used to be commit 1fd8d12ca414066acec71b33eb8a13e16c2acd3a) --- source3/smbd/uid.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c01fa1b052..a8e340e46f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -28,7 +28,6 @@ static int initial_gid; /* what user is current? */ struct current_user current_user; -extern pstring sesssetup_user; pstring OriginalDir; @@ -278,11 +277,6 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) current_user.cnum = cnum; current_user.vuid = vuid; - /* Ensure sesssetup_user is set correctly if we are using - user security. */ - if(vuser != NULL) - pstrcpy( sesssetup_user, vuser->requested_name); - DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index a8e340e46f..749248ac86 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -420,7 +420,7 @@ int smbrun(char *cmd,char *outfile,BOOL shared) return(1); } - sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"", + slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"", path,uid,gid,cmd, outfile?outfile:"/dev/null"); -- cgit From ddb7b8a3d6cb03a36ab23816b76c7b0c16c0ab37 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jul 1998 01:13:16 +0000 Subject: AIX patch from Michael Wojcik adding detail to the AIX specific (and undocumented) setpriv and setuidx calls. Jeremy. (This used to be commit 7a8d0a4ed4e07090bfe776b5544712274d2426e4) --- source3/smbd/uid.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 749248ac86..358de86875 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -74,15 +74,124 @@ static BOOL become_uid(int uid) #ifdef AIX { /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */ + /* MWW: This is all undocumented, of course. There's a patch to WU-ftpd + in the AIX FAQ which does the setpriv, then sets the gid stuff, then + sets uid. Since Samba separates setting the gid and setting the uid, + I've duplicated the setpriv code in become_gid. I've also made the + requisite changes to become_gid to match the WU-ftpd patch. + + I believe we'll still get errors in the Samba logs. This setpriv + call is supposed to disable "trapdooring" on AIX - ie. normally + once a seteuid / setegid is done, the effective ID can't be set back + to what it was before. See the comments in become_root / unbecome_root. + I *think* that we may have to do something additional here to prevent + the "Can't set uid (AIX3)" messages, though - possibly change the + values of priv.pv_priv to keep the SET_PROC_DAC privilege, and + possibly SET_OBJ_DAC and SET_OBJ_STAT as well. + + The pv_priv array is two longwords, and the constants in sys/priv.h + have values between 1 and 64, according to the comments in priv.h. + This strongly suggests a bit vector - but does BYPASS_DAC_WRITE + (#define'd to 1) mean 1<<0 or 1<<1? Unfortunately, nothing's + defined to 0 or 64, which would be a dead giveaway. Also, what's the + fullword-boundary endianness? That is, is pv_priv[0] the high or + the low 32 bits? Fortunately, the values used by "su" (see below) + don't make much sense if pv_priv[0] is the high bits. Also, based + on analysis of the values used by su, I concluded that, for example, + BYPASS_DAC_READ (defined to 2) is bit "2" counting from 1 - ie. + if (pv_priv[0] & (1 << (BYPASS_DAC_READ - 1))) then BYPASS_DAC_READ + is on. That's a bit odd, but it makes more sense than if the + privilege constants are meant to be taken as exponents of 2. + + For analysis, I ran "su" as root under dbx, and stopped in setpriv. + The first argument to setpriv can be examined using + + print $r3 (eg. "0x30009" = PRIV_SET|PRIV_MAXIMUM|PRIV_EFFECTIV) + + the contents of the pv_priv array can be examined using + + ($r4)/2X + + Here's what su does: + + setpriv(PRIV_SET | PRIV_INHERITED | PRIV_BEQUEATH, {0,0}) + setpriv(PRIV_SET | PRIV_EFFECTIVE | PRIV_MAXIMUM, + {0x02800006, 0x00040000}) + 0x02800006 = SET_PROC_AUDIT | SET_PROC_ENV | + BYPASS_DAC_EXEC | BYPASS_DAC_READ + 0x00040000 = TPATH_CONFIG + setpriv(PRIV_SET | PRIV_EFFECTIVE, {0, 0}) + + Analysis: + + Reduce inherited privileges to none, so the child doesn't inherit + anything special. + Change su's privileges so it can execute the shell even if someone + has goofed up the permissions to it or to directories on the + search path; so it can set the process auditing characteristics + and privileged environment (stuff in /etc/security/environ with + the sysenv attribute); and so that it can set the trusted path + characteristics for this login. + Zap those privileges back off when we don't need them any more. + + I'm guessing we want to keep SET_PROC_DAC in the current priv set, + but not in the inherited one. That is, set PRIV_INHERITED and + PRIV_BEQUEATH to 0. We also probably want to set PRIV_MAXIMUM and + PRIV_EFFECTIVE to only the privs we need, which at this point would + appear to be just SET_PROC_DAC. *Note*: setting PRIV_MAXIMUM + with any of the privilege sets higher than what you're trying to + set the maximum to will produce an EINVAL. For example, if we + try to set PRIV_MAXIMUM to SET_PROC_DAC *before* we reduce + PRIV_INHERITED and PRIV_BEQUEATH, it won't work. Zero out the + inherited privileges first. + + Some experimentation with simple programs confirms that if we're + running with an EUID of 0 we can switch our UID/EUID back and + forth with setuidx - *unless* we call setpriv({0,0}, ...) first. + In other words, by default root has SET_PROC_DAT set, but we can + remove it from our privilege set. This is what we want to do for + child processes, I believe. + + Also, calling setpriv(PRIV_SUB|PRIV_EFFECTIVE,...) with pv_priv[0] + set to SET_PROC_DAC (1 << (SET_PROC_DAC - 1)) will prevent an + EUID-root process from switching its EUID back with setuidx. + + In other words, setuidx on AIX is *not* trapdoor. setuid is + trapdoor. We need a non-trapdoor setuid function, but we don't + want processes we fork to have access to it. Thus we use setuidx + but first we disable it for our children. + + Note, however, that we can only increase our privileges (as we + do in the first call to setpriv) if we're EUID-root. If we + started out as root, and then switched to a non-root user ID, + that's OK; we've already set them. Just don't try to set them + again. + + Also, I suspect that after using setpriv / setuidx / etc. here in + the AIX-specific code we DON'T want to fall through to the code that + calls setuid, etc. However, I haven't noticed any more problems with + the code the way it is here. + */ + priv_t priv; priv.pv_priv[0] = 0; priv.pv_priv[1] = 0; - if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH, - &priv, sizeof(priv_t)) < 0 || - setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 || - seteuid((uid_t)uid) < 0) + if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_BEQUEATH, + &priv, sizeof(priv_t)) < 0) { + DEBUG(1, ("Can't set child privileges (AIX3): %s\n", strerror(errno))); + } + + priv.pv_priv[0] = (1 << (SET_PROC_DAC - 1)); + if (setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_MAXIMUM, + &priv, sizeof(priv_t)) < 0) { + DEBUG(1, ("Can't set own privileges (AIX3): %s\n", strerror(errno))); + } + + if (setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 || + seteuid((uid_t)uid) < 0) { DEBUG(1,("Can't set uid (AIX3)\n")); + } } #endif @@ -125,6 +234,24 @@ static BOOL become_gid(int gid) DEBUG(1,("WARNING: using gid %d is a security risk\n",gid)); } +#ifdef AIX + { + /* MWW: See comment above in become_uid. */ + priv_t priv; + + priv.pv_priv[0] = 0; + priv.pv_priv[1] = 0; + if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH, + &priv, sizeof(priv_t)) < 0) { + DEBUG(1, ("Can't set privilege (AIX3)\n")); + } + if (setgidx(ID_REAL|ID_EFFECTIVE, (gid_t)gid) < 0 || + setegid((gid_t)gid) < 0) { + DEBUG(1,("Can't set gid (AIX3)\n")); + } + } +#endif + #ifdef USE_SETRES if (setresgid(-1,gid,-1) != 0) #elif defined(USE_SETFS) @@ -169,6 +296,10 @@ BOOL become_guest(void) 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); +#endif ret = become_id(pass->pw_uid,pass->pw_gid); if (!ret) -- cgit From 1aa138922e5c0e4925ff5cbfcdb4e7cad367b31b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Jul 1998 18:50:45 +0000 Subject: chgpasswd.c: Fixed up debug calls to stop crashes if ptsname failed. local.h: Kept FSTYPE_STRING as Samba for now. nmbd_browsesync.c: Added bugfix from Matt Chapman mattyc@cyberdude.com - lmb_browserlist is now a struct ubi_dlList not a struct browse_cache_record *. server.c: smb.h: uid.c: password.c: Removed attrs code - it is not used anywhere. Jeremy (This used to be commit ef1af7fe6d5c58ae57b8e4efff0729e1a315da43) --- source3/smbd/uid.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 358de86875..2a75b660b5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -369,7 +369,6 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) current_user.groups = conn->groups; current_user.igroups = conn->igroups; current_user.ngroups = conn->ngroups; - current_user.attrs = conn->attrs; } else { @@ -385,7 +384,6 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; current_user.igroups = vuser->igroups; - current_user.attrs = vuser->attrs; } if (initial_uid == 0) -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/smbd/uid.c | 279 ++++++++++++++--------------------------------------- 1 file changed, 75 insertions(+), 204 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2a75b660b5..a8e0bf0d03 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -36,26 +36,25 @@ initialise the uid routines ****************************************************************************/ void init_uid(void) { - initial_uid = current_user.uid = geteuid(); - initial_gid = current_user.gid = getegid(); + initial_uid = current_user.uid = geteuid(); + initial_gid = current_user.gid = getegid(); - if (initial_gid != 0 && initial_uid == 0) - { -#ifdef HPUX - setresgid(0,0,0); + if (initial_gid != 0 && initial_uid == 0) { +#ifdef HAVE_SETRESUID + setresgid(0,0,0); #else - setgid(0); - setegid(0); + setgid(0); + setegid(0); #endif - } - - initial_uid = geteuid(); - initial_gid = getegid(); + } - current_user.cnum = -1; - current_user.vuid = UID_FIELD_INVALID; + initial_uid = geteuid(); + initial_gid = getegid(); - ChDir(OriginalDir); + current_user.cnum = -1; + current_user.vuid = UID_FIELD_INVALID; + + ChDir(OriginalDir); } @@ -64,141 +63,33 @@ void init_uid(void) ****************************************************************************/ static BOOL become_uid(int uid) { - if (initial_uid != 0) - return(True); - - if (uid == -1 || uid == 65535) { - DEBUG(1,("WARNING: using uid %d is a security risk\n",uid)); - } - -#ifdef AIX - { - /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */ - /* MWW: This is all undocumented, of course. There's a patch to WU-ftpd - in the AIX FAQ which does the setpriv, then sets the gid stuff, then - sets uid. Since Samba separates setting the gid and setting the uid, - I've duplicated the setpriv code in become_gid. I've also made the - requisite changes to become_gid to match the WU-ftpd patch. - - I believe we'll still get errors in the Samba logs. This setpriv - call is supposed to disable "trapdooring" on AIX - ie. normally - once a seteuid / setegid is done, the effective ID can't be set back - to what it was before. See the comments in become_root / unbecome_root. - I *think* that we may have to do something additional here to prevent - the "Can't set uid (AIX3)" messages, though - possibly change the - values of priv.pv_priv to keep the SET_PROC_DAC privilege, and - possibly SET_OBJ_DAC and SET_OBJ_STAT as well. - - The pv_priv array is two longwords, and the constants in sys/priv.h - have values between 1 and 64, according to the comments in priv.h. - This strongly suggests a bit vector - but does BYPASS_DAC_WRITE - (#define'd to 1) mean 1<<0 or 1<<1? Unfortunately, nothing's - defined to 0 or 64, which would be a dead giveaway. Also, what's the - fullword-boundary endianness? That is, is pv_priv[0] the high or - the low 32 bits? Fortunately, the values used by "su" (see below) - don't make much sense if pv_priv[0] is the high bits. Also, based - on analysis of the values used by su, I concluded that, for example, - BYPASS_DAC_READ (defined to 2) is bit "2" counting from 1 - ie. - if (pv_priv[0] & (1 << (BYPASS_DAC_READ - 1))) then BYPASS_DAC_READ - is on. That's a bit odd, but it makes more sense than if the - privilege constants are meant to be taken as exponents of 2. - - For analysis, I ran "su" as root under dbx, and stopped in setpriv. - The first argument to setpriv can be examined using - - print $r3 (eg. "0x30009" = PRIV_SET|PRIV_MAXIMUM|PRIV_EFFECTIV) - - the contents of the pv_priv array can be examined using - - ($r4)/2X - - Here's what su does: - - setpriv(PRIV_SET | PRIV_INHERITED | PRIV_BEQUEATH, {0,0}) - setpriv(PRIV_SET | PRIV_EFFECTIVE | PRIV_MAXIMUM, - {0x02800006, 0x00040000}) - 0x02800006 = SET_PROC_AUDIT | SET_PROC_ENV | - BYPASS_DAC_EXEC | BYPASS_DAC_READ - 0x00040000 = TPATH_CONFIG - setpriv(PRIV_SET | PRIV_EFFECTIVE, {0, 0}) - - Analysis: - - Reduce inherited privileges to none, so the child doesn't inherit - anything special. - Change su's privileges so it can execute the shell even if someone - has goofed up the permissions to it or to directories on the - search path; so it can set the process auditing characteristics - and privileged environment (stuff in /etc/security/environ with - the sysenv attribute); and so that it can set the trusted path - characteristics for this login. - Zap those privileges back off when we don't need them any more. - - I'm guessing we want to keep SET_PROC_DAC in the current priv set, - but not in the inherited one. That is, set PRIV_INHERITED and - PRIV_BEQUEATH to 0. We also probably want to set PRIV_MAXIMUM and - PRIV_EFFECTIVE to only the privs we need, which at this point would - appear to be just SET_PROC_DAC. *Note*: setting PRIV_MAXIMUM - with any of the privilege sets higher than what you're trying to - set the maximum to will produce an EINVAL. For example, if we - try to set PRIV_MAXIMUM to SET_PROC_DAC *before* we reduce - PRIV_INHERITED and PRIV_BEQUEATH, it won't work. Zero out the - inherited privileges first. - - Some experimentation with simple programs confirms that if we're - running with an EUID of 0 we can switch our UID/EUID back and - forth with setuidx - *unless* we call setpriv({0,0}, ...) first. - In other words, by default root has SET_PROC_DAT set, but we can - remove it from our privilege set. This is what we want to do for - child processes, I believe. - - Also, calling setpriv(PRIV_SUB|PRIV_EFFECTIVE,...) with pv_priv[0] - set to SET_PROC_DAC (1 << (SET_PROC_DAC - 1)) will prevent an - EUID-root process from switching its EUID back with setuidx. - - In other words, setuidx on AIX is *not* trapdoor. setuid is - trapdoor. We need a non-trapdoor setuid function, but we don't - want processes we fork to have access to it. Thus we use setuidx - but first we disable it for our children. - - Note, however, that we can only increase our privileges (as we - do in the first call to setpriv) if we're EUID-root. If we - started out as root, and then switched to a non-root user ID, - that's OK; we've already set them. Just don't try to set them - again. - - Also, I suspect that after using setpriv / setuidx / etc. here in - the AIX-specific code we DON'T want to fall through to the code that - calls setuid, etc. However, I haven't noticed any more problems with - the code the way it is here. - */ - - priv_t priv; - - priv.pv_priv[0] = 0; - priv.pv_priv[1] = 0; - if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_BEQUEATH, - &priv, sizeof(priv_t)) < 0) { - DEBUG(1, ("Can't set child privileges (AIX3): %s\n", strerror(errno))); - } - - priv.pv_priv[0] = (1 << (SET_PROC_DAC - 1)); - if (setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_MAXIMUM, - &priv, sizeof(priv_t)) < 0) { - DEBUG(1, ("Can't set own privileges (AIX3): %s\n", strerror(errno))); - } + if (initial_uid != 0) { + return(True); + } + + if (uid == -1 || uid == 65535) { + static int done; + if (!done) { + DEBUG(1,("WARNING: using uid %d is a security risk\n", + uid)); + done=1; + } + } - if (setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 || - seteuid((uid_t)uid) < 0) { - DEBUG(1,("Can't set uid (AIX3)\n")); - } - } +#ifdef HAVE_TRAPDOOR_UID +#ifdef HAVE_SETUIDX + /* AIX3 has setuidx which is NOT a trapoor function (tridge) */ + if (setuidx(ID_EFFECTIVE, (uid_t)uid) != 0) { + if (seteuid((uid_t)uid) != 0) { + DEBUG(1,("Can't set uid (setuidx)\n")); + return False; + } + } +#endif #endif -#ifdef USE_SETRES - if (setresuid(-1,uid,-1) != 0) -#elif defined(USE_SETFS) - if (setfsuid(uid) != 0) +#ifdef HAVE_SETRESUID + if (setresuid(-1,uid,-1) != 0) #else if ((seteuid(uid) != 0) && (setuid(uid) != 0)) @@ -206,19 +97,20 @@ static BOOL become_uid(int uid) { DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n", uid,getuid(), geteuid())); - if (uid > 32000) - DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); + if (uid > 32000) { + DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); + } return(False); } - if (((uid == -1) || (uid == 65535)) && geteuid() != uid) { - DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n")); - return(False); - } + if (((uid == -1) || (uid == 65535)) && geteuid() != uid) { + DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n")); + return(False); + } - current_user.uid = uid; + current_user.uid = uid; - return(True); + return(True); } @@ -234,36 +126,17 @@ static BOOL become_gid(int gid) DEBUG(1,("WARNING: using gid %d is a security risk\n",gid)); } -#ifdef AIX - { - /* MWW: See comment above in become_uid. */ - priv_t priv; - - priv.pv_priv[0] = 0; - priv.pv_priv[1] = 0; - if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH, - &priv, sizeof(priv_t)) < 0) { - DEBUG(1, ("Can't set privilege (AIX3)\n")); - } - if (setgidx(ID_REAL|ID_EFFECTIVE, (gid_t)gid) < 0 || - setegid((gid_t)gid) < 0) { - DEBUG(1,("Can't set gid (AIX3)\n")); - } - } -#endif - -#ifdef USE_SETRES +#ifdef HAVE_SETRESUID if (setresgid(-1,gid,-1) != 0) -#elif defined(USE_SETFS) - if (setfsgid(gid) != 0) #else if (setgid(gid) != 0) #endif { DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n", gid,getgid(),getegid())); - if (gid > 32000) - DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); + if (gid > 32000) { + DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); + } return(False); } @@ -278,7 +151,7 @@ static BOOL become_gid(int gid) ****************************************************************************/ static BOOL become_id(int uid,int gid) { - return(become_gid(gid) && become_uid(uid)); + return(become_gid(gid) && become_uid(uid)); } /**************************************************************************** @@ -300,10 +173,12 @@ BOOL become_guest(void) /* 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) + if (!ret) { DEBUG(1,("Failed to become guest. Invalid guest account?\n")); + } current_user.cnum = -2; current_user.vuid = UID_FIELD_INVALID; @@ -390,7 +265,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) { if (!become_gid(gid)) return(False); -#ifndef NO_SETGROUPS +#ifdef HAVE_SETGROUPS if (!(VALID_CNUM(cnum) && conn->ipc)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) @@ -424,34 +299,30 @@ BOOL unbecome_user(void ) if (initial_uid == 0) { -#ifdef USE_SETRES +#ifdef HAVE_SETRESUID setresuid(-1,getuid(),-1); setresgid(-1,getgid(),-1); -#elif defined(USE_SETFS) - setfsuid(initial_uid); - setfsgid(initial_gid); #else if (seteuid(initial_uid) != 0) setuid(initial_uid); setgid(initial_gid); #endif } + #ifdef NO_EID if (initial_uid == 0) DEBUG(2,("Running with no EID\n")); initial_uid = getuid(); initial_gid = getgid(); #else - if (geteuid() != initial_uid) - { - DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); - initial_uid = geteuid(); - } - if (getegid() != initial_gid) - { - DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); - initial_gid = getegid(); - } + if (geteuid() != initial_uid) { + DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); + initial_uid = geteuid(); + } + if (getegid() != initial_gid) { + DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); + initial_gid = getegid(); + } #endif current_user.uid = initial_uid; @@ -485,13 +356,13 @@ static BOOL setup_stdout_file(char *outfile,BOOL shared) close(1); if (shared) { - /* become root - unprivilaged users can't delete these files */ -#ifdef USE_SETRES - setresgid(0,0,0); - setresuid(0,0,0); + /* become root - unprivilaged users can't delete these files */ +#ifdef HAVE_SETRESUID + setresgid(0,0,0); + setresuid(0,0,0); #else - setuid(0); - seteuid(0); + setuid(0); + seteuid(0); #endif } @@ -534,7 +405,7 @@ int smbrun(char *cmd,char *outfile,BOOL shared) int uid = current_user.uid; int gid = current_user.gid; -#if USE_SYSTEM +#ifndef HAVE_EXECL int ret; pstring syscmd; char *path = lp_smbrun(); @@ -583,7 +454,7 @@ int smbrun(char *cmd,char *outfile,BOOL shared) /* now completely lose our privilages. This is a fairly paranoid way of doing it, but it does work on all systems that I know of */ -#ifdef USE_SETRES +#ifdef HAVE_SETRESUID setresgid(0,0,0); setresuid(0,0,0); setresgid(gid,gid,gid); @@ -668,7 +539,7 @@ void unbecome_root(BOOL restore_dir) exit_server("Failed to restore gid"); } -#ifndef NO_SETGROUPS +#ifdef HAVE_SETGROUPS if (current_user_saved.ngroups > 0) { if (setgroups(current_user_saved.ngroups, current_user_saved.groups)<0) -- cgit From fb08c34cf3950f994701a9c98c89670f6346f7ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 05:05:36 +0000 Subject: get rid of the runtime test for broken getgroups() and add a compile time test instead. This also allows us to get rid of the igroups element of a couple of structures. (This used to be commit 8b25fe734166b76ceebf8d9543c706ebe0fddc96) --- source3/smbd/uid.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index a8e0bf0d03..173fdaca03 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -242,7 +242,6 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; - current_user.igroups = conn->igroups; current_user.ngroups = conn->ngroups; } else @@ -258,7 +257,6 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) gid = conn->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; - current_user.igroups = vuser->igroups; } if (initial_uid == 0) -- cgit From 28900ea26ff1c8d41328bba30206db7fe91e2184 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 31 Jul 1998 22:39:15 +0000 Subject: As per a Andrew's message, I went through and removed the timestring() timestamps from several DEBUG messages. The timestamps are redundant now that DEBUG() provides them automatically. There are still a few more files to do, but I've got to get home for dinner. Chris -)----- (This used to be commit 60286ccecaa6028d687e6406755016455e3b3a26) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 173fdaca03..82ff7ee7ce 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -327,8 +327,7 @@ BOOL unbecome_user(void ) current_user.gid = initial_gid; if (ChDir(OriginalDir) != 0) - DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", - timestring(),OriginalDir)); + DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) ); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); -- cgit From 3aeadef40b92d031036a50042bbf8fbe60d0954a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Aug 1998 23:45:34 +0000 Subject: nttrans.c: Fix change_notify. Queue processing code wasn't changing to the correct directory before doing the stat. Doh ! uid.c: Fix for performance in security=share mode. Invalid vuid meant that in security=share mode Samba was always doing the become_user/ undebome_user pairs for *every* smb. This code fixes it, but tridge should review for security implications. Jeremy. (This used to be commit c3663379fdcec487feea2e5d848ee012ee6c6baf) --- source3/smbd/uid.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 82ff7ee7ce..9e669c301b 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -216,7 +216,18 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) int snum,gid; int uid; - if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == 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.cnum == cnum) && + (current_user.uid == conn->uid)) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } else if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == vuid) && (current_user.uid == vuser->uid)) { DEBUG(4,("Skipping become_user - already user\n")); return(True); -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/smbd/uid.c | 303 ++++++++++++++--------------------------------------- 1 file changed, 78 insertions(+), 225 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9e669c301b..1276eeaaac 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -27,7 +27,7 @@ static int initial_uid; static int initial_gid; /* what user is current? */ -struct current_user current_user; +extern struct current_user current_user; pstring OriginalDir; @@ -51,7 +51,7 @@ void init_uid(void) initial_uid = geteuid(); initial_gid = getegid(); - current_user.cnum = -1; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; ChDir(OriginalDir); @@ -180,7 +180,7 @@ BOOL become_guest(void) DEBUG(1,("Failed to become guest. Invalid guest account?\n")); } - current_user.cnum = -2; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; return(ret); @@ -210,90 +210,89 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) /**************************************************************************** become the user of a connection number ****************************************************************************/ -BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) +BOOL become_user(connection_struct *conn, uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); - int snum,gid; - int uid; - - /* - * 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.cnum == cnum) && - (current_user.uid == conn->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); - return(True); - } else if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.uid == vuser->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); - return(True); - } - - unbecome_user(); - - if (!(VALID_CNUM(cnum) && conn->open)) { - DEBUG(2,("Connection %d not open\n",cnum)); - return(False); - } - - snum = conn->service; + user_struct *vuser = get_valid_user_struct(vuid); + int snum,gid; + int uid; + + /* + * 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.uid == conn->uid)) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } else if ((current_user.conn == conn) && + (vuser != 0) && (current_user.vuid == vuid) && + (current_user.uid == vuser->uid)) { + DEBUG(4,("Skipping become_user - already user\n")); + return(True); + } - if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) - return False; + unbecome_user(); - if (conn->force_user || - lp_security() == SEC_SHARE || - !(vuser) || (vuser->guest) - ) - { - uid = conn->uid; - gid = conn->gid; - current_user.groups = conn->groups; - current_user.ngroups = conn->ngroups; - } - else - { - if (!vuser) { - DEBUG(2,("Invalid vuid used %d\n",vuid)); - return(False); - } - uid = vuser->uid; - if(!*lp_force_group(snum)) - gid = vuser->gid; - else - gid = conn->gid; - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; - } + if (!(conn && conn->open)) { + DEBUG(2,("Connection not open\n")); + return(False); + } - if (initial_uid == 0) - { - if (!become_gid(gid)) return(False); + snum = SNUM(conn); + + if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) + return False; + + if (conn->force_user || + lp_security() == SEC_SHARE || + !(vuser) || (vuser->guest)) { + uid = conn->uid; + gid = conn->gid; + current_user.groups = conn->groups; + current_user.ngroups = conn->ngroups; + } else { + if (!vuser) { + DEBUG(2,("Invalid vuid used %d\n",vuid)); + return(False); + } + uid = vuser->uid; + if(!*lp_force_group(snum)) { + gid = vuser->gid; + } else { + gid = conn->gid; + } + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + } + + if (initial_uid == 0) { + if (!become_gid(gid)) return(False); #ifdef HAVE_SETGROUPS - if (!(VALID_CNUM(cnum) && conn->ipc)) { - /* groups stuff added by ih/wreu */ - if (current_user.ngroups > 0) - if (setgroups(current_user.ngroups,current_user.groups)<0) - DEBUG(0,("setgroups call failed!\n")); - } + if (!(conn && conn->ipc)) { + /* groups stuff added by ih/wreu */ + if (current_user.ngroups > 0) + if (setgroups(current_user.ngroups, + current_user.groups)<0) { + DEBUG(0,("setgroups call failed!\n")); + } + } #endif - if (!conn->admin_user && !become_uid(uid)) - return(False); - } - - current_user.cnum = cnum; - current_user.vuid = vuid; + if (!conn->admin_user && !become_uid(uid)) + return(False); + } + + current_user.conn = conn; + current_user.vuid = vuid; - DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", - getuid(),geteuid(),getgid(),getegid())); + DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", + getuid(),geteuid(),getgid(),getegid())); - return(True); + return(True); } /**************************************************************************** @@ -301,7 +300,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) ****************************************************************************/ BOOL unbecome_user(void ) { - if (current_user.cnum == -1) + if (!current_user.conn) return(False); ChDir(OriginalDir); @@ -343,158 +342,12 @@ BOOL unbecome_user(void ) DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); - current_user.cnum = -1; + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; return(True); } - -/**************************************************************************** -This is a utility function of smbrun(). It must be called only from -the child as it may leave the caller in a privilaged state. -****************************************************************************/ -static BOOL setup_stdout_file(char *outfile,BOOL shared) -{ - int fd; - struct stat st; - mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH; - int flags = O_RDWR|O_CREAT|O_TRUNC|O_EXCL; - - close(1); - - if (shared) { - /* become root - unprivilaged users can't delete these files */ -#ifdef HAVE_SETRESUID - setresgid(0,0,0); - setresuid(0,0,0); -#else - setuid(0); - seteuid(0); -#endif - } - - if(stat(outfile, &st) == 0) { - /* Check we're not deleting a device file. */ - if(st.st_mode & S_IFREG) - unlink(outfile); - else - flags = O_RDWR; - } - /* now create the file */ - fd = open(outfile,flags,mode); - - if (fd == -1) return False; - - if (fd != 1) { - if (dup2(fd,1) != 0) { - DEBUG(2,("Failed to create stdout file descriptor\n")); - close(fd); - return False; - } - close(fd); - } - return True; -} - - -/**************************************************************************** -run a command being careful about uid/gid handling and putting the output in -outfile (or discard it if outfile is NULL). - -if shared is True then ensure the file will be writeable by all users -but created such that its owned by root. This overcomes a security hole. - -if shared is not set then open the file with O_EXCL set -****************************************************************************/ -int smbrun(char *cmd,char *outfile,BOOL shared) -{ - int fd,pid; - int uid = current_user.uid; - int gid = current_user.gid; - -#ifndef HAVE_EXECL - int ret; - pstring syscmd; - char *path = lp_smbrun(); - - /* in the old method we use system() to execute smbrun which then - executes the command (using system() again!). This involves lots - of shell launches and is very slow. It also suffers from a - potential security hole */ - if (!file_exist(path,NULL)) - { - DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path)); - return(1); - } - - slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"", - path,uid,gid,cmd, - outfile?outfile:"/dev/null"); - - DEBUG(5,("smbrun - running %s ",syscmd)); - ret = system(syscmd); - DEBUG(5,("gave %d\n",ret)); - return(ret); -#else - /* in this newer method we will exec /bin/sh with the correct - arguments, after first setting stdout to point at the file */ - - if ((pid=fork())) { - int status=0; - /* the parent just waits for the child to exit */ - if (sys_waitpid(pid,&status,0) != pid) { - DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno))); - return -1; - } - return status; - } - - - /* we are in the child. we exec /bin/sh to do the work for us. we - don't directly exec the command we want because it may be a - pipeline or anything else the config file specifies */ - - /* point our stdout at the file we want output to go into */ - if (outfile && !setup_stdout_file(outfile,shared)) { - exit(80); - } - - /* now completely lose our privilages. This is a fairly paranoid - way of doing it, but it does work on all systems that I know of */ -#ifdef HAVE_SETRESUID - setresgid(0,0,0); - setresuid(0,0,0); - setresgid(gid,gid,gid); - setresuid(uid,uid,uid); -#else - setuid(0); - seteuid(0); - setgid(gid); - setegid(gid); - setuid(uid); - seteuid(uid); -#endif - - if (getuid() != uid || geteuid() != uid || - getgid() != gid || getegid() != gid) { - /* we failed to lose our privilages - do not execute the command */ - exit(81); /* we can't print stuff at this stage, instead use exit codes - for debugging */ - } - - /* close all other file descriptors, leaving only 0, 1 and 2. 0 and - 2 point to /dev/null from the startup code */ - for (fd=3;fd<256;fd++) close(fd); - - execl("/bin/sh","sh","-c",cmd,NULL); - - /* not reached */ - exit(82); -#endif - return 1; -} - static struct current_user current_user_saved; static int become_root_depth; static pstring become_root_dir; -- cgit From e13aeea928dd89373cfaf3916c96f853c1227884 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Aug 1998 01:19:26 +0000 Subject: configure: Changes for extra headers. configure.in: Source for header changes. client/clitar.c: Fixed isXXX macros & debugs for gcc pedantic compile. include/config.h.in: Added MEMSET, BZERO, MEMORY, RPCSVC_YPCLNT, STRINGS headers. include/includes.h: Headers for the above. include/smb.h: Made SIGNAL_CAST POSIX by default void (*)(int). lib/access.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/charset.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/debug.c: Fixed signal functs. lib/kanji.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/smbrun.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/util.c: Fixed isXXX macros & debugs for gcc pedantic compile. libsmb/namequery.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem_sysv.c: Fixed error messages in sysV stuff. nmbd/asyncdns.c: Fixed signal functs. nmbd/nmbd.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/passdb.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/smbpassfile.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/chgpasswd.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/ipc.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/nttrans.c: Fixed fsp code path. smbd/password.c: fixed HAVE_YP_GET_DEFAULT_DOMAIN problem. smbd/printing.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/reply.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/server.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/trans2.c: Fixed core dump bug. smbd/uid.c: Fixed isXXX macros & debugs for gcc pedantic compile. Jeremy. (This used to be commit 1b9cbcd02e575dc0a95fa589f720df30a4acc46b) --- source3/smbd/uid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 1276eeaaac..08a3952b3a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -96,7 +96,7 @@ static BOOL become_uid(int uid) #endif { DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n", - uid,getuid(), geteuid())); + uid,(int)getuid(), (int)geteuid())); if (uid > 32000) { DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); } @@ -133,7 +133,7 @@ static BOOL become_gid(int gid) #endif { DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n", - gid,getgid(),getegid())); + gid,(int)getgid(),(int)getegid())); if (gid > 32000) { DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); } @@ -290,7 +290,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) current_user.vuid = vuid; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", - getuid(),geteuid(),getgid(),getegid())); + (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); return(True); } @@ -340,7 +340,7 @@ BOOL unbecome_user(void ) DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) ); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", - getuid(),geteuid(),getgid(),getegid())); + (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; -- cgit From 983dc71c9844675ad364f3ea59ddd04b87857b55 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 06:13:32 +0000 Subject: moved connection_struct handling code into smbd/conn.c and changed it to a linked list with bitmap format. (This used to be commit b7aaab1b6b2d2f72b2bb7c11f5c7bf081a6093d9) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 08a3952b3a..4ffec90521 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -236,7 +236,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) unbecome_user(); - if (!(conn && conn->open)) { + if (!conn) { DEBUG(2,("Connection not open\n")); return(False); } -- cgit From 9066025a8a4afe1f7f559c455d86fc023792ed17 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Sep 1998 20:24:17 +0000 Subject: Got very strict about the differences and uses of uid_t, gid_t and vuid. Added sys_getgroups() to get around the int * return problem. Set correct datatypes for all uid, gid and vuid variables. Jeremy. (This used to be commit e570db46fc3a78e499523fd342e9a34cebb18998) --- source3/smbd/uid.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4ffec90521..7cd8c8673c 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -23,8 +23,8 @@ extern int DEBUGLEVEL; -static int initial_uid; -static int initial_gid; +static uid_t initial_uid; +static gid_t initial_gid; /* what user is current? */ extern struct current_user current_user; @@ -61,17 +61,16 @@ void init_uid(void) /**************************************************************************** become the specified uid ****************************************************************************/ -static BOOL become_uid(int uid) +static BOOL become_uid(uid_t uid) { if (initial_uid != 0) { return(True); } - if (uid == -1 || uid == 65535) { + 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", - uid)); + DEBUG(1,("WARNING: using uid %d is a security risk\n",(int)uid)); done=1; } } @@ -79,9 +78,9 @@ static BOOL become_uid(int uid) #ifdef HAVE_TRAPDOOR_UID #ifdef HAVE_SETUIDX /* AIX3 has setuidx which is NOT a trapoor function (tridge) */ - if (setuidx(ID_EFFECTIVE, (uid_t)uid) != 0) { - if (seteuid((uid_t)uid) != 0) { - DEBUG(1,("Can't set uid (setuidx)\n")); + if (setuidx(ID_EFFECTIVE, uid) != 0) { + if (seteuid(uid) != 0) { + DEBUG(1,("Can't set uid %d (setuidx)\n", (int)uid)); return False; } } @@ -96,14 +95,14 @@ static BOOL become_uid(int uid) #endif { DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n", - uid,(int)getuid(), (int)geteuid())); - if (uid > 32000) { + (int)uid,(int)getuid(), (int)geteuid())); + if (uid > (uid_t)32000) { DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); } return(False); } - if (((uid == -1) || (uid == 65535)) && geteuid() != uid) { + if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) && (geteuid() != uid)) { DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n")); return(False); } @@ -117,13 +116,13 @@ static BOOL become_uid(int uid) /**************************************************************************** become the specified gid ****************************************************************************/ -static BOOL become_gid(int gid) +static BOOL become_gid(gid_t gid) { if (initial_uid != 0) return(True); - if (gid == -1 || gid == 65535) { - DEBUG(1,("WARNING: using gid %d is a security risk\n",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)); } #ifdef HAVE_SETRESUID @@ -133,7 +132,7 @@ static BOOL become_gid(int gid) #endif { DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n", - gid,(int)getgid(),(int)getegid())); + (int)gid,(int)getgid(),(int)getegid())); if (gid > 32000) { DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); } @@ -149,7 +148,7 @@ static BOOL become_gid(int gid) /**************************************************************************** become the specified uid and gid ****************************************************************************/ -static BOOL become_id(int uid,int gid) +static BOOL become_id(uid_t uid,gid_t gid) { return(become_gid(gid) && become_uid(uid)); } @@ -213,8 +212,9 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) BOOL become_user(connection_struct *conn, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); - int snum,gid; - int uid; + int snum; + gid_t gid; + uid_t uid; /* * We need a separate check in security=share mode due to vuid -- cgit From 29e36b713468d7e7de301c483fc340ef42b4a9fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Nov 1998 07:06:48 +0000 Subject: extracted the password change code from smbpasswd and used it in swat instead of opening pipes and other horrible stuff. (This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821) --- source3/smbd/uid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7cd8c8673c..7c951b461a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -421,3 +421,5 @@ void unbecome_root(BOOL restore_dir) become_root_depth = 0; } + + -- cgit From bfc38ff872446e0ad365c22327c779e72a81bef9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Nov 1998 21:17:20 +0000 Subject: Makefile.in: Added maintainer mode fixes. aclocal.m4: Added AC_LIBTESTFUNC. configure.in: Fixed -lsecurity -lsec problems. client.c: dos_ fixes. groupdb/aliasunix.c: Dead code removal. include/includes.h: Added default PRINTCAP_NAME. lib/genrand.c: dos_ fixes. lib/replace.c: Added strtoul. lib/system.c: dos_ fixes. lib/util.c: dos_ fixes. lib/util_sid.c: Signed/unsigned fixes. lib/util_str.c: removed bad const. locking/locking_slow.c: dos_ fixes. printing/printing.c: dos_ fixes. rpc_server/srv_samr.c: Dead code removal. rpc_server/srv_sid.c: global_myworkgroup defined with wrong size AGAIN ! smbd/dir.c: dos_ fixes. smbd/open.c: dos_ fixes. smbd/oplock.c: dos_ fixes. smbd/reply.c smbd/server.c smbd/service.c smbd/uid.c: dos_ fixes. Jeremy. (This used to be commit 6acb4b68f68d516e2ac3c47e500f5600d653435e) --- source3/smbd/uid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7c951b461a..f76fa49d56 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -54,7 +54,7 @@ void init_uid(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; - ChDir(OriginalDir); + dos_ChDir(OriginalDir); } @@ -303,7 +303,7 @@ BOOL unbecome_user(void ) if (!current_user.conn) return(False); - ChDir(OriginalDir); + dos_ChDir(OriginalDir); if (initial_uid == 0) { @@ -336,7 +336,7 @@ BOOL unbecome_user(void ) current_user.uid = initial_uid; current_user.gid = initial_gid; - if (ChDir(OriginalDir) != 0) + if (dos_ChDir(OriginalDir) != 0) DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) ); DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", @@ -366,7 +366,7 @@ void become_root(BOOL save_dir) DEBUG(0,("ERROR: become root depth is non zero\n")); } if (save_dir) - GetWd(become_root_dir); + dos_GetWd(become_root_dir); current_user_saved = current_user; become_root_depth = 1; @@ -415,7 +415,7 @@ void unbecome_root(BOOL restore_dir) } if (restore_dir) - ChDir(become_root_dir); + dos_ChDir(become_root_dir); current_user = current_user_saved; -- cgit From d330c907bdc5d8e3c242cea76dfafaae84041270 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 1 Apr 1999 05:22:58 +0000 Subject: Ken McDonell from SGI was interested in adding some profiling capabilities to Samba so that Samba could talk to the SGI PCP (Performance Co-Pilot) apps. This change adds a profiling shared memory area and uses it to count two fairly trivial things, the number of uid switches and the number of SMB packets processes. To add more just edit include/profile.h and then increment it at the right place. I've also added a -P switch to smbstatus to dump the profile area. (This used to be commit ef3d61a80ad0b87c196a63ef2bd4fe8fc3863bd0) --- source3/smbd/uid.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f76fa49d56..b2407ed5fc 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -109,6 +109,10 @@ static BOOL become_uid(uid_t uid) current_user.uid = uid; +#ifdef WITH_PROFILE + profile_p->uid_changes++; +#endif + return(True); } -- cgit From 731c7f2ecfe17651506ba05b88358360e4654a37 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 13 Jun 1999 04:14:24 +0000 Subject: Moved code that changes the pw_passwd entry (i.e shadow password and weird unixware stuff) into _Get_Pwnam() to fix a memory allocation bug. Note that the Get_Pwnam() function now returns a const struct passwd * as a hint to other developers not to change entries in the struct passwd. (This used to be commit 36d7cb4ccc42268e8e6a7b783c945d1853624958) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b2407ed5fc..92565b7507 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -163,7 +163,7 @@ become the guest user BOOL become_guest(void) { BOOL ret; - static struct passwd *pass=NULL; + static const struct passwd *pass=NULL; if (initial_uid != 0) return(True); -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/smbd/uid.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 9 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 92565b7507..3501879d5f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -25,6 +25,7 @@ extern int DEBUGLEVEL; static uid_t initial_uid; static gid_t initial_gid; +static struct uid_cache vcache; /* what user is current? */ extern struct current_user current_user; @@ -54,6 +55,8 @@ void init_uid(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; + vcache.entries = 0; + dos_ChDir(OriginalDir); } @@ -192,24 +195,127 @@ BOOL become_guest(void) /******************************************************************* check if a username is OK ********************************************************************/ -static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) +static BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum) { int i; - for (i=0;iuid_cache.entries;i++) - if (conn->uid_cache.list[i] == vuser->uid) return(True); + for (i=0;ientries;i++) + if (cache->list[i] == vuser->uid) return(True); if (!user_ok(vuser->name,snum)) return(False); - i = conn->uid_cache.entries % UID_CACHE_SIZE; - conn->uid_cache.list[i] = vuser->uid; + i = cache->entries % UID_CACHE_SIZE; + cache->list[i] = vuser->uid; - if (conn->uid_cache.entries < UID_CACHE_SIZE) - conn->uid_cache.entries++; + if (cache->entries < UID_CACHE_SIZE) + cache->entries++; return(True); } +/**************************************************************************** + become the user of a connection number +****************************************************************************/ +BOOL become_vuser(uint16 vuid) +{ + user_struct *vuser = get_valid_user_struct(vuid); + gid_t gid; + uid_t uid; + + unbecome_vuser(); + + if((vuser != NULL) && !check_vuser_ok(&vcache, vuser, -1)) + return False; + + if ( vuser != 0 && + current_user.vuid == vuid && + current_user.uid == vuser->uid) + { + DEBUG(4,("Skipping become_vuser - already user\n")); + return(True); + } + uid = vuser->uid; + gid = vuser->gid; + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + + if (initial_uid == 0) + { + if (!become_gid(gid)) return(False); + +#ifdef HAVE_SETGROUPS + /* groups stuff added by ih/wreu */ + if (current_user.ngroups > 0) + { + if (setgroups(current_user.ngroups, + current_user.groups)<0) { + DEBUG(0,("setgroups call failed!\n")); + } + } +#endif + + if (!become_uid(uid)) return(False); + } + + current_user.conn = NULL; + current_user.vuid = vuid; + + DEBUG(5,("become_vuser uid=(%d,%d) gid=(%d,%d)\n", + (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); + + return(True); +} + +/**************************************************************************** + unbecome a user +****************************************************************************/ +BOOL unbecome_vuser(void) +{ + dos_ChDir(OriginalDir); + + if (initial_uid == 0) + { +#ifdef HAVE_SETRESUID + setresuid(-1,getuid(),-1); + setresgid(-1,getgid(),-1); +#else + if (seteuid(initial_uid) != 0) + setuid(initial_uid); + setgid(initial_gid); +#endif + } + +#ifdef NO_EID + if (initial_uid == 0) + DEBUG(2,("Running with no EID\n")); + initial_uid = getuid(); + initial_gid = getgid(); +#else + if (geteuid() != initial_uid) { + DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); + initial_uid = geteuid(); + } + if (getegid() != initial_gid) { + DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); + initial_gid = getegid(); + } +#endif + + current_user.uid = initial_uid; + current_user.gid = initial_gid; + + if (dos_ChDir(OriginalDir) != 0) + DEBUG( 0, ( "chdir(%s) failed in unbecome_vuser\n", OriginalDir ) ); + + DEBUG(5,("unbecome_vuser now uid=(%d,%d) gid=(%d,%d)\n", + (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); + + current_user.conn = NULL; + current_user.vuid = UID_FIELD_INVALID; + + return(True); +} + /**************************************************************************** become the user of a connection number ****************************************************************************/ @@ -217,7 +323,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; /* @@ -247,7 +353,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); - if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) + if((vuser != NULL) && !check_vuser_ok(&conn->uid_cache, vuser, snum)) return False; if (conn->force_user || -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/uid.c | 434 ++++++++++++++++++++--------------------------------- 1 file changed, 161 insertions(+), 273 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3501879d5f..ce0631e418 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -23,53 +23,36 @@ extern int DEBUGLEVEL; -static uid_t initial_uid; -static gid_t initial_gid; -static struct uid_cache vcache; - /* what user is current? */ extern struct current_user current_user; pstring OriginalDir; /**************************************************************************** -initialise the uid routines + Initialise the uid routines. ****************************************************************************/ + void init_uid(void) { - initial_uid = current_user.uid = geteuid(); - initial_gid = current_user.gid = getegid(); - - if (initial_gid != 0 && initial_uid == 0) { -#ifdef HAVE_SETRESUID - setresgid(0,0,0); -#else - setgid(0); - setegid(0); -#endif - } + current_user.uid = geteuid(); + current_user.gid = getegid(); - initial_uid = geteuid(); - initial_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; - vcache.entries = 0; - dos_ChDir(OriginalDir); } - /**************************************************************************** - become the specified uid + Become the specified uid. ****************************************************************************/ + static BOOL become_uid(uid_t uid) { - if (initial_uid != 0) { - return(True); - } - if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) { static int done; if (!done) { @@ -78,98 +61,53 @@ static BOOL become_uid(uid_t uid) } } -#ifdef HAVE_TRAPDOOR_UID -#ifdef HAVE_SETUIDX - /* AIX3 has setuidx which is NOT a trapoor function (tridge) */ - if (setuidx(ID_EFFECTIVE, uid) != 0) { - if (seteuid(uid) != 0) { - DEBUG(1,("Can't set uid %d (setuidx)\n", (int)uid)); - return False; - } - } -#endif -#endif - -#ifdef HAVE_SETRESUID - if (setresuid(-1,uid,-1) != 0) -#else - if ((seteuid(uid) != 0) && - (setuid(uid) != 0)) -#endif - { - DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n", - (int)uid,(int)getuid(), (int)geteuid())); - if (uid > (uid_t)32000) { - DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n")); - } - return(False); - } - - if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) && (geteuid() != uid)) { - DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n")); - return(False); - } + set_effective_uid(uid); - current_user.uid = uid; + current_user.uid = uid; #ifdef WITH_PROFILE - profile_p->uid_changes++; + profile_p->uid_changes++; #endif - return(True); + return(True); } /**************************************************************************** - become the specified gid + Become the specified gid. ****************************************************************************/ + static BOOL become_gid(gid_t gid) { - if (initial_uid != 0) - return(True); - - 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)); - } - -#ifdef HAVE_SETRESUID - if (setresgid(-1,gid,-1) != 0) -#else - if (setgid(gid) != 0) -#endif - { - DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n", - (int)gid,(int)getgid(),(int)getegid())); - if (gid > 32000) { - DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n")); + 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)); } - return(False); - } - - current_user.gid = gid; - - return(True); + + set_effective_gid(gid); + + current_user.gid = gid; + + return(True); } /**************************************************************************** - become the specified uid and gid + 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 + Become the guest user. ****************************************************************************/ + BOOL become_guest(void) { BOOL ret; - static const struct passwd *pass=NULL; - - if (initial_uid != 0) - return(True); + static struct passwd *pass=NULL; if (!pass) pass = Get_Pwnam(lp_guestaccount(-1),True); @@ -193,138 +131,43 @@ BOOL become_guest(void) } /******************************************************************* -check if a username is OK + Check if a username is OK. ********************************************************************/ -static BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum) + +static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;ientries;i++) - if (cache->list[i] == vuser->uid) return(True); + for (i=0;iuid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) return(True); if (!user_ok(vuser->name,snum)) return(False); - i = cache->entries % UID_CACHE_SIZE; - cache->list[i] = vuser->uid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - if (cache->entries < UID_CACHE_SIZE) - cache->entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; return(True); } /**************************************************************************** - become the user of a connection number -****************************************************************************/ -BOOL become_vuser(uint16 vuid) -{ - user_struct *vuser = get_valid_user_struct(vuid); - gid_t gid; - uid_t uid; - - unbecome_vuser(); - - if((vuser != NULL) && !check_vuser_ok(&vcache, vuser, -1)) - return False; - - if ( vuser != 0 && - current_user.vuid == vuid && - current_user.uid == vuser->uid) - { - DEBUG(4,("Skipping become_vuser - already user\n")); - return(True); - } - uid = vuser->uid; - gid = vuser->gid; - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; - - if (initial_uid == 0) - { - if (!become_gid(gid)) return(False); - -#ifdef HAVE_SETGROUPS - /* groups stuff added by ih/wreu */ - if (current_user.ngroups > 0) - { - if (setgroups(current_user.ngroups, - current_user.groups)<0) { - DEBUG(0,("setgroups call failed!\n")); - } - } -#endif - - if (!become_uid(uid)) return(False); - } - - current_user.conn = NULL; - current_user.vuid = vuid; - - DEBUG(5,("become_vuser uid=(%d,%d) gid=(%d,%d)\n", - (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - - return(True); -} - -/**************************************************************************** - unbecome a user + Become the user of a connection number. ****************************************************************************/ -BOOL unbecome_vuser(void) -{ - dos_ChDir(OriginalDir); - - if (initial_uid == 0) - { -#ifdef HAVE_SETRESUID - setresuid(-1,getuid(),-1); - setresgid(-1,getgid(),-1); -#else - if (seteuid(initial_uid) != 0) - setuid(initial_uid); - setgid(initial_gid); -#endif - } - -#ifdef NO_EID - if (initial_uid == 0) - DEBUG(2,("Running with no EID\n")); - initial_uid = getuid(); - initial_gid = getgid(); -#else - if (geteuid() != initial_uid) { - DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); - initial_uid = geteuid(); - } - if (getegid() != initial_gid) { - DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); - initial_gid = getegid(); - } -#endif - current_user.uid = initial_uid; - current_user.gid = initial_gid; - - if (dos_ChDir(OriginalDir) != 0) - DEBUG( 0, ( "chdir(%s) failed in unbecome_vuser\n", OriginalDir ) ); - - DEBUG(5,("unbecome_vuser now uid=(%d,%d) gid=(%d,%d)\n", - (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - - current_user.conn = NULL; - current_user.vuid = UID_FIELD_INVALID; - - return(True); -} - -/**************************************************************************** - become the user of a connection number -****************************************************************************/ 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; + + if (!conn) { + DEBUG(2,("Connection not open\n")); + return(False); + } /* * We need a separate check in security=share mode due to vuid @@ -346,14 +189,9 @@ BOOL become_user(connection_struct *conn, uint16 vuid) unbecome_user(); - if (!conn) { - DEBUG(2,("Connection not open\n")); - return(False); - } - snum = SNUM(conn); - if((vuser != NULL) && !check_vuser_ok(&conn->uid_cache, vuser, snum)) + if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) return False; if (conn->force_user || @@ -369,32 +207,55 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return(False); } uid = vuser->uid; - if(!*lp_force_group(snum)) { - gid = vuser->gid; + gid = vuser->gid; + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + } + + /* + * 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))) { + if(group_c == '+') { + + /* + * 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 < current_user.ngroups; i++) { + if (current_user.groups[i] == conn->gid) { + gid = conn->gid; + break; + } + } } else { gid = conn->gid; } - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; } - if (initial_uid == 0) { - if (!become_gid(gid)) return(False); + if (!become_gid(gid)) + return(False); #ifdef HAVE_SETGROUPS - if (!(conn && conn->ipc)) { - /* groups stuff added by ih/wreu */ - if (current_user.ngroups > 0) - if (setgroups(current_user.ngroups, - current_user.groups)<0) { - DEBUG(0,("setgroups call failed!\n")); - } - } + 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); - } + if (!conn->admin_user && !become_uid(uid)) + return(False); current_user.conn = conn; current_user.vuid = vuid; @@ -406,56 +267,83 @@ BOOL become_user(connection_struct *conn, uint16 vuid) } /**************************************************************************** - unbecome the user of a connection number + Unbecome the user of a connection number. ****************************************************************************/ + BOOL unbecome_user(void ) { - if (!current_user.conn) - return(False); - - dos_ChDir(OriginalDir); - - if (initial_uid == 0) - { -#ifdef HAVE_SETRESUID - setresuid(-1,getuid(),-1); - setresgid(-1,getgid(),-1); -#else - if (seteuid(initial_uid) != 0) - setuid(initial_uid); - setgid(initial_gid); -#endif - } - -#ifdef NO_EID - if (initial_uid == 0) - DEBUG(2,("Running with no EID\n")); - initial_uid = getuid(); - initial_gid = getgid(); -#else - if (geteuid() != initial_uid) { - DEBUG(0,("Warning: You appear to have a trapdoor uid system\n")); - initial_uid = geteuid(); - } - if (getegid() != initial_gid) { - DEBUG(0,("Warning: You appear to have a trapdoor gid system\n")); - initial_gid = getegid(); - } -#endif + if (!current_user.conn) + return(False); + + dos_ChDir(OriginalDir); - current_user.uid = initial_uid; - current_user.gid = initial_gid; + 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 ) ); + if (dos_ChDir(OriginalDir) != 0) + DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) ); - DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", - (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); + DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", + (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - current_user.conn = NULL; - current_user.vuid = UID_FIELD_INVALID; + current_user.conn = NULL; + current_user.vuid = UID_FIELD_INVALID; - return(True); + return(True); +} + +/**************************************************************************** + Become the user of an authenticated connected named pipe. + When this is called we are currently running as the connection + user. +****************************************************************************/ + +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. + */ + + if(!become_id(p->uid, p->gid)) { + /* Go back to the connection user. */ + become_user(p->conn, p->vuid); + return False; + } + + return True; +} + +/**************************************************************************** + Unbecome the user of an authenticated connected named pipe. + When this is called we are running as the authenticated pipe + user and need to go back to being the connection user. +****************************************************************************/ + +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); } static struct current_user current_user_saved; @@ -463,13 +351,14 @@ static int become_root_depth; static pstring become_root_dir; /**************************************************************************** -This is used when we need to do a privilaged operation (such as mucking +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 ****************************************************************************/ + void become_root(BOOL save_dir) { if (become_root_depth) { @@ -486,10 +375,11 @@ void become_root(BOOL save_dir) } /**************************************************************************** -When the privilaged operation is over call this +When the privileged operation is over call this Set save_dir if you also need to save/restore the CWD ****************************************************************************/ + void unbecome_root(BOOL restore_dir) { if (become_root_depth != 1) { @@ -512,9 +402,9 @@ void unbecome_root(BOOL restore_dir) #ifdef HAVE_SETGROUPS if (current_user_saved.ngroups > 0) { - if (setgroups(current_user_saved.ngroups, + if (sys_setgroups(current_user_saved.ngroups, current_user_saved.groups)<0) - DEBUG(0,("ERROR: setgroups call failed!\n")); + DEBUG(0,("ERROR: sys_setgroups call failed!\n")); } #endif @@ -531,5 +421,3 @@ void unbecome_root(BOOL restore_dir) become_root_depth = 0; } - - -- cgit From 32d5416b6a777a7874fec8518ec44e750560d882 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 May 2000 13:55:42 +0000 Subject: split the username in the vuser structure into a separate userdom_struct. As the name implies this also contains a domain (unused at the moment). This will be important shortly, as operation in appliance mode needs the domain to be always carried with the username. (This used to be commit ee8546342d5be90e730372b985710d764564b124) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ce0631e418..28d2fb71f6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -140,7 +140,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) for (i=0;iuid_cache.entries;i++) if (conn->uid_cache.list[i] == vuser->uid) return(True); - if (!user_ok(vuser->name,snum)) return(False); + if (!user_ok(vuser->user.unix_name,snum)) return(False); i = conn->uid_cache.entries % UID_CACHE_SIZE; conn->uid_cache.list[i] = vuser->uid; -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/uid.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 28d2fb71f6..d749470793 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -1,3 +1,5 @@ +#define OLD_NTDOMAIN 1 + /* Unix SMB/Netbios implementation. Version 1.9. @@ -421,3 +423,5 @@ void unbecome_root(BOOL restore_dir) become_root_depth = 0; } + +#undef OLD_NTDOMAIN -- cgit From dd4c0901b6da73452d2d748cb425a8d715bc56c0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Jun 2000 05:57:20 +0000 Subject: Moved some static functions to sec_ctx.c Implemented become_root() and friends in terms of push/pop/set security contexts. (This used to be commit 0bcdcd0606fc2b6aba35b03255aad5bb2bd8e848) --- source3/smbd/uid.c | 252 +++++++---------------------------------------------- 1 file changed, 30 insertions(+), 222 deletions(-) (limited to 'source3/smbd/uid.c') 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 -- cgit From 0e4a583374a39eefbf442b426f9a7340acc5553f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Jun 2000 06:27:05 +0000 Subject: Added return for become_authenticated_pipe_user() function. (This used to be commit d0f55e04c9400481e4a981431715e167a8246e45) --- source3/smbd/uid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f3a606a1b1..e66abd1e98 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -204,6 +204,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) } set_sec_ctx(p->uid, p->gid, 0, NULL); /* fix group stuff */ + + return True; } /**************************************************************************** -- cgit From f048209484b10ed397c55864ca9ee29789f4e372 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jul 2000 06:52:31 +0000 Subject: Some more sec_ctx changes. Modified some fields in the pipe_struct structure so authenticated pipe users can have their unix groups set when become_authenticated_pipe_user() is called. (This used to be commit 55c9bf124dc661df43bfe582ef14b1297aeaf0fa) --- source3/smbd/uid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e66abd1e98..2078bb5a7d 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -203,7 +203,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) return False; } - set_sec_ctx(p->uid, p->gid, 0, NULL); /* fix group stuff */ + set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, + p->pipe_user.n_groups, p->pipe_user.groups); return True; } -- cgit From 96446651af3f41c74de751f091740b06268a7a8c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 6 Jul 2000 07:01:37 +0000 Subject: Moved authenticated pipe user details into a current_user struct. (This used to be commit 3c4a5f624bfa69eb81d998530d9227e158edd109) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2078bb5a7d..172e872020 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -204,7 +204,7 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) } set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.n_groups, p->pipe_user.groups); + p->pipe_user.ngroups, p->pipe_user.groups); return True; } -- cgit From 17dcd9a834fc915fb1ff2d8042a23000eeb7acfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Aug 2000 02:11:55 +0000 Subject: Started to canonicalize our handling of uid -> sid code in order to get ready and fix se_access_check(). Added cannonical lookup_name(), lookup_sid(), uid_to_sid(), gid_to_sid() functions that look via winbind first the fall back on local lookup. All Samba should use these rather than trying to call winbindd code directly. Added NT_USER_TOKEN struct in user_struct, contains list of NT sids associated with this user. se_access_check() should use this (cached) value rather than attempting to do the same thing itself when given a uid/gid pair. More work needs to be done to preserve these things accross security context changes (especially with the tricky pipe problem) but I'm beginning to see how this will be done..... probably by registering a new vuid for an authenticated RPC pipe and not treating the pipe calls specially. More thoughts needed - but we're almost there... Jeremy. (This used to be commit 5e5cc6efe2e4687be59085f562caea1e2e05d0a8) --- source3/smbd/uid.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 172e872020..4cb2c512b6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -38,7 +38,8 @@ BOOL become_guest(void) if (!pass) pass = Get_Pwnam(lp_guestaccount(-1),True); - if (!pass) return(False); + if (!pass) + return(False); #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before @@ -60,19 +61,21 @@ BOOL become_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { - int i; - for (i=0;iuid_cache.entries;i++) - if (conn->uid_cache.list[i] == vuser->uid) return(True); + int i; + for (i=0;iuid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) + return(True); - if (!user_ok(vuser->user.unix_name,snum)) return(False); + if (!user_ok(vuser->user.unix_name,snum)) + return(False); - i = conn->uid_cache.entries % UID_CACHE_SIZE; - conn->uid_cache.list[i] = vuser->uid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - if (conn->uid_cache.entries < UID_CACHE_SIZE) - conn->uid_cache.entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; - return(True); + return(True); } /**************************************************************************** -- cgit From f87399915b009f88c41cb75a583c2972fe3daf30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Aug 2000 22:38:43 +0000 Subject: Added an NT_USER_TOKEN structure that is copied/passed around associated with the current user. This will allow se_access_check() to quickly do a SD check without having to translate uid/gid's to SIDs. Still needs work on pipe calls. Jeremy. (This used to be commit e28d01b744b3dbd33e0e54af4e7f426fa8c082b8) --- source3/smbd/uid.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4cb2c512b6..f6687e9a5a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -47,7 +47,7 @@ BOOL become_guest(void) initgroups(pass->pw_name, (gid_t)pass->pw_gid); #endif - set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL); + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; @@ -164,10 +164,11 @@ BOOL become_user(connection_struct *conn, uint16 vuid) } } - set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups); + set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, current_user.nt_user_token); current_user.conn = conn; current_user.vuid = vuid; + current_user.nt_user_token = conn->nt_user_token; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); @@ -206,8 +207,9 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) return False; } + /* JRATEST - this needs fixined w.r.t. NT user tokens... */ set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups); + p->pipe_user.ngroups, p->pipe_user.groups, NULL); return True; } -- cgit From 06e4f11acd3aedd6c8e4adf365932a01eca902b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Aug 2000 00:59:09 +0000 Subject: Fixed up the user/group contexts when using authenticated pipes. Added a become_root()/unbecome_root() (push/pop security context) around the initgroups() call to ensure it would succeed. Hmmm - I wonder if this call being done as non-root might explain any "group access" bugs we've had in the past.... Jeremy. (This used to be commit 06a65972e872f37d88b84f22ea714feebd38f6c0) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f6687e9a5a..fafcd71b1a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -207,9 +207,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) return False; } - /* JRATEST - this needs fixined w.r.t. NT user tokens... */ set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, NULL); + p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token); return True; } -- cgit From e3048cfc0b324ec5ab825efe87eaa97cc9504c09 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Aug 2000 18:40:48 +0000 Subject: Fixed memory leak with NT tokens. Added debug messages to se_access_check(). Added FULL_ACCESS acl to default acl on printers. Jeremy. (This used to be commit 7507f6f408cf8b0f8d7e2b3da54ce5fb5ef5343b) --- source3/smbd/uid.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index fafcd71b1a..b28f056a30 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -89,6 +89,8 @@ BOOL become_user(connection_struct *conn, uint16 vuid) gid_t gid; uid_t uid; char group_c; + BOOL must_free_token = False; + NT_USER_TOKEN *token = NULL; if (!conn) { DEBUG(2,("Connection not open\n")); @@ -125,6 +127,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) gid = conn->gid; current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; + token = conn->nt_user_token; } else { if (!vuser) { DEBUG(2,("Invalid vuid used %d\n",vuid)); @@ -134,6 +137,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; + token = vuser->nt_user_token; } /* @@ -162,13 +166,27 @@ BOOL become_user(connection_struct *conn, uint16 vuid) } else { gid = conn->gid; } + + /* + * We've changed the group list in the token - we must + * re-create it. + */ + + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups); + must_free_token = True; } - set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, current_user.nt_user_token); + set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token); + + /* + * Free the new token (as set_sec_ctx copies it). + */ + + if (must_free_token) + delete_nt_token(&token); current_user.conn = conn; current_user.vuid = vuid; - current_user.nt_user_token = conn->nt_user_token; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); -- cgit From 330d678fbad70fabd9712c56ad15bd215f950255 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Oct 2000 01:59:14 +0000 Subject: Fix to allow smbd to call winbindd if it is running for all group enumeration, falling back to the UNIX calls on error. This should fix all problems with smbd enumerating all users in all groups in all trusted domains via winbindd. Also changed GETDC to query 1C name rather than 1b name as only the PDC registers 1b. Jeremy. (This used to be commit 5b0038a2afd8abbd6fd4a58f5477a40d1926d498) --- source3/smbd/uid.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b28f056a30..fb83e724b8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -257,4 +257,230 @@ void unbecome_root(void) pop_sec_ctx(); } +/***************************************************************** + *THE CANONICAL* convert name to SID function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern pstring global_myname; + fstring sid; + + if (!winbind_lookup_name(name, psid, name_type)) { + BOOL ret; + + DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); + + ret = local_lookup_name(global_myname, name, psid, name_type); + if (ret) + DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), + (unsigned int)*name_type )); + else + DEBUG(10,("lookup name : (local) %s failed.\n", + name )); + return ret; + } + + DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), (unsigned int)*name_type )); + return True; +} + +/***************************************************************** + *THE CANONICAL* convert SID to name function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) +{ + if (!name_type) + return False; + + /* Check if this is our own sid. This should perhaps be done by + winbind? For the moment handle it here. */ + + if (sid->num_auths == 5) { + DOM_SID tmp_sid; + uint32 rid; + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + + if (sid_equal(&global_sam_sid, &tmp_sid)) { + + return map_domain_sid_to_name(&tmp_sid, dom_name) && + local_lookup_rid(rid, name, name_type); + } + } + + if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { + fstring sid_str; + DOM_SID tmp_sid; + uint32 rid; + + DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + return map_domain_sid_to_name(&tmp_sid, dom_name) && + lookup_known_rid(&tmp_sid, rid, name, name_type); + } + return True; +} + +/***************************************************************** + *THE CANONICAL* convert uid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) +{ + fstring sid; + + if (!winbind_uid_to_sid(psid, uid)) { + DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid )); + + return local_uid_to_sid(psid, uid); + } + + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert gid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) +{ + fstring sid; + + if (!winbind_gid_to_sid(psid, gid)) { + DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid )); + + return local_gid_to_sid(psid, gid); + } + + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, sid_to_string(sid,psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert SID to uid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a user sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_uid(puid, psid, sidtype); + } + + /* + * Ensure this is a user sid. + */ + + if (name_type != SID_NAME_USER) { + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + (unsigned int)name_type )); + return False; + } + + *sidtype = SID_NAME_USER; + + /* + * Get the uid for this SID. + */ + + if (!winbind_sid_to_uid(puid, psid)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*puid )); + + return True; +} + +/***************************************************************** + *THE CANONICAL* convert SID to gid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a group sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + /* + * Ensure this is a group sid. + */ + + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", + (unsigned int)name_type )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + *sidtype = name_type; + + /* + * Get the gid for this SID. + */ + + if (!winbind_sid_to_gid(pgid, psid)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("gid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*pgid )); + + return True; +} + #undef OLD_NTDOMAIN -- cgit From 5073d116431a03b2d6e00f529dd03c5c19264c33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Nov 2000 06:45:26 +0000 Subject: Fix for admin user being ignored. Jeremy. (This used to be commit f0dcc39d34202ed67d778ff40166856d4c2ad87b) --- source3/smbd/uid.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index fb83e724b8..c181b9a00f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -121,6 +121,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return False; if (conn->force_user || + conn->admin_user || lp_security() == SEC_SHARE || !(vuser) || (vuser->guest)) { uid = conn->uid; -- cgit From 9fede0dc0dbad51528cd1384023d24549c3f0ba4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 13 Nov 2000 23:03:34 +0000 Subject: Large commit which restructures the local password storage API. Currently the only backend which works is smbpasswd (tdb, LDAP, and NIS+) are broken, but they were somewhat broken before. :) The following functions implement the storage manipulation interface /*The following definitions come from passdb/pdb_smbpasswd.c */ BOOL pdb_setsampwent (BOOL update); void pdb_endsampwent (void); SAM_ACCOUNT* pdb_getsampwent (void); SAM_ACCOUNT* pdb_getsampwnam (char *username); SAM_ACCOUNT* pdb_getsampwuid (uid_t uid); SAM_ACCOUNT* pdb_getsampwrid (uint32 rid); BOOL pdb_add_sam_account (SAM_ACCOUNT *sampass); BOOL pdb_update_sam_account (SAM_ACCOUNT *sampass, BOOL override); BOOL pdb_delete_sam_account (char* username); There is also a host of pdb_set..() and pdb_get..() functions for manipulating SAM_ACCOUNT struct members. Note that the struct passdb_ops {} has gone away. Also notice that struct smb_passwd (formally in smb.h) has been moved to passdb/pdb_smbpasswd.c and is not accessed outisde of static internal functions in this file. All local password searches should make use of the the SAM_ACCOUNT struct and the previously mentioned functions. I'll write some documentation for this later. The next step is to fix the TDB passdb backend, then work on spliting the backends out into share libraries, and finally get the LDAP backend going. What works and may not: o domain logons from Win9x works o domain logons from WinNT 4 works o user and group enumeration as implemented by Tim works o file and print access works o changing password from Win9x & NT ummm...i'll fix this tonight :) If I broke anything else, just yell and I'll fix it. I think it should be fairly quite. -- jerry (This used to be commit 0b92d0838ebdbe24f34f17e313ecbf61a0301389) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c181b9a00f..d82edcbfae 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -243,8 +243,8 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p) return pop_sec_ctx(); } -/* Temporarily become a root user. Must match with unbecome_root(). */ +/* Temporarily become a root user. Must match with unbecome_root(). */ void become_root(void) { push_sec_ctx(); -- cgit From 4bce271e4fe239a8b4aac2bb65a52165d68d8ea5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Nov 2000 21:56:32 +0000 Subject: Merge from appliance head of JR's changes for driver versioning. Jeremy. (This used to be commit cdbd2e99775642dc2e92004be9014bf38a92d80f) --- source3/smbd/uid.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d82edcbfae..008765cde1 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -243,8 +243,8 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p) return pop_sec_ctx(); } - /* Temporarily become a root user. Must match with unbecome_root(). */ + void become_root(void) { push_sec_ctx(); @@ -267,25 +267,49 @@ BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; fstring sid; + char *sep = lp_winbind_separator(); if (!winbind_lookup_name(name, psid, name_type)) { BOOL ret; - DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); + DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name)); + + /* If we are looking up a domain user, make sure it is + for the local machine only */ + + if (strchr(name, sep[0]) || strchr(name, '\\')) { + fstring domain, username; + + split_domain_name(name, domain, username); + + if (strcasecmp(global_myname, domain) != 0) { + DEBUG(5, ("domain %s is not local\n", domain)); + return False; + } + + ret = local_lookup_name(domain, username, psid, + name_type); + } else { + + ret = local_lookup_name(global_myname, name, psid, + name_type); + } + + if (ret) { + DEBUG(10, + ("lookup_name: (local) %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), + (unsigned int)*name_type )); + } else { + DEBUG(10,("lookup name: (local) %s failed.\n", name)); + } - ret = local_lookup_name(global_myname, name, psid, name_type); - if (ret) - DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n", - name, sid_to_string(sid,psid), - (unsigned int)*name_type )); - else - DEBUG(10,("lookup name : (local) %s failed.\n", - name )); return ret; } - DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", - name, sid_to_string(sid,psid), (unsigned int)*name_type )); + DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", + name, sid_to_string(sid, psid), + (unsigned int)*name_type)); return True; } @@ -300,7 +324,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE return False; /* Check if this is our own sid. This should perhaps be done by - winbind? For the moment handle it here. */ + winbind? For the moment handle it here. */ if (sid->num_auths == 5) { DOM_SID tmp_sid; -- cgit From 276364e2a4cee00f4521845347a0b0a371f6b0e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Dec 2000 02:36:14 +0000 Subject: Removed the special casing of SIDs in se_access_check. This is now done (correctly) when the NT_USER_TOKEN is *created*. Jeremy. (This used to be commit 27d72ed1cf8ece2bede812341279ba5a7262ace4) --- source3/smbd/uid.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 008765cde1..25cadb51b0 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -148,6 +148,8 @@ BOOL become_user(connection_struct *conn, uint16 vuid) */ if((group_c = *lp_force_group(snum))) { + BOOL is_guest = False; + if(group_c == '+') { /* @@ -173,7 +175,10 @@ BOOL become_user(connection_struct *conn, uint16 vuid) * re-create it. */ - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups); + if (vuser && vuser->guest) + is_guest = True; + + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); must_free_token = True; } -- cgit From adb91565b5ec81ebb9e0d57b7d91fbd9da410aa3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Jan 2001 18:38:55 +0000 Subject: rpc_server/srv_samr.c: smbd/reply.c: Added fix needed for appliances. When using winbindd - a new user may exist (from winbind) but have no home directory. Extend add user script so it is called with a %H substitution when a user exists but their home directory does not. Thanks to Alex Win at VA Linux for finding this one and testing the fix. libsmb/clidgram.c: Fixed missing return statements. smbd/uid.c: Fixed typo in debug. Jeremy. (This used to be commit 7ba0a2192b89954604dd793c537b4a17c2d1ac07) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 25cadb51b0..1d2b8f4e9f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -488,7 +488,7 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) */ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { - DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); return local_sid_to_gid(pgid, psid, sidtype); -- cgit From fd46817f0b20c633c80dee70a29cf7478e2dfd68 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Feb 2001 19:21:18 +0000 Subject: Excise snprintf -> slprintf. srv_samr.c: duplicate gid fix. srv_spoolss_nt.c: Merge of JF's work. uid.c: Fix for returning names when a PDC. Jeremy. (This used to be commit d938ad6963a2dd4eda930d508600ec1902dc2b16) --- source3/smbd/uid.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 1d2b8f4e9f..db43106b77 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -271,6 +271,7 @@ void unbecome_root(void) BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; + extern fstring global_myworkgroup; fstring sid; char *sep = lp_winbind_separator(); @@ -287,9 +288,17 @@ BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) split_domain_name(name, domain, username); - if (strcasecmp(global_myname, domain) != 0) { - DEBUG(5, ("domain %s is not local\n", domain)); - return False; + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + if (strequal(domain, global_myworkgroup)) + fstrcpy(domain, global_myname); + /* No break is deliberate here. JRA. */ + default: + if (strcasecmp(global_myname, domain) != 0) { + DEBUG(5, ("domain %s is not local\n", domain)); + return False; + } } ret = local_lookup_name(domain, username, psid, -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/uid.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index db43106b77..3d37021fff 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -1,5 +1,3 @@ -#define OLD_NTDOMAIN 1 - /* Unix SMB/Netbios implementation. Version 1.9. @@ -521,5 +519,3 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) return True; } - -#undef OLD_NTDOMAIN -- cgit From beec1ea8291c9c2b12745d37ffe307dd4e3bd6ec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2001 23:07:36 +0000 Subject: Fix for crash when doing name lookup with a quoted string. Part of lookup_name was expecting to be able to write to the string. Changed lookup_name to use const. Jeremy. (This used to be commit 80c18d88491f1148ade623e81c33f84ba4f952f3) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3d37021fff..02522a37a2 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -266,7 +266,7 @@ void unbecome_root(void) Tries winbind first - then uses local lookup. *****************************************************************/ -BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; extern fstring global_myworkgroup; @@ -302,7 +302,6 @@ BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) ret = local_lookup_name(domain, username, psid, name_type); } else { - ret = local_lookup_name(global_myname, name, psid, name_type); } -- cgit From 18f3f5ff9282417b350873fd572e9e0c4d4bcea4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 15 Apr 2001 23:36:05 +0000 Subject: Fixed potential bug in "become_guest" pointed out by elrond. Get_Pwnam() returns a pointer to changable storage so ensure we save the details and don't use the pointer directly. Jeremy. (This used to be commit d9fdaae54ee3a267aebd02ff6058a98aefc084c2) --- source3/smbd/uid.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 02522a37a2..da4c538319 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -33,19 +33,26 @@ extern struct current_user current_user; BOOL become_guest(void) { static struct passwd *pass=NULL; - - if (!pass) + static uid_t guest_uid = (uid_t)-1; + static gid_t guest_gid = (gid_t)-1; + static fstring guest_name; + + if (!pass) { pass = Get_Pwnam(lp_guestaccount(-1),True); - if (!pass) - return(False); + if (!pass) + return(False); + guest_uid = pass->pw_uid; + guest_gid = pass->pw_gid; + fstrcpy(guest_name, pass->pw_name); + } #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ - initgroups(pass->pw_name, (gid_t)pass->pw_gid); + initgroups(guest_name, guest_gid); #endif - set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_sec_ctx(guest_uid, guest_gid, 0, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; -- cgit From 527e824293ee934ca5da0ef5424efe5ab7757248 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:36:09 +0000 Subject: strchr and strrchr are macros when compiling with optimisation in gcc, so we can't redefine them. damn. (This used to be commit c41fc06376d1a2b83690612304e85010b5e5f3cf) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index da4c538319..0070781d24 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -288,7 +288,7 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) /* If we are looking up a domain user, make sure it is for the local machine only */ - if (strchr(name, sep[0]) || strchr(name, '\\')) { + if (strchr_m(name, sep[0]) || strchr_m(name, '\\')) { fstring domain, username; split_domain_name(name, domain, username); -- cgit From bd0eacb24cb5b138e9c95dc56d023119dec66f4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Jul 2001 01:46:47 +0000 Subject: Fix invalid uid being used after logoff. Thanks to Nigel Williams for this bug report. Jeremy. (This used to be commit 50d8e5b22f2c2c792e3a2d33e00a1c9caab48981) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 0070781d24..9fe634a7e9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -127,8 +127,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) if (conn->force_user || conn->admin_user || - lp_security() == SEC_SHARE || - !(vuser) || (vuser->guest)) { + (lp_security() == SEC_SHARE)) { uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/uid.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9fe634a7e9..6afaf1493e 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -21,8 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /* what user is current? */ extern struct current_user current_user; -- cgit From ed94aa9d611aba4d82e717797565550a4a47270e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Oct 2001 20:54:56 +0000 Subject: Fixes from John Trostel (modified somewhat by me) to ensure that all lookup_XX functions correctly deal with the SID_NAME_TYPE. One fix for connection user lookup in LSA. Jeremy. (This used to be commit 29730027d8118ec7d207c89d0fd7fb24ac173fde) --- source3/smbd/uid.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 6afaf1493e..45ae31da2a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -277,7 +277,9 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) fstring sid; char *sep = lp_winbind_separator(); - if (!winbind_lookup_name(name, psid, name_type)) { + *name_type = SID_NAME_UNKNOWN; + + if (!winbind_lookup_name(name, psid, name_type) || (*name_type != SID_NAME_USER) ) { BOOL ret; DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name)); @@ -293,21 +295,19 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - if (strequal(domain, global_myworkgroup)) + if (strequal(domain, global_myworkgroup)) { fstrcpy(domain, global_myname); + ret = local_lookup_name(domain, username, psid, name_type); + } /* No break is deliberate here. JRA. */ default: if (strcasecmp(global_myname, domain) != 0) { - DEBUG(5, ("domain %s is not local\n", domain)); - return False; + DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); + ret = local_lookup_name(global_myname, username, psid, name_type); } } - - ret = local_lookup_name(domain, username, psid, - name_type); } else { - ret = local_lookup_name(global_myname, name, psid, - name_type); + ret = local_lookup_name(global_myname, name, psid, name_type); } if (ret) { @@ -322,9 +322,9 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) return ret; } - DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", - name, sid_to_string(sid, psid), - (unsigned int)*name_type)); + DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", + name, sid_to_string(sid, psid), + (unsigned int)*name_type)); return True; } @@ -338,6 +338,8 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE if (!name_type) return False; + *name_type = SID_NAME_UNKNOWN; + /* Check if this is our own sid. This should perhaps be done by winbind? For the moment handle it here. */ @@ -418,7 +420,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) *THE CANONICAL* convert SID to uid function. Tries winbind first - then uses local lookup. Returns True if this name is a user sid and the conversion - was done correctly, False if not. + was done correctly, False if not. sidtype is set by this function. *****************************************************************/ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) @@ -432,7 +434,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) * First we must look up the name and decide if this is a user sid. */ - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); -- cgit From 2f7ce531ada2b7c7d09ab6a976b53ce40e6135be Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 12 Oct 2001 06:09:39 +0000 Subject: fixed compiler warning. (This used to be commit 2d5b0f7ad865f92668954f87fd3b116a7abffa10) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 45ae31da2a..39bdaaa596 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -280,7 +280,7 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) *name_type = SID_NAME_UNKNOWN; if (!winbind_lookup_name(name, psid, name_type) || (*name_type != SID_NAME_USER) ) { - BOOL ret; + BOOL ret = False; DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name)); -- cgit From c416ff851b4ecc7a44aee9d00d07dd481d8ae2a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2001 20:15:12 +0000 Subject: Merge the become_XXX -> change_to_XXX fixes from 2.2.2 to HEAD. Ensure make_conection() can only be called as root. Jeremy. (This used to be commit 8d23a7441b4687458ee021bfe8880558506eddba) --- source3/smbd/uid.c | 142 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 20 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 39bdaaa596..b1012c3c91 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -25,10 +25,10 @@ extern struct current_user current_user; /**************************************************************************** - Become the guest user. + Become the guest user without changing the security context stack. ****************************************************************************/ -BOOL become_guest(void) +BOOL change_to_guest(void) { static struct passwd *pass=NULL; static uid_t guest_uid = (uid_t)-1; @@ -82,10 +82,11 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } /**************************************************************************** - Become the user of a connection number. + Become the user of a connection number without changing the security context + stack, but modify the currnet_user entries. ****************************************************************************/ -BOOL become_user(connection_struct *conn, uint16 vuid) +BOOL change_to_user(connection_struct *conn, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum; @@ -96,7 +97,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) NT_USER_TOKEN *token = NULL; if (!conn) { - DEBUG(2,("Connection not open\n")); + DEBUG(2,("change_to_user: Connection not open\n")); return(False); } @@ -109,12 +110,12 @@ BOOL become_user(connection_struct *conn, uint16 vuid) if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && (current_user.uid == conn->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); + DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && (current_user.uid == vuser->uid)) { - DEBUG(4,("Skipping become_user - already user\n")); + DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } @@ -133,7 +134,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) token = conn->nt_user_token; } else { if (!vuser) { - DEBUG(2,("Invalid vuid used %d\n",vuid)); + DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid)); return(False); } uid = vuser->uid; @@ -196,21 +197,22 @@ BOOL become_user(connection_struct *conn, uint16 vuid) current_user.conn = conn; current_user.vuid = vuid; - DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", + DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); return(True); } /**************************************************************************** - Unbecome the user of a connection number. + Go back to being root without changing the security context stack, + but modify the current_user entries. ****************************************************************************/ -BOOL unbecome_user(void ) +BOOL change_to_root_user(void) { set_root_sec_ctx(); - DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n", + DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); current_user.conn = NULL; @@ -222,16 +224,13 @@ BOOL unbecome_user(void ) /**************************************************************************** Become the user of an authenticated connected named pipe. When this is called we are currently running as the connection - user. + user. Doesn't modify current_user. ****************************************************************************/ BOOL become_authenticated_pipe_user(pipes_struct *p) { - BOOL res = push_sec_ctx(); - - if (!res) { + if (!push_sec_ctx()) return False; - } set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token); @@ -242,19 +241,93 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) /**************************************************************************** Unbecome the user of an authenticated connected named pipe. When this is called we are running as the authenticated pipe - user and need to go back to being the connection user. + user and need to go back to being the connection user. Doesn't modify + current_user. ****************************************************************************/ -BOOL unbecome_authenticated_pipe_user(pipes_struct *p) +BOOL unbecome_authenticated_pipe_user(void) { return pop_sec_ctx(); } -/* Temporarily become a root user. Must match with unbecome_root(). */ +/**************************************************************************** + Utility functions used by become_xxx/unbecome_xxx. +****************************************************************************/ + +struct conn_ctx { + connection_struct *conn; + uint16 vuid; +}; + +/* A stack of current_user connection contexts. */ + +static struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH]; +static int conn_ctx_stack_ndx; + +static void push_conn_ctx(void) +{ + struct conn_ctx *ctx_p; + + /* Check we don't overflow our stack */ + + if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) { + DEBUG(0, ("Connection context stack overflow!\n")); + smb_panic("Connection context stack overflow!\n"); + } + + /* Store previous user context */ + ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx]; + + ctx_p->conn = current_user.conn; + ctx_p->vuid = current_user.vuid; + + DEBUG(3, ("push_conn_ctx(%u) : conn_ctx_stack_ndx = %d\n", + (unsigned int)ctx_p->vuid, conn_ctx_stack_ndx )); + + conn_ctx_stack_ndx++; +} + +static void pop_conn_ctx(void) +{ + struct conn_ctx *ctx_p; + + /* Check for stack underflow. */ + + if (conn_ctx_stack_ndx == 0) { + DEBUG(0, ("Connection context stack underflow!\n")); + smb_panic("Connection context stack underflow!\n"); + } + + conn_ctx_stack_ndx--; + ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx]; + + current_user.conn = ctx_p->conn; + current_user.vuid = ctx_p->vuid; + + ctx_p->conn = NULL; + ctx_p->vuid = UID_FIELD_INVALID; +} + +void init_conn_ctx(void) +{ + int i; + + /* Initialise connection context stack */ + for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) { + conn_ctx_stack[i].conn = NULL; + conn_ctx_stack[i].vuid = UID_FIELD_INVALID; + } +} + +/**************************************************************************** + Temporarily become a root user. Must match with unbecome_root(). Saves and + restores the connection context. +****************************************************************************/ void become_root(void) { push_sec_ctx(); + push_conn_ctx(); set_root_sec_ctx(); } @@ -263,6 +336,35 @@ void become_root(void) void unbecome_root(void) { pop_sec_ctx(); + pop_conn_ctx(); +} + +/**************************************************************************** + Push the current security context then force a change via change_to_user(). + Saves and restores the connection context. +****************************************************************************/ + +BOOL become_user(connection_struct *conn, uint16 vuid) +{ + if (!push_sec_ctx()) + return False; + + push_conn_ctx(); + + if (!change_to_user(conn, vuid)) { + pop_sec_ctx(); + pop_conn_ctx(); + return False; + } + + return True; +} + +BOOL unbecome_user() +{ + pop_sec_ctx(); + pop_conn_ctx(); + return True; } /***************************************************************** -- cgit From b49b5b94818827da43dee53346ced84c789fd73d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Oct 2001 00:02:36 +0000 Subject: client : Fixed error return. uid.c: Added missing void. Jeremy. (This used to be commit c2e06ed2219860479868fd1ac18013ae4f891e10) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b1012c3c91..2151068de5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -360,7 +360,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return True; } -BOOL unbecome_user() +BOOL unbecome_user(void) { pop_sec_ctx(); pop_conn_ctx(); -- cgit From 2038649e51f48a489aeec49947e1b791f0b3df43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 07:28:32 +0000 Subject: This commit is number 3 of 4. In particular this commit focuses on: Changing the Get_Pwnam code so that it can work in a const-enforced environment. While these changes have been mildly tested, and are pretty small, any assistance in this is appreciated. ---- These changes allow for 'const' in the Samba tree. There are a number of good reasons to do this: - I want to allow the SAM_ACCOUNT structure to move from wasteful pstrings and fstrings to allocated strings. We can't do that if people are modifying these outputs, as they may well make assumptions about getting pstrings and fstrings - I want --with-pam_smbpass to compile with a slightly sane volume of warnings, currently its pretty bad, even in 2.2 where is compiles at all. - Tridge assures me that he no longer opposes 'const religion' based on the ability to #define const the problem away. - Changed Get_Pwnam(x,y) into two variants (so that the const parameter can work correctly): - Get_Pwnam(const x) and Get_Pwnam_Modify(x). - Reworked smbd/chgpasswd.c to work with these mods, passing around a 'struct passwd' rather than the modified username (This used to be commit e7634f81c5116ff4addfb7e495f54b6bb78e8f77) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2151068de5..ae287cca76 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -36,7 +36,7 @@ BOOL change_to_guest(void) static fstring guest_name; if (!pass) { - pass = Get_Pwnam(lp_guestaccount(-1),True); + pass = Get_Pwnam(lp_guestaccount(-1)); if (!pass) return(False); guest_uid = pass->pw_uid; -- cgit From f8e2baf39eb864481dd48f61404136b325cd73c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/smbd/uid.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ae287cca76..b33c9ede17 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -181,7 +181,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); must_free_token = True; } @@ -367,6 +367,75 @@ BOOL unbecome_user(void) return True; } +/***************************************************************** + Convert the suplimentary SIDs returned in a netlogon into UNIX + group gid_t's. Add to the total group array. +*****************************************************************/ + +void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok) +{ + int total_groups; + int current_n_groups = *n_groups; + gid_t *final_groups = NULL; + size_t i; + NT_USER_TOKEN *ptok = *pptok; + NT_USER_TOKEN *new_tok = NULL; + + if (!ptok || (ptok->num_sids == 0)) + return; + + new_tok = dup_nt_token(ptok); + if (!new_tok) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n")); + return; + } + /* Leave the allocated space but empty the number of SIDs. */ + new_tok->num_sids = 0; + + total_groups = current_n_groups + ptok->num_sids; + + final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t)); + if (!final_groups) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n")); + delete_nt_token(&new_tok); + return; + } + + memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t)); + for (i = 0; i < ptok->num_sids; i++) { + enum SID_NAME_USE sid_type; + gid_t new_grp; + + if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) { + /* + * Don't add the gid_t if it is already in the current group + * list. Some UNIXen don't like the same group more than once. + */ + int j; + + for (j = 0; j < current_n_groups; j++) + if (final_groups[j] == new_grp) + break; + + if ( j == current_n_groups) { + /* Group not already present. */ + final_groups[current_n_groups++] = new_grp; + } + } else { + /* SID didn't map. Copy to the new token to be saved. */ + sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]); + } + } + + SAFE_FREE(*pp_groups); + *pp_groups = final_groups; + *n_groups = current_n_groups; + + /* Replace the old token with the truncated one. */ + delete_nt_token(&ptok); + *pptok = new_tok; +} + /***************************************************************** *THE CANONICAL* convert name to SID function. Tries winbind first - then uses local lookup. -- cgit From f56a3ea612beded266c614511aa4c451639cbe9a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 8 Nov 2001 04:41:13 +0000 Subject: Fixed incorrect debug message. )-: (This used to be commit a99d9cec7e090736ab49c91720cfd2b43e2a6f00) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b33c9ede17..e40b4707fc 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -689,7 +689,7 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) return False; } - DEBUG(10,("gid_to_uid: winbindd %s -> %u\n", + DEBUG(10,("sid_to_gid: winbindd %s -> %u\n", sid_to_string(sid_str, psid), (unsigned int)*pgid )); -- cgit From 395aa946cd4fb9d5e07dd2fee418045a8064dfab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Nov 2001 11:16:06 +0000 Subject: This change updates lp_guestaccount() to be a *global* paramater, rather than per-share. I beleive that almost all the things that this could have done on a per-share basis can be done with other tools, like 'force user'. Almost all the user's of this paramater used it as a global anyway... While this is one step at a time, I hope it will allow me to considerably simplfy the make_connection() code, particularly for the user-level security case. This already removes an absolute truckload of extra attempted password lookups on the guest account. Andrew Bartlett (This used to be commit 8e708332eded210c1d1fe0cebca3c9c19f054b71) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e40b4707fc..4329e3fb76 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -36,7 +36,7 @@ BOOL change_to_guest(void) static fstring guest_name; if (!pass) { - pass = Get_Pwnam(lp_guestaccount(-1)); + pass = sys_getpwnam(lp_guestaccount()); if (!pass) return(False); guest_uid = pass->pw_uid; -- cgit From 64dd6c3412f961239ad4c6989aab67250d312c9d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Nov 2001 04:27:51 +0000 Subject: Another merge from appliance-head: in [ug]id_to_sid don't call the winbind function if the id is obviously going to be local. Cleanup of winbind [ug]id parameter handling. (This used to be commit 4ab9ca31a02b3388aa89a00e0390ea9e4c76283a) --- source3/smbd/uid.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4329e3fb76..14b0290e33 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -551,16 +551,24 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) { + uid_t low, high; fstring sid; - if (!winbind_uid_to_sid(psid, uid)) { - DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid )); + if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { + if (winbind_uid_to_sid(psid, uid)) { - return local_uid_to_sid(psid, uid); - } + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, + sid_to_string(sid, psid))); + + return psid; + } + } - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid) )); + local_uid_to_sid(psid, uid); + + DEBUG(10,("uid_to_sid: local %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid))); return psid; } @@ -573,16 +581,24 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) { + gid_t low, high; fstring sid; - if (!winbind_gid_to_sid(psid, gid)) { - DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid )); - - return local_gid_to_sid(psid, gid); - } - - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, sid_to_string(sid,psid) )); + if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { + if (winbind_gid_to_sid(psid, gid)) { + + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, + sid_to_string(sid, psid))); + + return psid; + } + } + + local_gid_to_sid(psid, gid); + + DEBUG(10,("gid_to_sid: local %u -> %s\n", + (unsigned int)gid, sid_to_string(sid, psid))); return psid; } -- cgit From 7d2d605f0db0c3689a263d6857721eac66a1b9c1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Nov 2001 19:51:25 +0000 Subject: space -> tab. Jeremy. (This used to be commit c7dd0364f2b084d9a372ac885fd788bbb5113125) --- source3/smbd/uid.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 14b0290e33..524ddb15ab 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -551,24 +551,22 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) { - uid_t low, high; + uid_t low, high; fstring sid; - if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { - if (winbind_uid_to_sid(psid, uid)) { + if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { + if (winbind_uid_to_sid(psid, uid)) { - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, - sid_to_string(sid, psid))); + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid))); - return psid; - } - } + return psid; + } + } - local_uid_to_sid(psid, uid); + local_uid_to_sid(psid, uid); - DEBUG(10,("uid_to_sid: local %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); + DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); return psid; } @@ -581,24 +579,22 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) { - gid_t low, high; + gid_t low, high; fstring sid; - if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { - if (winbind_gid_to_sid(psid, gid)) { + if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { + if (winbind_gid_to_sid(psid, gid)) { - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, - sid_to_string(sid, psid))); + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, sid_to_string(sid, psid))); - return psid; - } - } + return psid; + } + } - local_gid_to_sid(psid, gid); + local_gid_to_sid(psid, gid); - DEBUG(10,("gid_to_sid: local %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); + DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); return psid; } -- cgit From c2e3d8ba018221c0a0b22a91fdb361dd740482b9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Dec 2001 02:58:22 +0000 Subject: Tidyup of lib/username. Add name_is_local fn to determine if name is winbindd. Getting ready for efficiency fix in group lookups. Jeremy. (This used to be commit 8d41dfd149625e8ac53ab5e90a96e9a2daf9a629) --- source3/smbd/uid.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 524ddb15ab..9a9de0a796 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -436,6 +436,16 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER *pptok = new_tok; } +/***************************************************************** + Check if a user or group name is local (this is a *local* name for + *local* people, there's nothing for you here...). +*****************************************************************/ + +BOOL name_is_local(const char *name) +{ + return !strchr_m(name, *lp_winbind_separator()); +} + /***************************************************************** *THE CANONICAL* convert name to SID function. Tries winbind first - then uses local lookup. -- cgit From 8e99888e7b29817e2e242b8fe59a10465500807c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Dec 2001 03:47:44 +0000 Subject: Moved name_is_local to the correct place. Ooops. Jeremy. (This used to be commit 708c0a8d16ca86439e451def5f8d37f600ff15f1) --- source3/smbd/uid.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9a9de0a796..524ddb15ab 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -436,16 +436,6 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER *pptok = new_tok; } -/***************************************************************** - Check if a user or group name is local (this is a *local* name for - *local* people, there's nothing for you here...). -*****************************************************************/ - -BOOL name_is_local(const char *name) -{ - return !strchr_m(name, *lp_winbind_separator()); -} - /***************************************************************** *THE CANONICAL* convert name to SID function. Tries winbind first - then uses local lookup. -- cgit From 922eb763d7365716fd3c20aa069746fc9bfb8ab3 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 4 Dec 2001 21:53:47 +0000 Subject: added a boolean to the group mapping functions to specify if we need or not the privileges. Usually we don't need them, so the memory is free early. lib/util_sid.c: added some helper functions to check an SID. passdb/passdb.c: renamed local_lookup_rid() to local_lookup_sid() and pass an RID all the way. If the group doesn't exist on the domain SID, don't return a faked one as it can collide with a builtin one. Some rpc structures have been badly designed, they return only rids and force the client to do subsequent lsa_lookup_sid() on the domain sid and the builtin sid ! rpc_server/srv_util.c: wrote a new version of get_domain_user_groups(). Only the samr code uses it atm. It uses the group mapping code instead of a bloody hard coded crap. The netlogon code will use it too, but I have to do some test first. J.F. (This used to be commit 6c87e96149101995b7d049657d5c26eefef37d8c) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 524ddb15ab..650d9270cb 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -524,7 +524,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE if (sid_equal(&global_sam_sid, &tmp_sid)) { return map_domain_sid_to_name(&tmp_sid, dom_name) && - local_lookup_rid(rid, name, name_type); + local_lookup_sid(sid, name, name_type); } } -- cgit From c311d24ce32d2a8aa244f126bcec67ec03549727 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Jan 2002 08:45:58 +0000 Subject: A nice *big* change to the fundemental way we do things. Samba (ab)uses the returns from getpwnam() a lot - in particular it keeps them around for a long time - often past the next call... This adds a getpwnam_alloc and a getpwuid_alloc to the collection. These function as expected, returning a malloced structure that can be free()ed with passwd_free(&passwd). This patch also cuts down on the number of calls to getpwnam - mostly by taking advantage of the fact that the passdb interface is already case-insensiteve. With this patch most of the recursive cases have been removed (that I know of) and the problems are reduced further by not using the sys_ interface in the new code. This means that pointers to the cache won't be affected. (This is a tempoary HACK, I intend to kill the password cache entirly). The only change I'm a little worried about is the change to rpc_server/srv_samr_nt.c for private groups. In this case we are getting groups from the new group mapping DB. Do we still need to check for private groups? I've toned down the check to a case sensitve match with the new code, but we might be able to kill it entirly. I've also added a make_modifyable_passwd() function, that copies a passwd struct into the form that the old sys_getpw* code provided. As far as I can tell this is only actually used in the pass_check.c crazies, where I moved the final 'special case' for shadow passwords (out of _Get_Pwnam()). The matching case for getpwent() is dealt with already, in lib/util_getent.c Also included in here is a small change to register the [homes] share at vuid creation rather than just in one varient of the session setup. (This picks up the SPNEGO cases). The home directory is now stored on the vuid, and I am hoping this might provide a saner way to do %H substitions. TODO: Kill off remaining Get_Pwnam_Modify calls (they are not needed), change the remaining sys_getpwnam() callers to use getpwnam_alloc() and move Get_Pwnam to return an allocated struct. Andrew Bartlett (This used to be commit 1d86c7f94230bc53daebd4d2cd829da6292e05da) --- source3/smbd/uid.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 650d9270cb..8df08a0e72 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -31,26 +31,21 @@ extern struct current_user current_user; BOOL change_to_guest(void) { static struct passwd *pass=NULL; - static uid_t guest_uid = (uid_t)-1; - static gid_t guest_gid = (gid_t)-1; - static fstring guest_name; if (!pass) { - pass = sys_getpwnam(lp_guestaccount()); + /* Don't need to free() this as its stored in a static */ + pass = getpwnam_alloc(lp_guestaccount()); if (!pass) return(False); - guest_uid = pass->pw_uid; - guest_gid = pass->pw_gid; - fstrcpy(guest_name, pass->pw_name); } #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ - initgroups(guest_name, guest_gid); + initgroups(pass->pw_name, pass->pw_gid); #endif - set_sec_ctx(guest_uid, guest_gid, 0, NULL, NULL); + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; -- cgit From 93a8358910d2b8788ffea33c04244ffd5ffecabf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 01:24:59 +0000 Subject: This patch makes the 'winbind use default domain' code interact better with smbd, and also makes it much cleaner inside winbindd. It is mostly my code, with a few changes and testing performed by Alexander Bokovoy . ab has tested it in security=domain and security=ads, but more testing is always appricatiated. The idea is that we no longer cart around a 'domain\user' string, we keep them seperate until the last moment - when we push that string into a pwent on onto the socket. This removes the need to be constantly parsing that string - the domain prefix is almost always already provided, (only a couple of functions actually changed arguments in all this). Some consequential changes to the RPC client code, to stop it concatonating the two strings (it now passes them both back as params). I havn't changed the cache code, however the usernames will no longer have a double domain prefix in the key string. The actual structures are unchanged - but the meaning of 'username' in the 'rid' will have changed. (The cache is invalidated at startup, so on-disk formats are not an issue here). Andrew Bartlett (This used to be commit e870f0e727952aeb8599cf93ad2650ae56eca033) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8df08a0e72..d9cedaf7b5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -453,7 +453,7 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) /* If we are looking up a domain user, make sure it is for the local machine only */ - if (strchr_m(name, sep[0]) || strchr_m(name, '\\')) { + if (strchr_m(name, sep[0]) || strchr_m(name, '\\') || lp_winbind_use_default_domain()) { fstring domain, username; split_domain_name(name, domain, username); -- cgit From b1da5c02535ec61991d19cf09abaf366927ef34e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Jan 2002 10:05:10 +0000 Subject: Rework lookup_name() to take seperate username/domain args, and to remove varioius crazy 'if winbind didn't find it' cases. This makes winbind default domain support easier to intergrate with smbd. (This used to be commit 3e71521957d579f00249679de837490aca5ba92f) --- source3/smbd/uid.c | 55 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d9cedaf7b5..240b4d46bb 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -436,60 +436,52 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER Tries winbind first - then uses local lookup. *****************************************************************/ -BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; extern fstring global_myworkgroup; fstring sid; - char *sep = lp_winbind_separator(); - + *name_type = SID_NAME_UNKNOWN; - if (!winbind_lookup_name(name, psid, name_type) || (*name_type != SID_NAME_USER) ) { + if (!winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) { BOOL ret = False; - DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name)); + DEBUG(10, ("lookup_name: winbind lookup for [%s]\\[%s] failed - trying local\n", domain, name)); /* If we are looking up a domain user, make sure it is for the local machine only */ - - if (strchr_m(name, sep[0]) || strchr_m(name, '\\') || lp_winbind_use_default_domain()) { - fstring domain, username; - - split_domain_name(name, domain, username); - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - if (strequal(domain, global_myworkgroup)) { - fstrcpy(domain, global_myname); - ret = local_lookup_name(domain, username, psid, name_type); - } - /* No break is deliberate here. JRA. */ - default: - if (strcasecmp(global_myname, domain) != 0) { - DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); - ret = local_lookup_name(global_myname, username, psid, name_type); - } + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + if (strequal(domain, global_myworkgroup)) { + ret = local_lookup_name(name, psid, name_type); + } + /* No break is deliberate here. JRA. */ + default: + if (ret) { + } else if (strequal(global_myname, domain)) { + ret = local_lookup_name(name, psid, name_type); + } else { + DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); } - } else { - ret = local_lookup_name(global_myname, name, psid, name_type); } if (ret) { DEBUG(10, - ("lookup_name: (local) %s -> SID %s (type %u)\n", - name, sid_to_string(sid,psid), + ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid,psid), (unsigned int)*name_type )); } else { - DEBUG(10,("lookup name: (local) %s failed.\n", name)); + DEBUG(10,("lookup name: (local) [%s]\\[%s] failed.\n", domain, name)); } return ret; } - DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", - name, sid_to_string(sid, psid), + DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid, psid), (unsigned int)*name_type)); return True; } @@ -702,3 +694,4 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) return True; } + -- cgit From 59b17ff5970fd932a45ae45b4f0d4f1b2da12704 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Jan 2002 12:24:18 +0000 Subject: - Provide sid->name lookup support for non-unix accounts. - Rework the name -> sid lookup function to always try local lookup first (for local domain names) before trying winbind. This seems to eliminate my winbind feedback loop problems. (I don't use winbind for nsswitch, where there are almost certainly further issues). Andrew Bartlett (This used to be commit 25cadce67bc8effd4248ab993ae78e1d8511d994) --- source3/smbd/uid.c | 69 ++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 240b4d46bb..eb1756008f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -433,7 +433,7 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER /***************************************************************** *THE CANONICAL* convert name to SID function. - Tries winbind first - then uses local lookup. + Tries local lookup first - for local domains - then uses winbind. *****************************************************************/ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) @@ -441,54 +441,51 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N extern pstring global_myname; extern fstring global_myworkgroup; fstring sid; + BOOL ret = False; *name_type = SID_NAME_UNKNOWN; - if (!winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) { - BOOL ret = False; - - DEBUG(10, ("lookup_name: winbind lookup for [%s]\\[%s] failed - trying local\n", domain, name)); - - /* If we are looking up a domain user, make sure it is - for the local machine only */ - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - if (strequal(domain, global_myworkgroup)) { - ret = local_lookup_name(name, psid, name_type); - } - /* No break is deliberate here. JRA. */ - default: - if (ret) { - } else if (strequal(global_myname, domain)) { - ret = local_lookup_name(name, psid, name_type); - } else { - DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); - } + /* If we are looking up a domain user, make sure it is + for the local machine only */ + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + if (strequal(domain, global_myworkgroup)) { + ret = local_lookup_name(name, psid, name_type); } - + /* No break is deliberate here. JRA. */ + default: if (ret) { - DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid,psid), - (unsigned int)*name_type )); + } else if (strequal(global_myname, domain)) { + ret = local_lookup_name(name, psid, name_type); } else { - DEBUG(10,("lookup name: (local) [%s]\\[%s] failed.\n", domain, name)); + DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); } - - return ret; + } + + if (ret) { + DEBUG(10, + ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid,psid), + (unsigned int)*name_type )); + return True; + } else if (winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) { + + DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid, psid), + (unsigned int)*name_type)); + return True; } - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; + DEBUG(10, ("lookup_name: winbind and local lookups for [%s]\\[%s] failed\n", domain, name)); + + return False; } /***************************************************************** *THE CANONICAL* convert SID to name function. - Tries winbind first - then uses local lookup. + Tries local lookup first - for local sids, then tries winbind. *****************************************************************/ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index eb1756008f..3a939e4fce 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. uid/user handling Copyright (C) Andrew Tridgell 1992-1998 -- cgit From 276ff4df82313abcf09db2d373a4229a5b8db506 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Feb 2002 23:51:25 +0000 Subject: this allows us to support foreign SIDs in winbindd and smbd this means "xcopy /o" has a chance of working with ACLs that contain ACEs that use SIDs that the Samba server has no knowledge of. It's a bit hackish, Tim, can you look at my uid.c changes? (This used to be commit fe2db3148587937aa7b674c1c99036d42a3776b3) --- source3/smbd/uid.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3a939e4fce..f2b3bdbe6c 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -596,6 +596,11 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) *sidtype = SID_NAME_UNKNOWN; + +/* (tridge) I commented out the slab of code below in order to support foreign SIDs + Do we really need to validate the type of SID we have in this case? +*/ +#if 0 /* * First we must look up the name and decide if this is a user sid. */ @@ -616,7 +621,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) (unsigned int)name_type )); return False; } - +#endif *sidtype = SID_NAME_USER; /* @@ -658,7 +663,13 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - return local_sid_to_gid(pgid, psid, sidtype); + if (!local_sid_to_gid(pgid, psid, sidtype)) { + /* this was probably a foreign sid - assume its a group rid + and continue */ + name_type = SID_NAME_DOM_GRP; + } else { + return True; + } } /* -- cgit From 1d5fb7865d2a8441351668ea43b20a3b64ac232d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 5 Mar 2002 00:41:01 +0000 Subject: Fixed compiler warning about unused variables. (This used to be commit 7bb0dda8ee1d61a0e8448070f1a71fcd13be5d40) --- source3/smbd/uid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f2b3bdbe6c..c3156b7b14 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -591,16 +591,16 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - *sidtype = SID_NAME_UNKNOWN; - + fstring sid_str; /* (tridge) I commented out the slab of code below in order to support foreign SIDs Do we really need to validate the type of SID we have in this case? */ #if 0 + fstring dom_name, name; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; /* * First we must look up the name and decide if this is a user sid. */ -- cgit From 85d7e70d1fd5c69252310c22c60f9974cd392142 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Mar 2002 00:19:40 +0000 Subject: fixed mapping of SIDs for local users (This used to be commit df9e345366078ccaa94df7c2f2e33b292605e88a) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c3156b7b14..1946078d6e 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -631,7 +631,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) if (!winbind_sid_to_uid(puid, psid)) { DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", sid_to_string(sid_str, psid) )); - return False; + return local_sid_to_uid(puid, psid, sidtype); } DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", -- cgit From 8fe1df84e1dc83085bdc137629ca6c882c13c388 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Mar 2002 00:30:26 +0000 Subject: if we know that the SID is local then don't try via winbindd (This used to be commit 1a8f3ba3ab7717c481e3fb4f1ea8938461160d09) --- source3/smbd/uid.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 1946078d6e..864d3d6c66 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -593,6 +593,11 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { fstring sid_str; + /* if we know its local then don't try winbindd */ + if (sid_compare_domain(&global_sam_sid, psid) == 0) { + return local_sid_to_uid(puid, psid, sidtype); + } + /* (tridge) I commented out the slab of code below in order to support foreign SIDs Do we really need to validate the type of SID we have in this case? */ -- cgit From 4023a61892278c9e09acd035166a55ff2b3d4f30 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Apr 2002 10:18:46 +0000 Subject: merged the mangling test and passdb bugfixes into SAMBA_3_0 (This used to be commit 97eb3a121d33200ee7559b2413d6252efc04ebaf) --- source3/smbd/uid.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 864d3d6c66..ac0b535c13 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -546,9 +546,12 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) return psid; } } + + /* Make sure we report failure, (when psid == NULL) */ + become_root(); + psid = local_uid_to_sid(psid, uid); + unbecome_root(); - local_uid_to_sid(psid, uid); - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); return psid; @@ -611,10 +614,14 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) */ if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { + BOOL result; DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - return local_sid_to_uid(puid, psid, sidtype); + become_root(); + result = local_sid_to_uid(puid, psid, sidtype); + unbecome_root(); + return result; } /* @@ -634,9 +641,13 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) */ if (!winbind_sid_to_uid(puid, psid)) { + BOOL result; DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", sid_to_string(sid_str, psid) )); - return local_sid_to_uid(puid, psid, sidtype); + become_root(); + result = local_sid_to_uid(puid, psid, sidtype); + unbecome_root(); + return result; } DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", @@ -667,7 +678,6 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - if (!local_sid_to_gid(pgid, psid, sidtype)) { /* this was probably a foreign sid - assume its a group rid and continue */ -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/uid.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ac0b535c13..a18f62c9cc 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -465,11 +465,11 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N if (ret) { DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n", + ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", domain, name, sid_to_string(sid,psid), - (unsigned int)*name_type )); + sid_type_lookup(*name_type), (unsigned int)*name_type)); return True; - } else if (winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) { + } else if (winbind_lookup_name(domain, name, psid, name_type)) { DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", domain, name, sid_to_string(sid, psid), @@ -504,7 +504,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE sid_copy(&tmp_sid, sid); sid_split_rid(&tmp_sid, &rid); - if (sid_equal(&global_sam_sid, &tmp_sid)) { + if (sid_equal(get_global_sam_sid(), &tmp_sid)) { return map_domain_sid_to_name(&tmp_sid, dom_name) && local_lookup_sid(sid, name, name_type); @@ -521,7 +521,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE sid_copy(&tmp_sid, sid); sid_split_rid(&tmp_sid, &rid); return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_known_rid(&tmp_sid, rid, name, name_type); + lookup_known_rid(&tmp_sid, rid, name, name_type); } return True; } @@ -578,7 +578,8 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) } } - local_gid_to_sid(psid, gid); + /* Make sure we report failure, (when psid == NULL) */ + psid = local_gid_to_sid(psid, gid); DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); @@ -597,7 +598,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) fstring sid_str; /* if we know its local then don't try winbindd */ - if (sid_compare_domain(&global_sam_sid, psid) == 0) { + if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { return local_sid_to_uid(puid, psid, sidtype); } -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/uid.c | 86 +++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 39 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index a18f62c9cc..c0bacf8f91 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -440,44 +440,43 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N extern pstring global_myname; extern fstring global_myworkgroup; fstring sid; - BOOL ret = False; + BOOL local_lookup = False; *name_type = SID_NAME_UNKNOWN; /* If we are looking up a domain user, make sure it is for the local machine only */ - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: + if (strequal(global_myname, domain)) { + local_lookup = True; + } else if (lp_server_role() == ROLE_DOMAIN_PDC || + lp_server_role() == ROLE_DOMAIN_PDC) { if (strequal(domain, global_myworkgroup)) { - ret = local_lookup_name(name, psid, name_type); - } - /* No break is deliberate here. JRA. */ - default: - if (ret) { - } else if (strequal(global_myname, domain)) { - ret = local_lookup_name(name, psid, name_type); - } else { - DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); + local_lookup = True; } } - - if (ret) { - DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", - domain, name, sid_to_string(sid,psid), - sid_type_lookup(*name_type), (unsigned int)*name_type)); - return True; - } else if (winbind_lookup_name(domain, name, psid, name_type)) { - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; + if (local_lookup) { + if (local_lookup_name(name, psid, name_type)) { + DEBUG(10, + ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", + domain, name, sid_to_string(sid,psid), + sid_type_lookup(*name_type), (unsigned int)*name_type)); + return True; + } + } else { + /* Remote */ + if (winbind_lookup_name(domain, name, psid, name_type)) { + + DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", + domain, name, sid_to_string(sid, psid), + (unsigned int)*name_type)); + return True; + } } - - DEBUG(10, ("lookup_name: winbind and local lookups for [%s]\\[%s] failed\n", domain, name)); + + DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", + local_lookup ? "local" : "winbind", domain, name)); return False; } @@ -593,13 +592,17 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) was done correctly, False if not. sidtype is set by this function. *****************************************************************/ -BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { fstring sid_str; /* if we know its local then don't try winbindd */ if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - return local_sid_to_uid(puid, psid, sidtype); + BOOL result; + become_root(); + result = local_sid_to_uid(puid, psid, sidtype); + unbecome_root(); + return result; } /* (tridge) I commented out the slab of code below in order to support foreign SIDs @@ -665,7 +668,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) was done correctly, False if not. *****************************************************************/ -BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) { fstring dom_name, name, sid_str; enum SID_NAME_USE name_type; @@ -676,16 +679,21 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) * First we must look up the name and decide if this is a group sid. */ + /* if we know its local then don't try winbindd */ + if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { + BOOL result; + become_root(); + result = local_sid_to_gid(pgid, psid, sidtype); + unbecome_root(); + return result; + } + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", sid_to_string(sid_str, psid) )); - if (!local_sid_to_gid(pgid, psid, sidtype)) { - /* this was probably a foreign sid - assume its a group rid - and continue */ - name_type = SID_NAME_DOM_GRP; - } else { - return True; - } + /* this was probably a foreign sid - assume its a group rid + and continue */ + name_type = SID_NAME_DOM_GRP; } /* @@ -696,7 +704,7 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); - return local_sid_to_gid(pgid, psid, sidtype); + return False; } *sidtype = name_type; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/uid.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c0bacf8f91..2bda26aa51 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -59,18 +59,26 @@ BOOL change_to_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;iuid_cache.entries;i++) - if (conn->uid_cache.list[i] == vuser->uid) + for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) + if (conn->vuid_cache.list[i] == vuser->vuid) return(True); + if ((conn->force_user || conn->force_group) + && (conn->vuid != vuser->vuid)) { + return False; + } + if (!user_ok(vuser->user.unix_name,snum)) return(False); - i = conn->uid_cache.entries % UID_CACHE_SIZE; - conn->uid_cache.list[i] = vuser->uid; + if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { + return False; + } + + i = conn->vuid_cache.entries % VUID_CACHE_SIZE; + conn->vuid_cache.list[i] = vuser->vuid; - if (conn->uid_cache.entries < UID_CACHE_SIZE) - conn->uid_cache.entries++; + conn->vuid_cache.entries++; return(True); } @@ -115,27 +123,21 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); - if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) - return False; - - if (conn->force_user || - conn->admin_user || - (lp_security() == SEC_SHARE)) { + if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; token = conn->nt_user_token; - } else { - if (!vuser) { - DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid)); - return(False); - } + } else if ((vuser) && check_user_ok(conn, vuser, snum)) { uid = vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; token = vuser->nt_user_token; + } else { + DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid)); + return False; } /* @@ -175,7 +177,11 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + if (!token) { + DEBUG(1, ("change_to_user: create_nt_token failed!\n")); + return False; + } must_free_token = True; } -- cgit From f735551b9edef66b152261cf6eb2f29b7b69d65b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Oct 2002 01:22:32 +0000 Subject: First cut of new ACL mapping code from Andreas Gruenbacher . This is not 100% the same as what SuSE shipped in their Samba, there is a crash bug fix, a race condition fix, and a few logic changes I'd like to discuss with Andreas. Added Andreas to (C) notices for posix_acls.c Jeremy. (This used to be commit 40eafb9dde113af9f7f1808fda22908953f7e8c3) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2bda26aa51..9a38d6e9e2 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -456,7 +456,7 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N if (strequal(global_myname, domain)) { local_lookup = True; } else if (lp_server_role() == ROLE_DOMAIN_PDC || - lp_server_role() == ROLE_DOMAIN_PDC) { + lp_server_role() == ROLE_DOMAIN_BDC) { if (strequal(domain, global_myworkgroup)) { local_lookup = True; } -- cgit From 56dc17378b978f02f8397071021be5bf9a88b6a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 1 Nov 2002 22:17:19 +0000 Subject: Merges from HEAD: - off-by-one fix - fixes warnings about insufficent space in buffer. - fix a memleak in uid.c - we forgot to free() the allocated struct. (This used to be commit b8951a6551b352e4aac7e8b0ecf7fec3f2d9634e) --- source3/smbd/uid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9a38d6e9e2..48b9768358 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -49,6 +49,8 @@ BOOL change_to_guest(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; + passwd_free(&pass); + return True; } -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/smbd/uid.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 48b9768358..e2cc26e0ae 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -445,8 +445,6 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { - extern pstring global_myname; - extern fstring global_myworkgroup; fstring sid; BOOL local_lookup = False; @@ -455,11 +453,11 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N /* If we are looking up a domain user, make sure it is for the local machine only */ - if (strequal(global_myname, domain)) { + if (strequal(global_myname(), domain)) { local_lookup = True; } else if (lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_DOMAIN_BDC) { - if (strequal(domain, global_myworkgroup)) { + if (strequal(domain, lp_workgroup())) { local_lookup = True; } } -- cgit From 33eb26ba5e847db1585b234a6b2cbd8c54865426 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Feb 2003 23:51:08 +0000 Subject: Added code based on Michael Steffens uid/gid caching code. Reduces load on winbindd. Probably should be moved to use gencache at some future date. Jeremy. (This used to be commit f2674d1ac94fd5928754b8176cdd65eda50bf66e) --- source3/smbd/uid.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 205 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e2cc26e0ae..e7c00ba456 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -531,6 +531,183 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE return True; } +/***************************************************************** + Id mapping cache. This is to avoid Winbind mappings already + seen by smbd to be queried too frequently, keeping winbindd + busy, and blocking smbd while winbindd is busy with other + stuff. Written by Michael Steffens , + modified to use linked lists by jra. +*****************************************************************/ + +#define MAX_UID_SID_CACHE_SIZE 100 +#define TURNOVER_UID_SID_CACHE_SIZE 10 +#define MAX_GID_SID_CACHE_SIZE 100 +#define TURNOVER_GID_SID_CACHE_SIZE 10 + +static size_t n_uid_sid_cache = 0; +static size_t n_gid_sid_cache = 0; + +static struct uid_sid_cache { + struct uid_sid_cache *next, *prev; + uid_t uid; + DOM_SID sid; +} *uid_sid_cache_head; + +static struct gid_sid_cache { + struct gid_sid_cache *next, *prev; + gid_t gid; + DOM_SID sid; +} *gid_sid_cache_head; + +/***************************************************************** + Find a SID given a uid. +*****************************************************************/ + +static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) +{ + struct uid_sid_cache *pc; + + for (pc = uid_sid_cache_head; pc; pc = pc->next) { + if (pc->uid == uid) { + fstring sid; + *psid = pc->sid; + DEBUG(3,("fetch sid from uid cache %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid))); + DLIST_PROMOTE(uid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Find a uid given a SID. +*****************************************************************/ + +static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid) +{ + struct uid_sid_cache *pc; + + for (pc = uid_sid_cache_head; pc; pc = pc->next) { + if (sid_compare(&pc->sid, psid) == 0) { + fstring sid; + *puid = pc->uid; + DEBUG(3,("fetch uid from cache %u -> %s\n", + (unsigned int)*puid, sid_to_string(sid, psid))); + DLIST_PROMOTE(uid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Store uid to SID mapping in cache. +*****************************************************************/ + +static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) +{ + struct uid_sid_cache *pc; + + if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) { + /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */ + struct uid_sid_cache *pc_next; + size_t i; + + for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next) + ; + for(; pc; pc = pc_next) { + pc_next = pc->next; + DLIST_REMOVE(uid_sid_cache_head,pc); + SAFE_FREE(pc); + n_uid_sid_cache--; + } + } + + pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache)); + if (!pc) + return; + pc->uid = uid; + sid_copy(&pc->sid, psid); + DLIST_ADD(uid_sid_cache_head, pc); + n_uid_sid_cache++; +} + +/***************************************************************** + Find a SID given a gid. +*****************************************************************/ + +static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) +{ + struct gid_sid_cache *pc; + + for (pc = gid_sid_cache_head; pc; pc = pc->next) { + if (pc->gid == gid) { + fstring sid; + *psid = pc->sid; + DEBUG(3,("fetch sid from gid cache %u -> %s\n", + (unsigned int)gid, sid_to_string(sid, psid))); + DLIST_PROMOTE(gid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Find a gid given a SID. +*****************************************************************/ + +static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid) +{ + struct gid_sid_cache *pc; + + for (pc = gid_sid_cache_head; pc; pc = pc->next) { + if (sid_compare(&pc->sid, psid) == 0) { + fstring sid; + *pgid = pc->gid; + DEBUG(3,("fetch uid from cache %u -> %s\n", + (unsigned int)*pgid, sid_to_string(sid, psid))); + DLIST_PROMOTE(gid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Store gid to SID mapping in cache. +*****************************************************************/ + +static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) +{ + struct gid_sid_cache *pc; + + if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) { + /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */ + struct gid_sid_cache *pc_next; + size_t i; + + for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next) + ; + for(; pc; pc = pc_next) { + pc_next = pc->next; + DLIST_REMOVE(gid_sid_cache_head,pc); + SAFE_FREE(pc); + n_gid_sid_cache--; + } + } + + pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache)); + if (!pc) + return; + pc->gid = gid; + sid_copy(&pc->sid, psid); + DLIST_ADD(gid_sid_cache_head, pc); + n_gid_sid_cache++; +} + + /***************************************************************** *THE CANONICAL* convert uid_t to SID function. Tries winbind first - then uses local lookup. @@ -542,12 +719,17 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) uid_t low, high; fstring sid; + if (fetch_sid_from_uid_cache(psid, uid)) + return psid; + if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { if (winbind_uid_to_sid(psid, uid)) { DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); + if (psid) + store_uid_sid_cache(psid, uid); return psid; } } @@ -558,6 +740,8 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) unbecome_root(); DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); + if (psid) + store_uid_sid_cache(psid, uid); return psid; } @@ -573,20 +757,26 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) gid_t low, high; fstring sid; + if (fetch_sid_from_gid_cache(psid, gid)) + return psid; + if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { if (winbind_gid_to_sid(psid, gid)) { DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); + if (psid) + store_gid_sid_cache(psid, gid); return psid; } } /* Make sure we report failure, (when psid == NULL) */ psid = local_gid_to_sid(psid, gid); - DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); + if (psid) + store_gid_sid_cache(psid, gid); return psid; } @@ -602,12 +792,17 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { fstring sid_str; + if (fetch_uid_from_cache(puid, psid)) + return True; + /* if we know its local then don't try winbindd */ if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { BOOL result; become_root(); result = local_sid_to_uid(puid, psid, sidtype); unbecome_root(); + if (result) + store_uid_sid_cache(psid, *puid); return result; } @@ -657,6 +852,8 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) become_root(); result = local_sid_to_uid(puid, psid, sidtype); unbecome_root(); + if (result) + store_uid_sid_cache(psid, *puid); return result; } @@ -664,6 +861,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) sid_to_string(sid_str, psid), (unsigned int)*puid )); + store_uid_sid_cache(psid, *puid); return True; } @@ -681,6 +879,9 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) *sidtype = SID_NAME_UNKNOWN; + if (fetch_gid_from_cache(pgid, psid)) + return True; + /* * First we must look up the name and decide if this is a group sid. */ @@ -691,6 +892,8 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) become_root(); result = local_sid_to_gid(pgid, psid, sidtype); unbecome_root(); + if (result) + store_gid_sid_cache(psid, *pgid); return result; } @@ -729,6 +932,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) sid_to_string(sid_str, psid), (unsigned int)*pgid )); + store_gid_sid_cache(psid, *pgid); return True; } -- cgit From 3fd3bb38e24d39cae58894ce2b6bcb750b9de1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Feb 2003 22:31:05 +0000 Subject: Fix inspired by Stefan (metze) Metzmacher - cache the sidtype also. Jeremy. (This used to be commit efc92697801f5e62a89eda33e1826094c096900f) --- source3/smbd/uid.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e7c00ba456..7c0d3805e7 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -551,19 +551,21 @@ static struct uid_sid_cache { struct uid_sid_cache *next, *prev; uid_t uid; DOM_SID sid; + enum SID_NAME_USE sidtype; } *uid_sid_cache_head; static struct gid_sid_cache { struct gid_sid_cache *next, *prev; gid_t gid; DOM_SID sid; + enum SID_NAME_USE sidtype; } *gid_sid_cache_head; /***************************************************************** Find a SID given a uid. *****************************************************************/ -static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) +static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, uid_t uid) { struct uid_sid_cache *pc; @@ -571,6 +573,7 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) if (pc->uid == uid) { fstring sid; *psid = pc->sid; + *psidtype = pc->sidtype; DEBUG(3,("fetch sid from uid cache %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); DLIST_PROMOTE(uid_sid_cache_head, pc); @@ -584,7 +587,7 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) Find a uid given a SID. *****************************************************************/ -static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid) +static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE sidtype) { struct uid_sid_cache *pc; @@ -605,7 +608,7 @@ static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid) Store uid to SID mapping in cache. *****************************************************************/ -static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) +static void store_uid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, uid_t uid) { struct uid_sid_cache *pc; @@ -629,6 +632,7 @@ static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) return; pc->uid = uid; sid_copy(&pc->sid, psid); + pc->sidtype = sidtype; DLIST_ADD(uid_sid_cache_head, pc); n_uid_sid_cache++; } @@ -637,7 +641,7 @@ static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) Find a SID given a gid. *****************************************************************/ -static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) +static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, gid_t gid) { struct gid_sid_cache *pc; @@ -645,6 +649,7 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) if (pc->gid == gid) { fstring sid; *psid = pc->sid; + *psidtype = pc->sidtype; DEBUG(3,("fetch sid from gid cache %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); DLIST_PROMOTE(gid_sid_cache_head, pc); @@ -658,7 +663,7 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) Find a gid given a SID. *****************************************************************/ -static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid) +static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE sidtype) { struct gid_sid_cache *pc; @@ -679,7 +684,7 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid) Store gid to SID mapping in cache. *****************************************************************/ -static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) +static void store_gid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, gid_t gid) { struct gid_sid_cache *pc; @@ -703,6 +708,7 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) return; pc->gid = gid; sid_copy(&pc->sid, psid); + pc->sidtype = sidtype; DLIST_ADD(gid_sid_cache_head, pc); n_gid_sid_cache++; } @@ -717,9 +723,10 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) { uid_t low, high; + enum SID_NAME_USE sidtype; fstring sid; - if (fetch_sid_from_uid_cache(psid, uid)) + if (fetch_sid_from_uid_cache(psid, &sidtype, uid)) return psid; if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { @@ -729,7 +736,7 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) (unsigned int)uid, sid_to_string(sid, psid))); if (psid) - store_uid_sid_cache(psid, uid); + store_uid_sid_cache(psid, SID_NAME_USER, uid); return psid; } } @@ -741,7 +748,7 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); if (psid) - store_uid_sid_cache(psid, uid); + store_uid_sid_cache(psid, SID_NAME_USER, uid); return psid; } @@ -755,9 +762,10 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) { gid_t low, high; + enum SID_NAME_USE sidtype; fstring sid; - if (fetch_sid_from_gid_cache(psid, gid)) + if (fetch_sid_from_gid_cache(psid, &sidtype, gid)) return psid; if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { @@ -767,7 +775,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) (unsigned int)gid, sid_to_string(sid, psid))); if (psid) - store_gid_sid_cache(psid, gid); + store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); return psid; } } @@ -776,7 +784,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) psid = local_gid_to_sid(psid, gid); DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); if (psid) - store_gid_sid_cache(psid, gid); + store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); return psid; } @@ -792,7 +800,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { fstring sid_str; - if (fetch_uid_from_cache(puid, psid)) + if (fetch_uid_from_cache(puid, psid, *sidtype)) return True; /* if we know its local then don't try winbindd */ @@ -802,7 +810,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) result = local_sid_to_uid(puid, psid, sidtype); unbecome_root(); if (result) - store_uid_sid_cache(psid, *puid); + store_uid_sid_cache(psid, *sidtype, *puid); return result; } @@ -853,7 +861,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) result = local_sid_to_uid(puid, psid, sidtype); unbecome_root(); if (result) - store_uid_sid_cache(psid, *puid); + store_uid_sid_cache(psid, *sidtype, *puid); return result; } @@ -861,7 +869,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) sid_to_string(sid_str, psid), (unsigned int)*puid )); - store_uid_sid_cache(psid, *puid); + store_uid_sid_cache(psid, *sidtype, *puid); return True; } @@ -879,7 +887,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) *sidtype = SID_NAME_UNKNOWN; - if (fetch_gid_from_cache(pgid, psid)) + if (fetch_gid_from_cache(pgid, psid, *sidtype)) return True; /* @@ -893,7 +901,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) result = local_sid_to_gid(pgid, psid, sidtype); unbecome_root(); if (result) - store_gid_sid_cache(psid, *pgid); + store_gid_sid_cache(psid, *sidtype, *pgid); return result; } @@ -932,7 +940,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) sid_to_string(sid_str, psid), (unsigned int)*pgid )); - store_gid_sid_cache(psid, *pgid); + store_gid_sid_cache(psid, *sidtype, *pgid); return True; } -- cgit From e72ecdc862804339912325fe848401e8ec57cde7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:35:54 +0000 Subject: Merge of server-side authentication changes to 3.0: - user_ok() and user_in_group() now take a list of groups, instead of looking for the user in the members of all groups. - The 'server_info' returned from the authentication is now kept around - in future we won't copy the sesion key, username etc, we will just referece them directly. - rhosts upgraded to use the SAM if possible, otherwise fake up based on getpwnam(). - auth_util code to deal with groups upgraded to deal with non-winbind domain members again. Andrew Bartlett (This used to be commit 74b5436c75114170ce7c780c19226103d0df9060) --- source3/smbd/uid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7c0d3805e7..6ac3528b1a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -60,7 +60,7 @@ BOOL change_to_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { - int i; + unsigned i; for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) if (conn->vuid_cache.list[i] == vuser->vuid) return(True); @@ -70,7 +70,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return False; } - if (!user_ok(vuser->user.unix_name,snum)) + if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups)) return(False); if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { -- cgit From 560d83be393eadaa885f03ce17286c897913897f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Mar 2003 22:01:22 +0000 Subject: pdb_ldap may require ROOT privilages to access the group mapping. (yes, it's ugly :-) Andrew Bartlett (This used to be commit 12579a62945d0d475b53c4ab49761a01be9e8394) --- source3/smbd/uid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 6ac3528b1a..b9cf0de3bd 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -781,7 +781,9 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) } /* Make sure we report failure, (when psid == NULL) */ + become_root(); psid = local_gid_to_sid(psid, gid); + unbecome_root(); DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); if (psid) store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); -- cgit From c823b191ab476fc2583d6d6aaa1e2edb09cbb88e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 12 May 2003 18:12:31 +0000 Subject: And finally IDMAP in 3_0 We really need idmap_ldap to have a good solution with ldapsam, porting it from the prvious code is beeing made, the code is really simple to do so I am confident it is not a problem to commit this code in. Not committing it would have been worst. I really would have been able to finish also the group code, maybe we can put it into a followin release after 3.0.0 even if it may be an upgrade problem. The code has been tested and seem to work right, more testing is needed for corner cases. Currently winbind pdc (working only for users and not for groups) is disabled as I was not able to make a complete group code replacement that works somewhat in a week (I have a complete patch, but there are bugs) Simo. (This used to be commit 0e58085978f984436815114a2ec347cf7899a89d) --- source3/smbd/uid.c | 419 +---------------------------------------------------- 1 file changed, 1 insertion(+), 418 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b9cf0de3bd..c68d00025c 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -405,10 +405,9 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t)); for (i = 0; i < ptok->num_sids; i++) { - enum SID_NAME_USE sid_type; gid_t new_grp; - if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) { + if (NT_STATUS_IS_OK(sid_to_gid(&ptok->user_sids[i], &new_grp))) { /* * Don't add the gid_t if it is already in the current group * list. Some UNIXen don't like the same group more than once. @@ -530,419 +529,3 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE } return True; } - -/***************************************************************** - Id mapping cache. This is to avoid Winbind mappings already - seen by smbd to be queried too frequently, keeping winbindd - busy, and blocking smbd while winbindd is busy with other - stuff. Written by Michael Steffens , - modified to use linked lists by jra. -*****************************************************************/ - -#define MAX_UID_SID_CACHE_SIZE 100 -#define TURNOVER_UID_SID_CACHE_SIZE 10 -#define MAX_GID_SID_CACHE_SIZE 100 -#define TURNOVER_GID_SID_CACHE_SIZE 10 - -static size_t n_uid_sid_cache = 0; -static size_t n_gid_sid_cache = 0; - -static struct uid_sid_cache { - struct uid_sid_cache *next, *prev; - uid_t uid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *uid_sid_cache_head; - -static struct gid_sid_cache { - struct gid_sid_cache *next, *prev; - gid_t gid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *gid_sid_cache_head; - -/***************************************************************** - Find a SID given a uid. -*****************************************************************/ - -static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, uid_t uid) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (pc->uid == uid) { - fstring sid; - *psid = pc->sid; - *psidtype = pc->sidtype; - DEBUG(3,("fetch sid from uid cache %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a uid given a SID. -*****************************************************************/ - -static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE sidtype) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *puid = pc->uid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*puid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store uid to SID mapping in cache. -*****************************************************************/ - -static void store_uid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, uid_t uid) -{ - struct uid_sid_cache *pc; - - if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */ - struct uid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(uid_sid_cache_head,pc); - SAFE_FREE(pc); - n_uid_sid_cache--; - } - } - - pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache)); - if (!pc) - return; - pc->uid = uid; - sid_copy(&pc->sid, psid); - pc->sidtype = sidtype; - DLIST_ADD(uid_sid_cache_head, pc); - n_uid_sid_cache++; -} - -/***************************************************************** - Find a SID given a gid. -*****************************************************************/ - -static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, gid_t gid) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (pc->gid == gid) { - fstring sid; - *psid = pc->sid; - *psidtype = pc->sidtype; - DEBUG(3,("fetch sid from gid cache %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a gid given a SID. -*****************************************************************/ - -static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE sidtype) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *pgid = pc->gid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*pgid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store gid to SID mapping in cache. -*****************************************************************/ - -static void store_gid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, gid_t gid) -{ - struct gid_sid_cache *pc; - - if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */ - struct gid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(gid_sid_cache_head,pc); - SAFE_FREE(pc); - n_gid_sid_cache--; - } - } - - pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache)); - if (!pc) - return; - pc->gid = gid; - sid_copy(&pc->sid, psid); - pc->sidtype = sidtype; - DLIST_ADD(gid_sid_cache_head, pc); - n_gid_sid_cache++; -} - - -/***************************************************************** - *THE CANONICAL* convert uid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ - -DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) -{ - uid_t low, high; - enum SID_NAME_USE sidtype; - fstring sid; - - if (fetch_sid_from_uid_cache(psid, &sidtype, uid)) - return psid; - - if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { - if (winbind_uid_to_sid(psid, uid)) { - - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - - if (psid) - store_uid_sid_cache(psid, SID_NAME_USER, uid); - return psid; - } - } - - /* Make sure we report failure, (when psid == NULL) */ - become_root(); - psid = local_uid_to_sid(psid, uid); - unbecome_root(); - - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); - if (psid) - store_uid_sid_cache(psid, SID_NAME_USER, uid); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert gid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ - -DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) -{ - gid_t low, high; - enum SID_NAME_USE sidtype; - fstring sid; - - if (fetch_sid_from_gid_cache(psid, &sidtype, gid)) - return psid; - - if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { - if (winbind_gid_to_sid(psid, gid)) { - - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - - if (psid) - store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); - return psid; - } - } - - /* Make sure we report failure, (when psid == NULL) */ - become_root(); - psid = local_gid_to_sid(psid, gid); - unbecome_root(); - DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); - if (psid) - store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert SID to uid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. sidtype is set by this function. -*****************************************************************/ - -BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) -{ - fstring sid_str; - - if (fetch_uid_from_cache(puid, psid, *sidtype)) - return True; - - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - if (result) - store_uid_sid_cache(psid, *sidtype, *puid); - return result; - } - -/* (tridge) I commented out the slab of code below in order to support foreign SIDs - Do we really need to validate the type of SID we have in this case? -*/ -#if 0 - fstring dom_name, name; - enum SID_NAME_USE name_type; - - *sidtype = SID_NAME_UNKNOWN; - /* - * First we must look up the name and decide if this is a user sid. - */ - - if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { - BOOL result; - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - return result; - } - - /* - * Ensure this is a user sid. - */ - - if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", - (unsigned int)name_type )); - return False; - } -#endif - *sidtype = SID_NAME_USER; - - /* - * Get the uid for this SID. - */ - - if (!winbind_sid_to_uid(puid, psid)) { - BOOL result; - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - if (result) - store_uid_sid_cache(psid, *sidtype, *puid); - return result; - } - - DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*puid )); - - store_uid_sid_cache(psid, *sidtype, *puid); - return True; -} - -/***************************************************************** - *THE CANONICAL* convert SID to gid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. -*****************************************************************/ - -BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - *sidtype = SID_NAME_UNKNOWN; - - if (fetch_gid_from_cache(pgid, psid, *sidtype)) - return True; - - /* - * First we must look up the name and decide if this is a group sid. - */ - - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_gid(pgid, psid, sidtype); - unbecome_root(); - if (result) - store_gid_sid_cache(psid, *sidtype, *pgid); - return result; - } - - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - /* this was probably a foreign sid - assume its a group rid - and continue */ - name_type = SID_NAME_DOM_GRP; - } - - /* - * Ensure this is a group sid. - */ - - if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { - DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", - (unsigned int)name_type )); - - return False; - } - - *sidtype = name_type; - - /* - * Get the gid for this SID. - */ - - if (!winbind_sid_to_gid(pgid, psid)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - return False; - } - - DEBUG(10,("sid_to_gid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*pgid )); - - store_gid_sid_cache(psid, *sidtype, *pgid); - return True; -} - -- cgit From 0b18acb841f6a372b3aa285d4734875e5e35fe3b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 7 Jul 2003 05:11:10 +0000 Subject: and so it begins.... * remove idmap_XX_to_XX calls from smbd. Move back to the the winbind_XXX and local_XXX calls used in 2.2 * all uid/gid allocation must involve winbindd now * move flags field around in winbindd_request struct * add WBFLAG_QUERY_ONLY option to winbindd_sid_to_[ug]id() to prevent automatic allocation for unknown SIDs * add 'winbind trusted domains only' parameter to force a domain member server to use matching users names from /etc/passwd for its domain (needed for domain member of a Samba domain) * rename 'idmap only' to 'enable rid algorithm' for better clarity (defaults to "yes") code has been tested on * domain member of native mode 2k domain * ads domain member of native mode 2k domain * domain member of NT4 domain * domain member of Samba domain * Samba PDC running winbindd with trusts Logons tested using 2k clients and smbclient as domain users and trusted users. Tested both 'winbind trusted domains only = [yes|no]' This will be a long week of changes. The next item on the list is winbindd_passdb.c & machine trust accounts not in /etc/passwd (done via winbindd_passdb) (This used to be commit 8266dffab4aedba12a33289ff32880037ce950a8) --- source3/smbd/uid.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c68d00025c..04ff0faa28 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -529,3 +529,411 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE } return True; } + + +/***************************************************************** + Id mapping cache. This is to avoid Winbind mappings already + seen by smbd to be queried too frequently, keeping winbindd + busy, and blocking smbd while winbindd is busy with other + stuff. Written by Michael Steffens , + modified to use linked lists by jra. +*****************************************************************/ + +#define MAX_UID_SID_CACHE_SIZE 100 +#define TURNOVER_UID_SID_CACHE_SIZE 10 +#define MAX_GID_SID_CACHE_SIZE 100 +#define TURNOVER_GID_SID_CACHE_SIZE 10 + +static size_t n_uid_sid_cache = 0; +static size_t n_gid_sid_cache = 0; + +static struct uid_sid_cache { + struct uid_sid_cache *next, *prev; + uid_t uid; + DOM_SID sid; + enum SID_NAME_USE sidtype; +} *uid_sid_cache_head; + +static struct gid_sid_cache { + struct gid_sid_cache *next, *prev; + gid_t gid; + DOM_SID sid; + enum SID_NAME_USE sidtype; +} *gid_sid_cache_head; + +/***************************************************************** + Find a SID given a uid. +*****************************************************************/ + +static BOOL fetch_sid_from_uid_cache(const DOM_SID *psid, uid_t uid) +{ + struct uid_sid_cache *pc; + + for (pc = uid_sid_cache_head; pc; pc = pc->next) { + if (pc->uid == uid) { + fstring sid; + *psid = pc->sid; + DEBUG(3,("fetch sid from uid cache %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid))); + DLIST_PROMOTE(uid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Find a uid given a SID. +*****************************************************************/ + +static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid ) +{ + struct uid_sid_cache *pc; + + for (pc = uid_sid_cache_head; pc; pc = pc->next) { + if (sid_compare(&pc->sid, psid) == 0) { + fstring sid; + *puid = pc->uid; + DEBUG(3,("fetch uid from cache %u -> %s\n", + (unsigned int)*puid, sid_to_string(sid, psid))); + DLIST_PROMOTE(uid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Store uid to SID mapping in cache. +*****************************************************************/ + +static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) +{ + struct uid_sid_cache *pc; + + if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) { + /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */ + struct uid_sid_cache *pc_next; + size_t i; + + for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next) + ; + for(; pc; pc = pc_next) { + pc_next = pc->next; + DLIST_REMOVE(uid_sid_cache_head,pc); + SAFE_FREE(pc); + n_uid_sid_cache--; + } + } + + pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache)); + if (!pc) + return; + pc->uid = uid; + sid_copy(&pc->sid, psid); + DLIST_ADD(uid_sid_cache_head, pc); + n_uid_sid_cache++; +} + +/***************************************************************** + Find a SID given a gid. +*****************************************************************/ + +static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) +{ + struct gid_sid_cache *pc; + + for (pc = gid_sid_cache_head; pc; pc = pc->next) { + if (pc->gid == gid) { + fstring sid; + *psid = pc->sid; + DEBUG(3,("fetch sid from gid cache %u -> %s\n", + (unsigned int)gid, sid_to_string(sid, psid))); + DLIST_PROMOTE(gid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Find a gid given a SID. +*****************************************************************/ + +static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid) +{ + struct gid_sid_cache *pc; + + for (pc = gid_sid_cache_head; pc; pc = pc->next) { + if (sid_compare(&pc->sid, psid) == 0) { + fstring sid; + *pgid = pc->gid; + DEBUG(3,("fetch uid from cache %u -> %s\n", + (unsigned int)*pgid, sid_to_string(sid, psid))); + DLIST_PROMOTE(gid_sid_cache_head, pc); + return True; + } + } + return False; +} + +/***************************************************************** + Store gid to SID mapping in cache. +*****************************************************************/ + +static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) +{ + struct gid_sid_cache *pc; + + if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) { + /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */ + struct gid_sid_cache *pc_next; + size_t i; + + for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next) + ; + for(; pc; pc = pc_next) { + pc_next = pc->next; + DLIST_REMOVE(gid_sid_cache_head,pc); + SAFE_FREE(pc); + n_gid_sid_cache--; + } + } + + pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache)); + if (!pc) + return; + pc->gid = gid; + sid_copy(&pc->sid, psid); + DLIST_ADD(gid_sid_cache_head, pc); + n_gid_sid_cache++; +} + +/***************************************************************** + *THE CANONICAL* convert uid_t to SID function. + check idmap if uid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs + Returns SID pointer. +*****************************************************************/ + +NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) +{ + uid_t low, high; + fstring sid; + + if (fetch_sid_from_uid_cache(psid, uid)) + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + + if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) { + if (winbind_uid_to_sid(psid, uid)) { + + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid))); + + if (psid) + store_uid_sid_cache(psid, uid); + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + } + } + + local_uid_to_sid(psid, uid); + + DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); + + if (psid) + store_uid_sid_cache(psid, uid); + + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); +} + +/***************************************************************** + *THE CANONICAL* convert gid_t to SID function. + check idmap if gid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs + Returns SID pointer. +*****************************************************************/ + +NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) +{ + gid_t low, high; + fstring sid; + + if (fetch_sid_from_gid_cache(psid, gid)) + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + + if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) { + if (winbind_gid_to_sid(psid, gid)) { + + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, sid_to_string(sid, psid))); + + if (psid) + store_gid_sid_cache(psid, gid); + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + } + } + + local_gid_to_sid(psid, gid); + + DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); + + if (psid) + store_gid_sid_cache(psid, gid); + + return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); +} + +/***************************************************************** + *THE CANONICAL* convert SID to uid function. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + BOOL ret; + + if (fetch_uid_from_cache(puid, psid)) + return NT_STATUS_OK; + + /* + * First we must look up the name and decide if this is a user sid. + */ + + if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + ret = local_sid_to_uid(puid, psid, &name_type); + if (ret) + store_uid_sid_cache(psid, *puid); + return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + } + + /* + * Ensure this is a user sid. + */ + + if (name_type != SID_NAME_USER) { + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + (unsigned int)name_type )); + return NT_STATUS_INVALID_PARAMETER; + } + + /* query only first */ + + if ( !winbind_sid_to_uid_query(puid, psid) ) + { + DEBUG(10,("sid_to_uid: winbind query for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + + /* see if we have a local mapping */ + + if ( local_sid_to_uid(puid, psid, &name_type) ) { + store_uid_sid_cache(psid, *puid); + return NT_STATUS_OK; + } + + /* Call back to winbind to allocate a new uid */ + + if ( !winbind_sid_to_uid(puid, psid) ) { + DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n", + sid_to_string(sid_str, psid) )); + return NT_STATUS_UNSUCCESSFUL; + } + } + + DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid), + (unsigned int)*puid )); + + store_uid_sid_cache(psid, *puid); + + return NT_STATUS_OK; +} +/***************************************************************** + *THE CANONICAL* convert SID to gid function. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + BOOL ret; + + if (fetch_gid_from_cache(pgid, psid)) + return NT_STATUS_OK; + + /* + * First we must look up the name and decide if this is a group sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + ret = local_sid_to_gid(pgid, psid, &name_type); + if (ret) + store_gid_sid_cache(psid, *pgid); + + return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + } + + /* + * Ensure this is a group sid. + */ + + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", + (unsigned int)name_type )); + + ret = local_sid_to_gid(pgid, psid, &name_type); + if (ret) + store_gid_sid_cache(psid, *pgid); + return (ret ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER); + } + + /* query only first */ + + if ( !winbind_sid_to_gid_query(pgid, psid) ) + { + DEBUG(10,("sid_to_gid: winbind query for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + + /* see if we have a local mapping */ + + if ( local_sid_to_gid(pgid, psid, &name_type) ) { + store_gid_sid_cache(psid, *pgid); + return NT_STATUS_OK; + } + + /* Call back to winbind to allocate a new uid */ + + if ( !winbind_sid_to_gid(pgid, psid) ) { + DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n", + sid_to_string(sid_str, psid) )); + return NT_STATUS_UNSUCCESSFUL; + } + else + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid), + (unsigned int)*pgid )); + + store_gid_sid_cache(psid, *pgid); + + return NT_STATUS_OK; +} + -- cgit From 436555aaa7fc1ba7459d25c2514c847cd127b13b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 7 Jul 2003 17:04:48 +0000 Subject: Fixed a couple of const issues with the new code. Jeremy. (This used to be commit e9fb6e45086a6170b6f6d5d3295398708ab1af58) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 04ff0faa28..6d67a63ccd 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -565,7 +565,7 @@ static struct gid_sid_cache { Find a SID given a uid. *****************************************************************/ -static BOOL fetch_sid_from_uid_cache(const DOM_SID *psid, uid_t uid) +static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) { struct uid_sid_cache *pc; -- cgit From 4f0b771af0b1d0ccbe8a4a6009c382a27661ad7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Jul 2003 00:01:40 +0000 Subject: Ensure we correctly test for errors in uid/gid_to sid. Jeremy. (This used to be commit f3c2e73a8c1c592d407542c12c0a445103415bc0) --- source3/smbd/uid.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 6d67a63ccd..320f8eb980 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -737,14 +737,15 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) } } - local_uid_to_sid(psid, uid); + if (!local_uid_to_sid(psid, uid)) { + DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid )); + return NT_STATUS_UNSUCCESSFUL; + } DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); - if (psid) - store_uid_sid_cache(psid, uid); - - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + store_uid_sid_cache(psid, uid); + return NT_STATUS_OK; } /***************************************************************** @@ -775,14 +776,15 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) } } - local_gid_to_sid(psid, gid); + if (!local_gid_to_sid(psid, gid)) { + DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid )); + return NT_STATUS_UNSUCCESSFUL; + } DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); - if (psid) - store_gid_sid_cache(psid, gid); - - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); + store_gid_sid_cache(psid, gid); + return NT_STATUS_OK; } /***************************************************************** @@ -829,8 +831,7 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) /* query only first */ - if ( !winbind_sid_to_uid_query(puid, psid) ) - { + if ( !winbind_sid_to_uid_query(puid, psid) ) { DEBUG(10,("sid_to_uid: winbind query for sid %s failed.\n", sid_to_string(sid_str, psid) )); @@ -906,8 +907,7 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) /* query only first */ - if ( !winbind_sid_to_gid_query(pgid, psid) ) - { + if ( !winbind_sid_to_gid_query(pgid, psid) ) { DEBUG(10,("sid_to_gid: winbind query for sid %s failed.\n", sid_to_string(sid_str, psid) )); @@ -936,4 +936,3 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) return NT_STATUS_OK; } - -- cgit From 4072006fecf56bebf113fe1d4566156c0d89bacc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Jul 2003 00:23:42 +0000 Subject: Get rid of DISP_USER_INFO/DISP_GROUP_INFO as they serve no useful purpose. Replace with an array of SAM_ACCOUNT/DOMAIN_GRP entries. ZERO struct's in smbd/uid.c stops core dumps when sid_to_XX functions fail. Getting ready to add caching. Jeremy. (This used to be commit 9d0692a54fe2cb087f25796ec2ab5e1d8433e388) --- source3/smbd/uid.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 320f8eb980..6ca2aa336d 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -722,6 +722,8 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) uid_t low, high; fstring sid; + ZERO_STRUCTP(psid); + if (fetch_sid_from_uid_cache(psid, uid)) return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); @@ -761,6 +763,8 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) gid_t low, high; fstring sid; + ZERO_STRUCTP(psid); + if (fetch_sid_from_gid_cache(psid, gid)) return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); -- cgit From 16ff7b26f6b9d288cbd1d39e075b637e24da13a6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 9 Jul 2003 16:44:47 +0000 Subject: Large set of changes to add UNIX account/group management to winbindd. See README.idmap-and-winbind-changes for details. (This used to be commit 1111bc7b0c7165e1cdf8d90eb49f4c368d2eded6) --- source3/smbd/uid.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 6ca2aa336d..8d8ce136a9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -809,17 +809,28 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) if (fetch_uid_from_cache(puid, psid)) return NT_STATUS_OK; - /* - * First we must look up the name and decide if this is a user sid. - */ + /* if this is our DIS then go straight to a local lookup */ + + if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) { + DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n", + sid_string_static(psid) )); + + if ( (ret = local_sid_to_uid(puid, psid, &name_type)) == True ) + store_uid_sid_cache(psid, *puid); + + return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + } + + + /* look up the name and decide if this is a user sid */ if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); + sid_string_static(psid) )); - ret = local_sid_to_uid(puid, psid, &name_type); - if (ret) + if ( (ret = local_sid_to_uid(puid, psid, &name_type)) == True ) store_uid_sid_cache(psid, *puid); + return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); } -- cgit From 733f767b9465c53822af99bb0cc761ba745c96b6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Jul 2003 16:37:23 +0000 Subject: fix sid_to_[uid|gid] (spotted by Volker). Still testing this, but I'm checking it in so Volker can test it as well. Should be right. (This used to be commit 8edf193722f699cc33baed410917a78a5e28d0a4) --- source3/smbd/uid.c | 124 ++++++++++++++++------------------------------------- 1 file changed, 37 insertions(+), 87 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8d8ce136a9..8d3e7cd9be 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -711,10 +711,6 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) /***************************************************************** *THE CANONICAL* convert uid_t to SID function. - check idmap if uid is in idmap range, otherwise falls back to - the legacy algorithmic mapping. - A special cache is used for uids that maps to Wellknown SIDs - Returns SID pointer. *****************************************************************/ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) @@ -752,10 +748,6 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) /***************************************************************** *THE CANONICAL* convert gid_t to SID function. - check idmap if gid is in idmap range, otherwise falls back to - the legacy algorithmic mapping. - Group mapping is used for gids that maps to Wellknown SIDs - Returns SID pointer. *****************************************************************/ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) @@ -793,79 +785,56 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) /***************************************************************** *THE CANONICAL* convert SID to uid function. - if it is a foreign sid or it is in idmap rid range check idmap, - otherwise falls back to the legacy algorithmic mapping. - A special cache is used for uids that maps to Wellknown SIDs - Returns True if this name is a user sid and the conversion - was done correctly, False if not. *****************************************************************/ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) { fstring dom_name, name, sid_str; enum SID_NAME_USE name_type; - BOOL ret; if (fetch_uid_from_cache(puid, psid)) return NT_STATUS_OK; - /* if this is our DIS then go straight to a local lookup */ + /* if this is our SID then go straight to a local lookup */ if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) { DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n", sid_string_static(psid) )); - if ( (ret = local_sid_to_uid(puid, psid, &name_type)) == True ) - store_uid_sid_cache(psid, *puid); + if ( local_sid_to_uid(puid, psid, &name_type) ) + goto success; + + DEBUG(10,("sid_to_uid: local lookup failed\n")); - return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + return NT_STATUS_UNSUCCESSFUL; } + /* If it is not our local domain, only hope is winbindd */ - /* look up the name and decide if this is a user sid */ - - if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", + if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) { + DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n", sid_string_static(psid) )); - - if ( (ret = local_sid_to_uid(puid, psid, &name_type)) == True ) - store_uid_sid_cache(psid, *puid); - - return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + + return NT_STATUS_UNSUCCESSFUL; } - /* - * Ensure this is a user sid. - */ + /* If winbindd does know the SID, ensure this is a user */ if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n", (unsigned int)name_type )); return NT_STATUS_INVALID_PARAMETER; } - /* query only first */ - - if ( !winbind_sid_to_uid_query(puid, psid) ) { - DEBUG(10,("sid_to_uid: winbind query for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - - /* see if we have a local mapping */ - - if ( local_sid_to_uid(puid, psid, &name_type) ) { - store_uid_sid_cache(psid, *puid); - return NT_STATUS_OK; - } - - /* Call back to winbind to allocate a new uid */ + /* get the uid. Has to work or else we are dead in the water */ - if ( !winbind_sid_to_uid(puid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } + if ( !winbind_sid_to_uid(puid, psid) ) { + DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n", + sid_to_string(sid_str, psid) )); + return NT_STATUS_UNSUCCESSFUL; } +success: DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid), (unsigned int)*puid )); @@ -875,75 +844,56 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) } /***************************************************************** *THE CANONICAL* convert SID to gid function. - if it is a foreign sid or it is in idmap rid range check idmap, - otherwise falls back to the legacy algorithmic mapping. Group mapping is used for gids that maps to Wellknown SIDs - Returns True if this name is a user sid and the conversion - was done correctly, False if not. *****************************************************************/ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) { fstring dom_name, name, sid_str; enum SID_NAME_USE name_type; - BOOL ret; if (fetch_gid_from_cache(pgid, psid)) return NT_STATUS_OK; /* * First we must look up the name and decide if this is a group sid. + * Group mapping can deal with foreign SIDs */ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - ret = local_sid_to_gid(pgid, psid, &name_type); - if (ret) - store_gid_sid_cache(psid, *pgid); + if ( local_sid_to_gid(pgid, psid, &name_type) ) + goto success; - return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL); + DEBUG(10,("sid_to_gid: no one knows this SID\n")); + + return NT_STATUS_UNSUCCESSFUL; } - /* - * Ensure this is a group sid. - */ + /* winbindd knows it; Ensure this is a group sid */ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); - ret = local_sid_to_gid(pgid, psid, &name_type); - if (ret) - store_gid_sid_cache(psid, *pgid); - return (ret ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER); + /* winbindd is running and knows about this SID. Just the wrong type. + Don't fallback to a local lookup here */ + + return NT_STATUS_INVALID_PARAMETER; } - - /* query only first */ - if ( !winbind_sid_to_gid_query(pgid, psid) ) { - DEBUG(10,("sid_to_gid: winbind query for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - - /* see if we have a local mapping */ - - if ( local_sid_to_gid(pgid, psid, &name_type) ) { - store_gid_sid_cache(psid, *pgid); - return NT_STATUS_OK; - } - - /* Call back to winbind to allocate a new uid */ + /* winbindd knows it and it is a type of group; sid_to_gid must succeed + or we are dead in the water */ - if ( !winbind_sid_to_gid(pgid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } - else - return NT_STATUS_UNSUCCESSFUL; + if ( !winbind_sid_to_gid(pgid, psid) ) { + DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n", + sid_to_string(sid_str, psid) )); + return NT_STATUS_UNSUCCESSFUL; } +success: DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid), (unsigned int)*pgid )); -- cgit From 74be920b0ee236d577cb357fcb34dd462300444d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Aug 2003 01:14:51 +0000 Subject: Spelling. (This used to be commit 7d009ebf66c82b254828bac267102eb6e6a4a75e) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8d3e7cd9be..b12fcca4b0 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -370,7 +370,7 @@ BOOL unbecome_user(void) } /***************************************************************** - Convert the suplimentary SIDs returned in a netlogon into UNIX + Convert the supplementary SIDs returned in a netlogon into UNIX group gid_t's. Add to the total group array. *****************************************************************/ -- cgit From c2983f9323099019d77b9480e884707e26895c5d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 27 Aug 2003 20:52:56 +0000 Subject: Fix bug 327 (again and I think for the last time). Make sure that pam_smbpass.so will load ok. Had to move some functions around to work around dependency problems (hence the new passdb/lookup_sid.c) Also make sure that libsmbclient.a is built and installed when we support shared libraries. (This used to be commit 780055f4422f11fb0524ac1f003cdc5f317f8b19) --- source3/smbd/uid.c | 463 ----------------------------------------------------- 1 file changed, 463 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b12fcca4b0..7979ffe854 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -437,467 +437,4 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER *pptok = new_tok; } -/***************************************************************** - *THE CANONICAL* convert name to SID function. - Tries local lookup first - for local domains - then uses winbind. -*****************************************************************/ - -BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) -{ - fstring sid; - BOOL local_lookup = False; - - *name_type = SID_NAME_UNKNOWN; - - /* If we are looking up a domain user, make sure it is - for the local machine only */ - - if (strequal(global_myname(), domain)) { - local_lookup = True; - } else if (lp_server_role() == ROLE_DOMAIN_PDC || - lp_server_role() == ROLE_DOMAIN_BDC) { - if (strequal(domain, lp_workgroup())) { - local_lookup = True; - } - } - - if (local_lookup) { - if (local_lookup_name(name, psid, name_type)) { - DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", - domain, name, sid_to_string(sid,psid), - sid_type_lookup(*name_type), (unsigned int)*name_type)); - return True; - } - } else { - /* Remote */ - if (winbind_lookup_name(domain, name, psid, name_type)) { - - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; - } - } - - DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", - local_lookup ? "local" : "winbind", domain, name)); - - return False; -} - -/***************************************************************** - *THE CANONICAL* convert SID to name function. - Tries local lookup first - for local sids, then tries winbind. -*****************************************************************/ - -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) -{ - if (!name_type) - return False; - - *name_type = SID_NAME_UNKNOWN; - - /* Check if this is our own sid. This should perhaps be done by - winbind? For the moment handle it here. */ - - if (sid->num_auths == 5) { - DOM_SID tmp_sid; - uint32 rid; - - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - - if (sid_equal(get_global_sam_sid(), &tmp_sid)) { - - return map_domain_sid_to_name(&tmp_sid, dom_name) && - local_lookup_sid(sid, name, name_type); - } - } - - if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { - fstring sid_str; - DOM_SID tmp_sid; - uint32 rid; - - DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); - - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_known_rid(&tmp_sid, rid, name, name_type); - } - return True; -} - - -/***************************************************************** - Id mapping cache. This is to avoid Winbind mappings already - seen by smbd to be queried too frequently, keeping winbindd - busy, and blocking smbd while winbindd is busy with other - stuff. Written by Michael Steffens , - modified to use linked lists by jra. -*****************************************************************/ - -#define MAX_UID_SID_CACHE_SIZE 100 -#define TURNOVER_UID_SID_CACHE_SIZE 10 -#define MAX_GID_SID_CACHE_SIZE 100 -#define TURNOVER_GID_SID_CACHE_SIZE 10 - -static size_t n_uid_sid_cache = 0; -static size_t n_gid_sid_cache = 0; - -static struct uid_sid_cache { - struct uid_sid_cache *next, *prev; - uid_t uid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *uid_sid_cache_head; - -static struct gid_sid_cache { - struct gid_sid_cache *next, *prev; - gid_t gid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *gid_sid_cache_head; - -/***************************************************************** - Find a SID given a uid. -*****************************************************************/ - -static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (pc->uid == uid) { - fstring sid; - *psid = pc->sid; - DEBUG(3,("fetch sid from uid cache %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a uid given a SID. -*****************************************************************/ - -static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid ) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *puid = pc->uid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*puid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store uid to SID mapping in cache. -*****************************************************************/ - -static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid) -{ - struct uid_sid_cache *pc; - - if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */ - struct uid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(uid_sid_cache_head,pc); - SAFE_FREE(pc); - n_uid_sid_cache--; - } - } - - pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache)); - if (!pc) - return; - pc->uid = uid; - sid_copy(&pc->sid, psid); - DLIST_ADD(uid_sid_cache_head, pc); - n_uid_sid_cache++; -} - -/***************************************************************** - Find a SID given a gid. -*****************************************************************/ - -static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (pc->gid == gid) { - fstring sid; - *psid = pc->sid; - DEBUG(3,("fetch sid from gid cache %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a gid given a SID. -*****************************************************************/ - -static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *pgid = pc->gid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*pgid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store gid to SID mapping in cache. -*****************************************************************/ -static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) -{ - struct gid_sid_cache *pc; - - if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */ - struct gid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(gid_sid_cache_head,pc); - SAFE_FREE(pc); - n_gid_sid_cache--; - } - } - - pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache)); - if (!pc) - return; - pc->gid = gid; - sid_copy(&pc->sid, psid); - DLIST_ADD(gid_sid_cache_head, pc); - n_gid_sid_cache++; -} - -/***************************************************************** - *THE CANONICAL* convert uid_t to SID function. -*****************************************************************/ - -NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) -{ - uid_t low, high; - fstring sid; - - ZERO_STRUCTP(psid); - - if (fetch_sid_from_uid_cache(psid, uid)) - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - - if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) { - if (winbind_uid_to_sid(psid, uid)) { - - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - - if (psid) - store_uid_sid_cache(psid, uid); - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - } - } - - if (!local_uid_to_sid(psid, uid)) { - DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid )); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); - - store_uid_sid_cache(psid, uid); - return NT_STATUS_OK; -} - -/***************************************************************** - *THE CANONICAL* convert gid_t to SID function. -*****************************************************************/ - -NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) -{ - gid_t low, high; - fstring sid; - - ZERO_STRUCTP(psid); - - if (fetch_sid_from_gid_cache(psid, gid)) - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - - if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) { - if (winbind_gid_to_sid(psid, gid)) { - - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - - if (psid) - store_gid_sid_cache(psid, gid); - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - } - } - - if (!local_gid_to_sid(psid, gid)) { - DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid )); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); - - store_gid_sid_cache(psid, gid); - return NT_STATUS_OK; -} - -/***************************************************************** - *THE CANONICAL* convert SID to uid function. -*****************************************************************/ - -NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - if (fetch_uid_from_cache(puid, psid)) - return NT_STATUS_OK; - - /* if this is our SID then go straight to a local lookup */ - - if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) { - DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n", - sid_string_static(psid) )); - - if ( local_sid_to_uid(puid, psid, &name_type) ) - goto success; - - DEBUG(10,("sid_to_uid: local lookup failed\n")); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* If it is not our local domain, only hope is winbindd */ - - if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) { - DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n", - sid_string_static(psid) )); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* If winbindd does know the SID, ensure this is a user */ - - if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n", - (unsigned int)name_type )); - return NT_STATUS_INVALID_PARAMETER; - } - - /* get the uid. Has to work or else we are dead in the water */ - - if ( !winbind_sid_to_uid(puid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } - -success: - DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid), - (unsigned int)*puid )); - - store_uid_sid_cache(psid, *puid); - - return NT_STATUS_OK; -} -/***************************************************************** - *THE CANONICAL* convert SID to gid function. - Group mapping is used for gids that maps to Wellknown SIDs -*****************************************************************/ - -NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - if (fetch_gid_from_cache(pgid, psid)) - return NT_STATUS_OK; - - /* - * First we must look up the name and decide if this is a group sid. - * Group mapping can deal with foreign SIDs - */ - - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - if ( local_sid_to_gid(pgid, psid, &name_type) ) - goto success; - - DEBUG(10,("sid_to_gid: no one knows this SID\n")); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* winbindd knows it; Ensure this is a group sid */ - - if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { - DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", - (unsigned int)name_type )); - - /* winbindd is running and knows about this SID. Just the wrong type. - Don't fallback to a local lookup here */ - - return NT_STATUS_INVALID_PARAMETER; - } - - /* winbindd knows it and it is a type of group; sid_to_gid must succeed - or we are dead in the water */ - - if ( !winbind_sid_to_gid(pgid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } - -success: - DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid), - (unsigned int)*pgid )); - - store_gid_sid_cache(psid, *pgid); - - return NT_STATUS_OK; -} -- cgit From ae2c8656b22ca855aaf1ab7382a92996b362a900 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 07:17:30 +0000 Subject: Samba hasn't used this function for ages - it's now handled deep in the auth subsystem. Andrew Bartlett (This used to be commit 5693730594b1a861c7916cac7d156cf6a9d913cd) --- source3/smbd/uid.c | 69 ------------------------------------------------------ 1 file changed, 69 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7979ffe854..09cf899522 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -369,72 +369,3 @@ BOOL unbecome_user(void) return True; } -/***************************************************************** - Convert the supplementary SIDs returned in a netlogon into UNIX - group gid_t's. Add to the total group array. -*****************************************************************/ - -void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok) -{ - int total_groups; - int current_n_groups = *n_groups; - gid_t *final_groups = NULL; - size_t i; - NT_USER_TOKEN *ptok = *pptok; - NT_USER_TOKEN *new_tok = NULL; - - if (!ptok || (ptok->num_sids == 0)) - return; - - new_tok = dup_nt_token(ptok); - if (!new_tok) { - DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n")); - return; - } - /* Leave the allocated space but empty the number of SIDs. */ - new_tok->num_sids = 0; - - total_groups = current_n_groups + ptok->num_sids; - - final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t)); - if (!final_groups) { - DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n")); - delete_nt_token(&new_tok); - return; - } - - memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t)); - for (i = 0; i < ptok->num_sids; i++) { - gid_t new_grp; - - if (NT_STATUS_IS_OK(sid_to_gid(&ptok->user_sids[i], &new_grp))) { - /* - * Don't add the gid_t if it is already in the current group - * list. Some UNIXen don't like the same group more than once. - */ - int j; - - for (j = 0; j < current_n_groups; j++) - if (final_groups[j] == new_grp) - break; - - if ( j == current_n_groups) { - /* Group not already present. */ - final_groups[current_n_groups++] = new_grp; - } - } else { - /* SID didn't map. Copy to the new token to be saved. */ - sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]); - } - } - - SAFE_FREE(*pp_groups); - *pp_groups = final_groups; - *n_groups = current_n_groups; - - /* Replace the old token with the truncated one. */ - delete_nt_token(&ptok); - *pptok = new_tok; -} - - -- cgit From 0f1dcf9839676aa6ae2d6121ed5233f8f4101384 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:26:46 +0000 Subject: nsswitch/winbindd_util.c: add static smbd/uid.c: remove unused function Andrew Bartlett (This used to be commit ab25af0e18d883757775a85f005775a79a86dcc8) --- source3/smbd/uid.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 09cf899522..f3d9004dd9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -310,17 +310,6 @@ static void pop_conn_ctx(void) ctx_p->vuid = UID_FIELD_INVALID; } -void init_conn_ctx(void) -{ - int i; - - /* Initialise connection context stack */ - for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) { - conn_ctx_stack[i].conn = NULL; - conn_ctx_stack[i].vuid = UID_FIELD_INVALID; - } -} - /**************************************************************************** Temporarily become a root user. Must match with unbecome_root(). Saves and restores the connection context. -- cgit From b545a8de0a605edda11cab322dab0ad26b6cebd1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Feb 2004 19:05:25 +0000 Subject: Fixup the 'multiple-vuids' bugs. Jeremy. (This used to be commit f0f7a48327ba1808088bc8c4e5d48b5cbeaeb4e3) --- source3/smbd/uid.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 12 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f3d9004dd9..3859298055 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -54,33 +54,97 @@ BOOL change_to_guest(void) return True; } +/**************************************************************************** + Readonly share for this user ? +****************************************************************************/ + +static BOOL is_share_read_only_for_user(connection_struct *conn, user_struct *vuser) +{ + char **list; + const char *service = lp_servicename(conn->service); + BOOL read_only_ret = lp_readonly(conn->service); + + if (!service) + return read_only_ret; + + str_list_copy(&list, lp_readlist(conn->service)); + if (list) { + if (!str_list_sub_basic(list, vuser->user.smb_name) ) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: read list substitution failed\n")); + } + if (!str_list_substitute(list, "%S", service)) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: read list service substitution failed\n")); + } + if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + read_only_ret = True; + } + str_list_free(&list); + } + + str_list_copy(&list, lp_writelist(conn->service)); + if (list) { + if (!str_list_sub_basic(list, vuser->user.smb_name) ) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: write list substitution failed\n")); + } + if (!str_list_substitute(list, "%S", service)) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: write list service substitution failed\n")); + } + if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + read_only_ret = False; + } + str_list_free(&list); + } + + DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user %s\n", + service, read_only_ret ? "read-only" : "read-write", vuser->user.unix_name )); + + return read_only_ret; +} + /******************************************************************* Check if a username is OK. ********************************************************************/ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { - unsigned i; - for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) - if (conn->vuid_cache.list[i] == vuser->vuid) + unsigned int i; + struct vuid_cache_entry *ent = NULL; + BOOL readonly_share; + + for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { + if (conn->vuid_cache.array[i].vuid == vuser->vuid) { + ent = &conn->vuid_cache.array[i]; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; return(True); - - if ((conn->force_user || conn->force_group) - && (conn->vuid != vuser->vuid)) { - return False; + } } - + if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups)) return(False); - if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { + readonly_share = is_share_read_only_for_user(conn, vuser); + + if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } i = conn->vuid_cache.entries % VUID_CACHE_SIZE; - conn->vuid_cache.list[i] = vuser->vuid; + if (conn->vuid_cache.entries < VUID_CACHE_SIZE) + conn->vuid_cache.entries++; + + ent = &conn->vuid_cache.array[i]; + ent->vuid = vuser->vuid; + ent->read_only = readonly_share; + + if (user_in_list(vuser->user.unix_name ,lp_admin_users(conn->service), vuser->groups, vuser->n_groups)) { + ent->admin_user = True; + } else { + ent->admin_user = False; + } - conn->vuid_cache.entries++; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; return(True); } @@ -132,7 +196,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) current_user.ngroups = conn->ngroups; token = conn->nt_user_token; } else if ((vuser) && check_user_ok(conn, vuser, snum)) { - uid = vuser->uid; + uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; -- cgit From 49f95e6d27ac9476e8308e53629e8ae4908957c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 May 2004 00:26:06 +0000 Subject: r762: Fix for #1319 when security > share. Jeremy. (This used to be commit 9fe2240d6b68a2f8a495df585d69ae20c9825d77) --- source3/smbd/uid.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3859298055..e1864c74ca 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -189,20 +189,26 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); + if ((vuser) && !check_user_ok(conn, vuser, snum)) { + DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) not permitted access to share %s.\n", + vuser->user.smb_name, vuser->user.unix_name, vuid, lp_servicename(snum))); + return False; + } + if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; token = conn->nt_user_token; - } else if ((vuser) && check_user_ok(conn, vuser, snum)) { + } else if (vuser) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; token = vuser->nt_user_token; } else { - DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid)); + DEBUG(2,("change_to_user: Invalid vuid used %d in accessing share %s.\n",vuid, lp_servicename(snum) )); return False; } -- cgit From 5aadb88b537e8beb994b9c7e063b1725d41fad8f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Jul 2004 13:13:15 +0000 Subject: r1375: When setting writable=yes in smb.conf and only allow read access in the security descriptor, allow read access. The code failed in this case. Jeremy, could you please cross-check this? The way I understood your code it could only work if smb.conf and secdesc said the same. This made the use of srvmgr a bit difficult.... What was your intention on how to use the share_info.tdb? The current code might check the secdesc twice, but I don't see any decent way around it that does not completely clutter the code. Volker (This used to be commit 7c673bd910e1fcbbf07198f38ceddd81e9064c11) --- source3/smbd/uid.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index e1864c74ca..de2f96450f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -125,6 +125,13 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) readonly_share = is_share_read_only_for_user(conn, vuser); + if (!readonly_share && + !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { + /* smb.conf allows r/w, but the security descriptor denies + * write. Fall back to looking at readonly. */ + readonly_share = True; + } + if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } -- cgit From e091cd81480ca14118dab1ae76c37f7bf891c295 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Aug 2004 13:26:31 +0000 Subject: r2016: Add message to ease access-control-debugging. Guenther (This used to be commit bc64bb0d206c54487e372824a14c38a4ba8f3c5a) --- source3/smbd/uid.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index de2f96450f..77dc19b87b 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -130,6 +130,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; + DEBUG(5,("falling back to read-only access-evaluation due to security descriptor\n")); } if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { -- cgit From fecdaec41c70916dc8e591c6e98e830c0f5cb0b1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Apr 2005 07:12:44 +0000 Subject: r6385: Convert checking of egid and secondary egid list into iterator functions so it can be used easily in a for loop. Drops duplicated code from posix_acls.c Jeremy. (This used to be commit 81f30bf5985f5c6dc8399c4695dfa6f14140fde1) --- source3/smbd/uid.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 77dc19b87b..d1ecaf6625 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -23,6 +23,29 @@ /* what user is current? */ extern struct current_user current_user; +/**************************************************************************** + Iterator functions for getting all gid's from current_user. +****************************************************************************/ + +gid_t get_current_user_gid_first(int *piterator) +{ + *piterator = 0; + return current_user.gid; +} + +gid_t get_current_user_gid_next(int *piterator) +{ + gid_t ret; + + if (!current_user.groups || *piterator >= current_user.ngroups) { + return (gid_t)-1; + } + + ret = current_user.groups[*piterator]; + (*piterator) += 1; + return ret; +} + /**************************************************************************** Become the guest user without changing the security context stack. ****************************************************************************/ -- cgit From 0a585102d656b267af723a5bdd258e83f532c3a6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Dec 2005 14:23:23 +0000 Subject: r12312: Reformatting and a trivial change: is_share_read_only_for_user only uses conn->service, so there's no point in passing down the whole conn struct. Volker (This used to be commit 39041297c771795efaa4292bc6e8020c1a047f32) --- source3/smbd/uid.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d1ecaf6625..458eb3a2c8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -81,45 +81,53 @@ BOOL change_to_guest(void) Readonly share for this user ? ****************************************************************************/ -static BOOL is_share_read_only_for_user(connection_struct *conn, user_struct *vuser) +static BOOL is_share_read_only_for_user(int snum, user_struct *vuser) { char **list; - const char *service = lp_servicename(conn->service); - BOOL read_only_ret = lp_readonly(conn->service); + const char *service = lp_servicename(snum); + BOOL read_only_ret = lp_readonly(snum); if (!service) return read_only_ret; - str_list_copy(&list, lp_readlist(conn->service)); + str_list_copy(&list, lp_readlist(snum)); if (list) { if (!str_list_sub_basic(list, vuser->user.smb_name) ) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: read list substitution failed\n")); + DEBUG(0, ("is_share_read_only_for_user: ERROR: read " + "list substitution failed\n")); } if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: read list service substitution failed\n")); + DEBUG(0, ("is_share_read_only_for_user: ERROR: read " + "list service substitution failed\n")); } - if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + if (user_in_list(vuser->user.unix_name, (const char **)list, + vuser->groups, vuser->n_groups)) { read_only_ret = True; } str_list_free(&list); } - str_list_copy(&list, lp_writelist(conn->service)); + str_list_copy(&list, lp_writelist(snum)); if (list) { if (!str_list_sub_basic(list, vuser->user.smb_name) ) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: write list substitution failed\n")); + DEBUG(0, ("is_share_read_only_for_user: ERROR: write " + "list substitution failed\n")); } if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: write list service substitution failed\n")); + DEBUG(0, ("is_share_read_only_for_user: ERROR: write " + "list service substitution failed\n")); } - if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + if (user_in_list(vuser->user.unix_name, (const char **)list, + vuser->groups, vuser->n_groups)) { read_only_ret = False; } str_list_free(&list); } - DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user %s\n", - service, read_only_ret ? "read-only" : "read-write", vuser->user.unix_name )); + DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user " + "%s\n", service, + read_only_ret ? "read-only" : "read-write", + vuser->user.unix_name )); return read_only_ret; } @@ -146,7 +154,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups)) return(False); - readonly_share = is_share_read_only_for_user(conn, vuser); + readonly_share = is_share_read_only_for_user(conn->service, vuser); if (!readonly_share && !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { -- cgit From 005c88054f526d9a14d748b665cd6b4853e60a35 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 13 Jan 2006 21:22:25 +0000 Subject: r12916: use rpcstr_pull() instead of unistr_to_ascii() when validating share names (This used to be commit c08bc30698eac2f3f5dd8257b4fd7c3e23e6de39) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 458eb3a2c8..9db3d97ab2 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -190,7 +190,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) /**************************************************************************** Become the user of a connection number without changing the security context - stack, but modify the currnet_user entries. + stack, but modify the current_user entries. ****************************************************************************/ BOOL change_to_user(connection_struct *conn, uint16 vuid) -- cgit From d14af63e6ab600eb3ac705f2f425c860e927553a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 20:44:50 +0000 Subject: r13293: Rather a big patch I'm afraid, but this should fix bug #3347 by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654) --- source3/smbd/uid.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9db3d97ab2..d419720c33 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -30,18 +30,18 @@ extern struct current_user current_user; gid_t get_current_user_gid_first(int *piterator) { *piterator = 0; - return current_user.gid; + return current_user.ut.gid; } gid_t get_current_user_gid_next(int *piterator) { gid_t ret; - if (!current_user.groups || *piterator >= current_user.ngroups) { + if (!current_user.ut.groups || *piterator >= current_user.ut.ngroups) { return (gid_t)-1; } - ret = current_user.groups[*piterator]; + ret = current_user.ut.groups[*piterator]; (*piterator) += 1; return ret; } @@ -216,12 +216,12 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.uid == conn->uid)) { + (current_user.ut.uid == conn->uid)) { DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.uid == vuser->uid)) { + (current_user.ut.uid == vuser->uid)) { DEBUG(4,("change_to_user: Skipping user change - already user\n")); return(True); } @@ -237,14 +237,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; - current_user.groups = conn->groups; - current_user.ngroups = conn->ngroups; + current_user.ut.groups = conn->groups; + current_user.ut.ngroups = conn->ngroups; token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; + current_user.ut.ngroups = vuser->n_groups; + current_user.ut.groups = vuser->groups; token = vuser->nt_user_token; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing share %s.\n",vuid, lp_servicename(snum) )); @@ -270,8 +270,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ int i; - for (i = 0; i < current_user.ngroups; i++) { - if (current_user.groups[i] == conn->gid) { + for (i = 0; i < current_user.ut.ngroups; i++) { + if (current_user.ut.groups[i] == conn->gid) { gid = conn->gid; break; } @@ -288,7 +288,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + token = create_nt_token(uid, gid, current_user.ut.ngroups, current_user.ut.groups, is_guest); if (!token) { DEBUG(1, ("change_to_user: create_nt_token failed!\n")); return False; @@ -296,7 +296,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) must_free_token = True; } - set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token); + set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, token); /* * Free the new token (as set_sec_ctx copies it). @@ -343,8 +343,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) if (!push_sec_ctx()) return False; - set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token); + set_sec_ctx(p->pipe_user.ut.uid, p->pipe_user.ut.gid, + p->pipe_user.ut.ngroups, p->pipe_user.ut.groups, p->pipe_user.nt_user_token); return True; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/smbd/uid.c | 131 ++++++++++++++++------------------------------------- 1 file changed, 40 insertions(+), 91 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d419720c33..6e516d3562 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -56,7 +56,7 @@ BOOL change_to_guest(void) if (!pass) { /* Don't need to free() this as its stored in a static */ - pass = getpwnam_alloc(lp_guestaccount()); + pass = getpwnam_alloc(NULL, lp_guestaccount()); if (!pass) return(False); } @@ -71,67 +71,13 @@ BOOL change_to_guest(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; - - passwd_free(&pass); + talloc_free(pass); + pass = NULL; + return True; } -/**************************************************************************** - Readonly share for this user ? -****************************************************************************/ - -static BOOL is_share_read_only_for_user(int snum, user_struct *vuser) -{ - char **list; - const char *service = lp_servicename(snum); - BOOL read_only_ret = lp_readonly(snum); - - if (!service) - return read_only_ret; - - str_list_copy(&list, lp_readlist(snum)); - if (list) { - if (!str_list_sub_basic(list, vuser->user.smb_name) ) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: read " - "list substitution failed\n")); - } - if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: read " - "list service substitution failed\n")); - } - if (user_in_list(vuser->user.unix_name, (const char **)list, - vuser->groups, vuser->n_groups)) { - read_only_ret = True; - } - str_list_free(&list); - } - - str_list_copy(&list, lp_writelist(snum)); - if (list) { - if (!str_list_sub_basic(list, vuser->user.smb_name) ) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: write " - "list substitution failed\n")); - } - if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("is_share_read_only_for_user: ERROR: write " - "list service substitution failed\n")); - } - if (user_in_list(vuser->user.unix_name, (const char **)list, - vuser->groups, vuser->n_groups)) { - read_only_ret = False; - } - str_list_free(&list); - } - - DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user " - "%s\n", service, - read_only_ret ? "read-only" : "read-write", - vuser->user.unix_name )); - - return read_only_ret; -} - /******************************************************************* Check if a username is OK. ********************************************************************/ @@ -151,20 +97,25 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } } - if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups)) + if (!user_ok_token(vuser->user.unix_name, vuser->nt_user_token, snum)) return(False); - readonly_share = is_share_read_only_for_user(conn->service, vuser); + readonly_share = is_share_read_only_for_token(vuser->user.unix_name, + vuser->nt_user_token, + conn->service); if (!readonly_share && !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; - DEBUG(5,("falling back to read-only access-evaluation due to security descriptor\n")); + DEBUG(5,("falling back to read-only access-evaluation due to " + "security descriptor\n")); } - if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { + if (!share_access_check(conn, snum, vuser, + readonly_share ? + FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } @@ -176,11 +127,9 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->vuid = vuser->vuid; ent->read_only = readonly_share; - if (user_in_list(vuser->user.unix_name ,lp_admin_users(conn->service), vuser->groups, vuser->n_groups)) { - ent->admin_user = True; - } else { - ent->admin_user = False; - } + ent->admin_user = token_contains_name_in_list( + vuser->user.unix_name, NULL, vuser->nt_user_token, + lp_admin_users(conn->service)); conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; @@ -217,20 +166,24 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && (current_user.ut.uid == conn->uid)) { - DEBUG(4,("change_to_user: Skipping user change - already user\n")); + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && (current_user.ut.uid == vuser->uid)) { - DEBUG(4,("change_to_user: Skipping user change - already user\n")); + DEBUG(4,("change_to_user: Skipping user change - already " + "user\n")); return(True); } snum = SNUM(conn); if ((vuser) && !check_user_ok(conn, vuser, snum)) { - DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) not permitted access to share %s.\n", - vuser->user.smb_name, vuser->user.unix_name, vuid, lp_servicename(snum))); + DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " + "not permitted access to share %s.\n", + vuser->user.smb_name, vuser->user.unix_name, vuid, + lp_servicename(snum))); return False; } @@ -247,7 +200,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) current_user.ut.groups = vuser->groups; token = vuser->nt_user_token; } else { - DEBUG(2,("change_to_user: Invalid vuid used %d in accessing share %s.\n",vuid, lp_servicename(snum) )); + DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " + "share %s.\n",vuid, lp_servicename(snum) )); return False; } @@ -258,7 +212,13 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ if((group_c = *lp_force_group(snum))) { - BOOL is_guest = False; + + token = dup_nt_token(NULL, token); + if (token == NULL) { + DEBUG(0, ("dup_nt_token failed\n")); + return False; + } + must_free_token = True; if(group_c == '+') { @@ -273,37 +233,25 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) for (i = 0; i < current_user.ut.ngroups; i++) { if (current_user.ut.groups[i] == conn->gid) { gid = conn->gid; + gid_to_sid(&token->user_sids[1], gid); break; } } } else { gid = conn->gid; + gid_to_sid(&token->user_sids[1], gid); } - - /* - * We've changed the group list in the token - we must - * re-create it. - */ - - if (vuser && vuser->guest) - is_guest = True; - - token = create_nt_token(uid, gid, current_user.ut.ngroups, current_user.ut.groups, is_guest); - if (!token) { - DEBUG(1, ("change_to_user: create_nt_token failed!\n")); - return False; - } - must_free_token = True; } - set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, token); + set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, + token); /* * Free the new token (as set_sec_ctx copies it). */ if (must_free_token) - delete_nt_token(&token); + talloc_free(token); current_user.conn = conn; current_user.vuid = vuid; @@ -344,7 +292,8 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) return False; set_sec_ctx(p->pipe_user.ut.uid, p->pipe_user.ut.gid, - p->pipe_user.ut.ngroups, p->pipe_user.ut.groups, p->pipe_user.nt_user_token); + p->pipe_user.ut.ngroups, p->pipe_user.ut.groups, + p->pipe_user.nt_user_token); return True; } -- cgit From fb5362c069b5b6548478b2217a0519c56d856705 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Feb 2006 17:59:58 +0000 Subject: r13571: Replace all calls to talloc_free() with thye TALLOC_FREE() macro which sets the freed pointer to NULL. (This used to be commit b65be8874a2efe5a4b167448960a4fcf6bd995e2) --- source3/smbd/uid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 6e516d3562..c62c9d928a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -72,7 +72,7 @@ BOOL change_to_guest(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; - talloc_free(pass); + TALLOC_FREE(pass); pass = NULL; return True; @@ -251,7 +251,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ if (must_free_token) - talloc_free(token); + TALLOC_FREE(token); current_user.conn = conn; current_user.vuid = vuid; -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/uid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c62c9d928a..48d7f590c3 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -102,7 +102,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) readonly_share = is_share_read_only_for_token(vuser->user.unix_name, vuser->nt_user_token, - conn->service); + SNUM(conn)); if (!readonly_share && !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { @@ -129,7 +129,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->admin_user = token_contains_name_in_list( vuser->user.unix_name, NULL, vuser->nt_user_token, - lp_admin_users(conn->service)); + lp_admin_users(SNUM(conn))); conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; -- cgit From 283b74fce595642fb2e2a2fad87c2de9c3bc5403 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Jul 2006 19:50:59 +0000 Subject: r17096: Simplify share_access_check a bit: It takes the sharename instead of the snum, and the decision which token to use (conn or vuser) does not really belong here, it is better done in the two places where this is called. Volker (This used to be commit 0a138888adf7a0f04a38cd911e797e1a379e908b) --- source3/smbd/uid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 48d7f590c3..89d082e1ac 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -87,6 +87,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) unsigned int i; struct vuid_cache_entry *ent = NULL; BOOL readonly_share; + NT_USER_TOKEN *token; for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { if (conn->vuid_cache.array[i].vuid == vuser->vuid) { @@ -104,8 +105,12 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) vuser->nt_user_token, SNUM(conn)); + token = conn->nt_user_token ? + conn->nt_user_token : vuser->nt_user_token; + if (!readonly_share && - !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { + !share_access_check(token, lp_servicename(snum), + FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; @@ -113,7 +118,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) "security descriptor\n")); } - if (!share_access_check(conn, snum, vuser, + if (!share_access_check(token, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; -- cgit From 5b3d559aa808210b1d6d61bc9bb9088b06e4c9c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 23:09:12 +0000 Subject: r17295: Back out the become_root_uid_only change on the POSIX acls code. I'm pretty sure this was safe, but become_root() does other things to the token stack that become_root_uid_only() does not, and as we're going into a vfs redirectred function I decided it wasn't safe for now. Jeremy. (This used to be commit b3e0f45488595aa96c852dab8e1349631a85dded) --- source3/smbd/uid.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 89d082e1ac..8588580322 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -420,4 +420,3 @@ BOOL unbecome_user(void) pop_conn_ctx(); return True; } - -- cgit From 0e9210d0eaf0c9de231e48e671cfb0861d62a1da Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 17 May 2007 22:27:42 +0000 Subject: r22978: Don't use current_user to prep the security ctx in change_to_user since any SID/uid/gid translation calls will reset the struct when popping the security ctx. This should fix the standalone server configuration issues reported by David Rankin (thanks for the logs). (This used to be commit 63cb25bad19d9600399a6ee2221497d71e805320) --- source3/smbd/uid.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8588580322..c6d4e3329c 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -156,7 +156,9 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) char group_c; BOOL must_free_token = False; NT_USER_TOKEN *token = NULL; - + int num_groups = 0; + gid_t *group_list = NULL; + if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); return(False); @@ -195,14 +197,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; - current_user.ut.groups = conn->groups; - current_user.ut.ngroups = conn->ngroups; + group_list = conn->groups; + num_groups = conn->ngroups; token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; - current_user.ut.ngroups = vuser->n_groups; - current_user.ut.groups = vuser->groups; + num_groups = vuser->n_groups; + group_list = vuser->groups; token = vuser->nt_user_token; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " @@ -235,8 +237,8 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) */ int i; - for (i = 0; i < current_user.ut.ngroups; i++) { - if (current_user.ut.groups[i] == conn->gid) { + for (i = 0; i < num_groups; i++) { + if (group_list[i] == conn->gid) { gid = conn->gid; gid_to_sid(&token->user_sids[1], gid); break; @@ -248,6 +250,12 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) } } + /* Now 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, token); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index c6d4e3329c..bf23680b54 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/uid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index bf23680b54..d1837c41dc 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/uid.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index d1837c41dc..dceea450e6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -49,7 +49,7 @@ gid_t get_current_user_gid_next(int *piterator) Become the guest user without changing the security context stack. ****************************************************************************/ -BOOL change_to_guest(void) +bool change_to_guest(void) { static struct passwd *pass=NULL; @@ -81,11 +81,11 @@ BOOL change_to_guest(void) Check if a username is OK. ********************************************************************/ -static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) +static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { unsigned int i; struct vuid_cache_entry *ent = NULL; - BOOL readonly_share; + bool readonly_share; NT_USER_TOKEN *token; for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { @@ -146,14 +146,14 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) stack, but modify the current_user entries. ****************************************************************************/ -BOOL change_to_user(connection_struct *conn, uint16 vuid) +bool change_to_user(connection_struct *conn, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum; gid_t gid; uid_t uid; char group_c; - BOOL must_free_token = False; + bool must_free_token = False; NT_USER_TOKEN *token = NULL; int num_groups = 0; gid_t *group_list = NULL; @@ -279,7 +279,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) but modify the current_user entries. ****************************************************************************/ -BOOL change_to_root_user(void) +bool change_to_root_user(void) { set_root_sec_ctx(); @@ -298,7 +298,7 @@ BOOL change_to_root_user(void) user. Doesn't modify current_user. ****************************************************************************/ -BOOL become_authenticated_pipe_user(pipes_struct *p) +bool become_authenticated_pipe_user(pipes_struct *p) { if (!push_sec_ctx()) return False; @@ -317,7 +317,7 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) current_user. ****************************************************************************/ -BOOL unbecome_authenticated_pipe_user(void) +bool unbecome_authenticated_pipe_user(void) { return pop_sec_ctx(); } @@ -405,7 +405,7 @@ void unbecome_root(void) Saves and restores the connection context. ****************************************************************************/ -BOOL become_user(connection_struct *conn, uint16 vuid) +bool become_user(connection_struct *conn, uint16 vuid) { if (!push_sec_ctx()) return False; @@ -421,7 +421,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return True; } -BOOL unbecome_user(void) +bool unbecome_user(void) { pop_sec_ctx(); pop_conn_ctx(); -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/smbd/uid.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index dceea450e6..1a3b7383c9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -387,7 +387,12 @@ static void pop_conn_ctx(void) void become_root(void) { - push_sec_ctx(); + /* + * no good way to handle push_sec_ctx() failing without changing + * the prototype of become_root() + */ + if (!push_sec_ctx()) + return; push_conn_ctx(); set_root_sec_ctx(); } -- cgit From c5356479c1953b15fee8097d5d3436204fc7a4ce Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Mar 2008 21:00:16 +0100 Subject: Some simplifications (This used to be commit b59b436997fba47afd02ffb6f1194dfaef229d44) --- source3/smbd/uid.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 1a3b7383c9..ffa643a8f5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -391,8 +391,9 @@ void become_root(void) * no good way to handle push_sec_ctx() failing without changing * the prototype of become_root() */ - if (!push_sec_ctx()) - return; + if (!push_sec_ctx()) { + smb_panic("become_root: push_sec_ctx failed"); + } push_conn_ctx(); set_root_sec_ctx(); } -- cgit From 8dd53811d57da9a079f81e1f742f803131239b09 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 May 2008 14:43:57 +0200 Subject: Fix allocation of conn->vuid_cache entries With the old code, if more than VUID_CACHE_SIZE elements were used all new entries ended up in slot 0. With this checkin we do cycle. Jeremy, please revert if the old behaviour was intentional (This used to be commit 50c891d3dfb75c9f607f7ad2a578aa3ba5d91988) --- source3/smbd/uid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ffa643a8f5..343a0cf490 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -123,9 +123,9 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return False; } - i = conn->vuid_cache.entries % VUID_CACHE_SIZE; - if (conn->vuid_cache.entries < VUID_CACHE_SIZE) - conn->vuid_cache.entries++; + i = conn->vuid_cache.entries; + conn->vuid_cache.entries = + (conn->vuid_cache.entries + 1) % VUID_CACHE_SIZE; ent = &conn->vuid_cache.array[i]; ent->vuid = vuser->vuid; -- cgit From 1a3f50559e06c9dc45556c2c52d68a23c05d7e41 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 May 2008 15:06:39 +0200 Subject: Revert "Fix allocation of conn->vuid_cache entries" This reverts commit 50c891d3dfb75c9f607f7ad2a578aa3ba5d91988. There's more to this code -- sorry for the spam (This used to be commit 6e0e0cb8dd6f57de36c041e2ba4b82feeb357ce8) --- source3/smbd/uid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 343a0cf490..ffa643a8f5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -123,9 +123,9 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return False; } - i = conn->vuid_cache.entries; - conn->vuid_cache.entries = - (conn->vuid_cache.entries + 1) % VUID_CACHE_SIZE; + i = conn->vuid_cache.entries % VUID_CACHE_SIZE; + if (conn->vuid_cache.entries < VUID_CACHE_SIZE) + conn->vuid_cache.entries++; ent = &conn->vuid_cache.array[i]; ent->vuid = vuser->vuid; -- cgit From bb3755968f5e953340edfb0b71997dddc11badb9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:35:00 +0200 Subject: Remove "nt_user_token" from "struct user_struct" (This used to be commit 51d5d512f28eadc74eced43e5e7f4e5bdff3ff69) --- source3/smbd/uid.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ffa643a8f5..866f954436 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -97,15 +97,15 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } } - if (!user_ok_token(vuser->user.unix_name, vuser->nt_user_token, snum)) + if (!user_ok_token(vuser->user.unix_name, vuser->server_info->ptok, + snum)) return(False); - readonly_share = is_share_read_only_for_token(vuser->user.unix_name, - vuser->nt_user_token, - SNUM(conn)); + readonly_share = is_share_read_only_for_token( + vuser->user.unix_name, vuser->server_info->ptok, SNUM(conn)); token = conn->nt_user_token ? - conn->nt_user_token : vuser->nt_user_token; + conn->nt_user_token : vuser->server_info->ptok; if (!readonly_share && !share_access_check(token, lp_servicename(snum), @@ -132,7 +132,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->read_only = readonly_share; ent->admin_user = token_contains_name_in_list( - vuser->user.unix_name, NULL, vuser->nt_user_token, + vuser->user.unix_name, NULL, vuser->server_info->ptok, lp_admin_users(SNUM(conn))); conn->read_only = ent->read_only; @@ -204,7 +204,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) gid = vuser->gid; num_groups = vuser->n_groups; group_list = vuser->groups; - token = vuser->nt_user_token; + token = vuser->server_info->ptok; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); -- cgit From c6d209f8342d56adc52a6c8ab99a4a2e17d409b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:43:10 +0200 Subject: Remove the unix token info from "struct user_struct" (This used to be commit aa2299d42adf4d27e707ac755e07be70d0af1bb4) --- source3/smbd/uid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 866f954436..0b87b93636 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -177,7 +177,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.ut.uid == vuser->uid)) { + (current_user.ut.uid == vuser->server_info->uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); return(True); @@ -200,10 +200,10 @@ bool change_to_user(connection_struct *conn, uint16 vuid) num_groups = conn->ngroups; token = conn->nt_user_token; } else if (vuser) { - uid = conn->admin_user ? 0 : vuser->uid; - gid = vuser->gid; - num_groups = vuser->n_groups; - group_list = vuser->groups; + uid = conn->admin_user ? 0 : vuser->server_info->uid; + gid = vuser->server_info->gid; + num_groups = vuser->server_info->n_groups; + group_list = vuser->server_info->groups; token = vuser->server_info->ptok; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " -- cgit From bec1dfab27be3db888eeb451b4547f16e08e93c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 17:42:39 +0200 Subject: Remove "userdom_struct user" from "struct user_struct" (This used to be commit 420de035237bb08bc470c9eb820f3da2edaa6805) --- source3/smbd/uid.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 0b87b93636..3779c3f608 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -97,12 +97,14 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } } - if (!user_ok_token(vuser->user.unix_name, vuser->server_info->ptok, + if (!user_ok_token(vuser->server_info->unix_name, + vuser->server_info->ptok, snum)) return(False); readonly_share = is_share_read_only_for_token( - vuser->user.unix_name, vuser->server_info->ptok, SNUM(conn)); + vuser->server_info->unix_name, vuser->server_info->ptok, + SNUM(conn)); token = conn->nt_user_token ? conn->nt_user_token : vuser->server_info->ptok; @@ -132,7 +134,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->read_only = readonly_share; ent->admin_user = token_contains_name_in_list( - vuser->user.unix_name, NULL, vuser->server_info->ptok, + vuser->server_info->unix_name, NULL, vuser->server_info->ptok, lp_admin_users(SNUM(conn))); conn->read_only = ent->read_only; @@ -188,7 +190,8 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if ((vuser) && !check_user_ok(conn, vuser, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", - vuser->user.smb_name, vuser->user.unix_name, vuid, + vuser->server_info->sanitized_username, + vuser->server_info->unix_name, vuid, lp_servicename(snum))); return False; } -- cgit From 89ac43d49859ef9169283341f2917e9100820bb4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 May 2008 14:16:06 +0200 Subject: Remove some unused code (This used to be commit 87383a4605ab99d32fccae7793dc5292b8f3e25b) --- source3/smbd/uid.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3779c3f608..78dff8ffee 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -22,29 +22,6 @@ /* what user is current? */ extern struct current_user current_user; -/**************************************************************************** - Iterator functions for getting all gid's from current_user. -****************************************************************************/ - -gid_t get_current_user_gid_first(int *piterator) -{ - *piterator = 0; - return current_user.ut.gid; -} - -gid_t get_current_user_gid_next(int *piterator) -{ - gid_t ret; - - if (!current_user.ut.groups || *piterator >= current_user.ut.ngroups) { - return (gid_t)-1; - } - - ret = current_user.ut.groups[*piterator]; - (*piterator) += 1; - return ret; -} - /**************************************************************************** Become the guest user without changing the security context stack. ****************************************************************************/ -- cgit From c881c866d656bacb30180b574f3634db26deb37a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 May 2008 15:51:42 +0200 Subject: Next try at making the vuid cache circular Jeremy, please check! (This used to be commit a34f73521712e3820d417f0d9ed811723b7681d6) --- source3/smbd/uid.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 78dff8ffee..ce8aaa33ea 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -65,9 +65,9 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) bool readonly_share; NT_USER_TOKEN *token; - for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { - if (conn->vuid_cache.array[i].vuid == vuser->vuid) { - ent = &conn->vuid_cache.array[i]; + for (i=0; ivuid_cache.array[i]; + if (ent->vuid == vuser->vuid) { conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; return(True); @@ -102,11 +102,11 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return False; } - i = conn->vuid_cache.entries % VUID_CACHE_SIZE; - if (conn->vuid_cache.entries < VUID_CACHE_SIZE) - conn->vuid_cache.entries++; + ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + + conn->vuid_cache.next_entry = + (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; - ent = &conn->vuid_cache.array[i]; ent->vuid = vuser->vuid; ent->read_only = readonly_share; -- cgit From e2b9ac714b0f7aeece4ebe8772b7f8380356818d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2008 11:47:43 +0200 Subject: Make use of talloc_tos() in change_to_user() (This used to be commit c4bed3a48b86d44ad641250add2fc189af7e72f5) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ce8aaa33ea..288ce50139 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -199,7 +199,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if((group_c = *lp_force_group(snum))) { - token = dup_nt_token(NULL, token); + token = dup_nt_token(talloc_tos(), token); if (token == NULL) { DEBUG(0, ("dup_nt_token failed\n")); return False; -- cgit From 0c2bf9521efcf066268016bdab5d7a30bf879e26 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2008 12:14:43 +0200 Subject: Empty some nonempty blank lines (This used to be commit 1a406def02bf171b223467d6b76317586d6205fc) --- source3/smbd/uid.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 288ce50139..2335bff9fd 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. uid/user handling Copyright (C) Andrew Tridgell 1992-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -36,21 +36,21 @@ bool change_to_guest(void) if (!pass) return(False); } - + #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ initgroups(pass->pw_name, pass->pw_gid); #endif - + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); - + current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; TALLOC_FREE(pass); pass = NULL; - + return True; } @@ -136,7 +136,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) NT_USER_TOKEN *token = NULL; int num_groups = 0; gid_t *group_list = NULL; - + if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); return(False); @@ -228,7 +228,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) gid_to_sid(&token->user_sids[1], gid); } } - + /* Now set current_user since we will immediately also call set_sec_ctx() */ @@ -250,7 +250,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n", (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid())); - + return(True); } @@ -310,29 +310,29 @@ struct conn_ctx { connection_struct *conn; uint16 vuid; }; - + /* A stack of current_user connection contexts. */ - + static struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH]; static int conn_ctx_stack_ndx; static void push_conn_ctx(void) { struct conn_ctx *ctx_p; - + /* Check we don't overflow our stack */ - + if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) { DEBUG(0, ("Connection context stack overflow!\n")); smb_panic("Connection context stack overflow!\n"); } - + /* Store previous user context */ ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx]; - + ctx_p->conn = current_user.conn; ctx_p->vuid = current_user.vuid; - + DEBUG(3, ("push_conn_ctx(%u) : conn_ctx_stack_ndx = %d\n", (unsigned int)ctx_p->vuid, conn_ctx_stack_ndx )); @@ -342,7 +342,7 @@ static void push_conn_ctx(void) static void pop_conn_ctx(void) { struct conn_ctx *ctx_p; - + /* Check for stack underflow. */ if (conn_ctx_stack_ndx == 0) { -- cgit From 776caa081bc36aac0ab7cc826836740f5bf0bf24 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2008 15:09:02 +0200 Subject: Replace nt_user_token with server_info in connection_struct (This used to be commit a3738aef59e97d4533010b048534d937d36c0950) --- source3/smbd/uid.c | 58 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2335bff9fd..8a4a54f867 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -56,6 +56,9 @@ bool change_to_guest(void) /******************************************************************* Check if a username is OK. + + This sets up conn->server_info with a copy related to this vuser that + later code can then mess with. ********************************************************************/ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) @@ -63,11 +66,11 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) unsigned int i; struct vuid_cache_entry *ent = NULL; bool readonly_share; - NT_USER_TOKEN *token; for (i=0; ivuid_cache.array[i]; if (ent->vuid == vuser->vuid) { + conn->server_info = ent->server_info; conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; return(True); @@ -83,11 +86,8 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) vuser->server_info->unix_name, vuser->server_info->ptok, SNUM(conn)); - token = conn->nt_user_token ? - conn->nt_user_token : vuser->server_info->ptok; - if (!readonly_share && - !share_access_check(token, lp_servicename(snum), + !share_access_check(vuser->server_info->ptok, lp_servicename(snum), FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ @@ -96,7 +96,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) "security descriptor\n")); } - if (!share_access_check(token, lp_servicename(snum), + if (!share_access_check(vuser->server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; @@ -107,6 +107,14 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) conn->vuid_cache.next_entry = (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + TALLOC_FREE(ent->server_info); + + ent->server_info = copy_serverinfo(conn, vuser->server_info); + if (ent->server_info == NULL) { + ent->vuid = UID_FIELD_INVALID; + return false; + } + ent->vuid = vuser->vuid; ent->read_only = readonly_share; @@ -116,6 +124,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; + conn->server_info = ent->server_info; return(True); } @@ -132,8 +141,6 @@ bool change_to_user(connection_struct *conn, uint16 vuid) gid_t gid; uid_t uid; char group_c; - bool must_free_token = False; - NT_USER_TOKEN *token = NULL; int num_groups = 0; gid_t *group_list = NULL; @@ -173,18 +180,21 @@ bool change_to_user(connection_struct *conn, uint16 vuid) return False; } + /* + * conn->server_info is now correctly set up with a copy we can mess + * with for force_group etc. + */ + if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; group_list = conn->groups; num_groups = conn->ngroups; - token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->server_info->uid; - gid = vuser->server_info->gid; - num_groups = vuser->server_info->n_groups; - group_list = vuser->server_info->groups; - token = vuser->server_info->ptok; + gid = conn->server_info->gid; + num_groups = conn->server_info->n_groups; + group_list = conn->server_info->groups; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); @@ -199,13 +209,6 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if((group_c = *lp_force_group(snum))) { - token = dup_nt_token(talloc_tos(), token); - if (token == NULL) { - DEBUG(0, ("dup_nt_token failed\n")); - return False; - } - must_free_token = True; - if(group_c == '+') { /* @@ -219,13 +222,15 @@ bool change_to_user(connection_struct *conn, uint16 vuid) for (i = 0; i < num_groups; i++) { if (group_list[i] == conn->gid) { gid = conn->gid; - gid_to_sid(&token->user_sids[1], gid); + gid_to_sid(&conn->server_info->ptok + ->user_sids[1], gid); break; } } } else { gid = conn->gid; - gid_to_sid(&token->user_sids[1], gid); + gid_to_sid(&conn->server_info->ptok->user_sids[1], + gid); } } @@ -236,14 +241,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) current_user.ut.groups = group_list; set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, - token); - - /* - * Free the new token (as set_sec_ctx copies it). - */ - - if (must_free_token) - TALLOC_FREE(token); + conn->server_info->ptok); current_user.conn = conn; current_user.vuid = vuid; -- cgit From 53a623d8a69b5dd7fbd964013032878e09032375 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2008 15:53:55 +0200 Subject: Remove the unix token info from connection_struct (This used to be commit 2834dacc8d49f77fe55fb5d7e3eb2dda431d1d3d) --- source3/smbd/uid.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8a4a54f867..004e48a44f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -157,7 +157,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) */ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->uid)) { + (current_user.ut.uid == conn->server_info->uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); return(True); @@ -186,10 +186,10 @@ bool change_to_user(connection_struct *conn, uint16 vuid) */ if (conn->force_user) /* security = share sets this too */ { - uid = conn->uid; - gid = conn->gid; - group_list = conn->groups; - num_groups = conn->ngroups; + uid = conn->server_info->uid; + gid = conn->server_info->gid; + group_list = conn->server_info->groups; + num_groups = conn->server_info->n_groups; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->server_info->uid; gid = conn->server_info->gid; @@ -220,15 +220,15 @@ bool change_to_user(connection_struct *conn, uint16 vuid) int i; for (i = 0; i < num_groups; i++) { - if (group_list[i] == conn->gid) { - gid = conn->gid; + if (group_list[i] == conn->server_info->gid) { + gid = conn->server_info->gid; gid_to_sid(&conn->server_info->ptok ->user_sids[1], gid); break; } } } else { - gid = conn->gid; + gid = conn->server_info->gid; gid_to_sid(&conn->server_info->ptok->user_sids[1], gid); } -- cgit From aac9e7d1cafc7be5abdbc73a238b7585cdba4708 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 May 2008 00:25:27 +0200 Subject: With force user, we have the same base token for all vuids (This used to be commit 0f19bc3f65bfc132aea1de1e76fcb4ee625a050f) --- source3/smbd/uid.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 004e48a44f..310ad4d23a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -109,7 +109,15 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) TALLOC_FREE(ent->server_info); - ent->server_info = copy_serverinfo(conn, vuser->server_info); + /* + * If force_user was set, all server_info's are based on the same + * username-based faked one. + */ + + ent->server_info = copy_serverinfo( + conn, + conn->force_user ? conn->server_info : vuser->server_info); + if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; return false; -- cgit From 320fadd8fc600262d26ea417a92d395aeb16ef57 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 May 2008 01:03:45 +0200 Subject: Remove the reference to current_user_info from share_access.c This required to pass around the domain a bit (This used to be commit 17b0db20d28d1b737c5e86b78106657e8ca5ce9c) --- source3/smbd/uid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 310ad4d23a..b0f8cb224b 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -78,12 +78,15 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } if (!user_ok_token(vuser->server_info->unix_name, + pdb_get_domain(vuser->server_info->sam_account), vuser->server_info->ptok, snum)) return(False); readonly_share = is_share_read_only_for_token( - vuser->server_info->unix_name, vuser->server_info->ptok, + vuser->server_info->unix_name, + pdb_get_domain(vuser->server_info->sam_account), + vuser->server_info->ptok, SNUM(conn)); if (!readonly_share && @@ -127,7 +130,9 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->read_only = readonly_share; ent->admin_user = token_contains_name_in_list( - vuser->server_info->unix_name, NULL, vuser->server_info->ptok, + vuser->server_info->unix_name, + pdb_get_domain(vuser->server_info->sam_account), + NULL, vuser->server_info->ptok, lp_admin_users(SNUM(conn))); conn->read_only = ent->read_only; -- cgit From ad538bf0ab4ae10ff10ea71898875d2d35e25dea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:35:22 +0200 Subject: Compare the pointer "vuser" to NULL, not 0 (This used to be commit 5c916549f002d5e4e06f24d396a2bdca73d384c7) --- source3/smbd/uid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b0f8cb224b..04796418bc 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -175,7 +175,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) "user\n")); return(True); } else if ((current_user.conn == conn) && - (vuser != 0) && (current_user.vuid == vuid) && + (vuser != NULL) && (current_user.vuid == vuid) && (current_user.ut.uid == vuser->server_info->uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); -- cgit From b935f4a2dca62d197195573ed868abe657a71993 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:43:03 +0200 Subject: Consistently use snum in check_user_ok Most already used it, these two still used SNUM(conn), where the only caller of this routine (change_to_user) had set snum = SNUM(conn). (This used to be commit b14e59bfdbfb62494002e22d0665c4d420484245) --- source3/smbd/uid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 04796418bc..af992d7aee 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -87,7 +87,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) vuser->server_info->unix_name, pdb_get_domain(vuser->server_info->sam_account), vuser->server_info->ptok, - SNUM(conn)); + snum); if (!readonly_share && !share_access_check(vuser->server_info->ptok, lp_servicename(snum), @@ -133,7 +133,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) vuser->server_info->unix_name, pdb_get_domain(vuser->server_info->sam_account), NULL, vuser->server_info->ptok, - lp_admin_users(SNUM(conn))); + lp_admin_users(snum)); conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; -- cgit From ee6ee96af2cf6a5bf2b825883a9cb5f2ff64de5b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:46:25 +0200 Subject: Group the access checks together in check_user_ok() (This used to be commit 45662b5e8b3c7bc39cb33c5d7deb7e9a91f30a8b) --- source3/smbd/uid.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index af992d7aee..54caca9405 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -66,6 +66,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) unsigned int i; struct vuid_cache_entry *ent = NULL; bool readonly_share; + bool admin_user; for (i=0; ivuid_cache.array[i]; @@ -105,6 +106,12 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) return False; } + admin_user = token_contains_name_in_list( + vuser->server_info->unix_name, + pdb_get_domain(vuser->server_info->sam_account), + NULL, vuser->server_info->ptok, + lp_admin_users(snum)); + ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; conn->vuid_cache.next_entry = @@ -128,12 +135,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) ent->vuid = vuser->vuid; ent->read_only = readonly_share; - - ent->admin_user = token_contains_name_in_list( - vuser->server_info->unix_name, - pdb_get_domain(vuser->server_info->sam_account), - NULL, vuser->server_info->ptok, - lp_admin_users(snum)); + ent->admin_user = admin_user; conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; -- cgit From 82d4806ce62a78b0eecc4805b7ecf7f77b196864 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:55:02 +0200 Subject: Slight refactoring for check_user_ok: It only needs vuid and server_info (This used to be commit 68944ea1ea7a0a63b08cbfc703f5ee29d2627696) --- source3/smbd/uid.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 54caca9405..bded780c49 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -61,7 +61,9 @@ bool change_to_guest(void) later code can then mess with. ********************************************************************/ -static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) +static bool check_user_ok(connection_struct *conn, uint16_t vuid, + struct auth_serversupplied_info *server_info, + int snum) { unsigned int i; struct vuid_cache_entry *ent = NULL; @@ -70,7 +72,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) for (i=0; ivuid_cache.array[i]; - if (ent->vuid == vuser->vuid) { + if (ent->vuid == vuid) { conn->server_info = ent->server_info; conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; @@ -78,20 +80,18 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) } } - if (!user_ok_token(vuser->server_info->unix_name, - pdb_get_domain(vuser->server_info->sam_account), - vuser->server_info->ptok, - snum)) + if (!user_ok_token(server_info->unix_name, + pdb_get_domain(server_info->sam_account), + server_info->ptok, snum)) return(False); readonly_share = is_share_read_only_for_token( - vuser->server_info->unix_name, - pdb_get_domain(vuser->server_info->sam_account), - vuser->server_info->ptok, - snum); + server_info->unix_name, + pdb_get_domain(server_info->sam_account), + server_info->ptok, snum); if (!readonly_share && - !share_access_check(vuser->server_info->ptok, lp_servicename(snum), + !share_access_check(server_info->ptok, lp_servicename(snum), FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ @@ -100,17 +100,16 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) "security descriptor\n")); } - if (!share_access_check(vuser->server_info->ptok, lp_servicename(snum), + if (!share_access_check(server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } admin_user = token_contains_name_in_list( - vuser->server_info->unix_name, - pdb_get_domain(vuser->server_info->sam_account), - NULL, vuser->server_info->ptok, - lp_admin_users(snum)); + server_info->unix_name, + pdb_get_domain(server_info->sam_account), + NULL, server_info->ptok, lp_admin_users(snum)); ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; @@ -125,15 +124,14 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) */ ent->server_info = copy_serverinfo( - conn, - conn->force_user ? conn->server_info : vuser->server_info); + conn, conn->force_user ? conn->server_info : server_info); if (ent->server_info == NULL) { ent->vuid = UID_FIELD_INVALID; return false; } - ent->vuid = vuser->vuid; + ent->vuid = vuid; ent->read_only = readonly_share; ent->admin_user = admin_user; @@ -186,7 +184,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); - if ((vuser) && !check_user_ok(conn, vuser, snum)) { + if ((vuser) && !check_user_ok(conn, vuid, vuser->server_info, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", vuser->server_info->sanitized_username, -- cgit From 101162257c14338eb2df7f331b18bca41813bff7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:59:07 +0200 Subject: Move connection-specific vuid cache clear to uid.c (This used to be commit 1025f687910ce40283c7344ed67ebd5bf31217b7) --- source3/smbd/uid.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index bded780c49..2bc5595661 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -142,6 +142,28 @@ static bool check_user_ok(connection_struct *conn, uint16_t vuid, return(True); } +/**************************************************************************** + Clear a vuid out of the connection's vuid cache +****************************************************************************/ + +void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) +{ + int i; + + for (i=0; ivuid_cache.array[i]; + + if (ent->vuid == vuid) { + ent->vuid = UID_FIELD_INVALID; + TALLOC_FREE(ent->server_info); + ent->read_only = False; + ent->admin_user = False; + } + } +} + /**************************************************************************** Become the user of a connection number without changing the security context stack, but modify the current_user entries. -- cgit From 40f5eab5eb515937e1b23cf6762b77c194d29b9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Jun 2008 16:54:12 +0200 Subject: Wrap the unix token info in a unix_user_token in auth_serversupplied_info No functional change, this is a preparation for more current_user ref removal (This used to be commit dcaedf345e62ab74ea87f0a3fa1e3199c75c5445) --- source3/smbd/uid.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'source3/smbd/uid.c') diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2bc5595661..8998f6a371 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -192,13 +192,13 @@ bool change_to_user(connection_struct *conn, uint16 vuid) */ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) && - (current_user.ut.uid == conn->server_info->uid)) { + (current_user.ut.uid == conn->server_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->server_info->uid)) { + (current_user.ut.uid == vuser->server_info->utok.uid)) { DEBUG(4,("change_to_user: Skipping user change - already " "user\n")); return(True); @@ -221,15 +221,15 @@ bool change_to_user(connection_struct *conn, uint16 vuid) */ if (conn->force_user) /* security = share sets this too */ { - uid = conn->server_info->uid; - gid = conn->server_info->gid; - group_list = conn->server_info->groups; - num_groups = conn->server_info->n_groups; + uid = conn->server_info->utok.uid; + gid = conn->server_info->utok.gid; + group_list = conn->server_info->utok.groups; + num_groups = conn->server_info->utok.ngroups; } else if (vuser) { - uid = conn->admin_user ? 0 : vuser->server_info->uid; - gid = conn->server_info->gid; - num_groups = conn->server_info->n_groups; - group_list = conn->server_info->groups; + uid = conn->admin_user ? 0 : vuser->server_info->utok.uid; + gid = conn->server_info->utok.gid; + num_groups = conn->server_info->utok.ngroups; + group_list = conn->server_info->utok.groups; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); @@ -255,15 +255,16 @@ bool change_to_user(connection_struct *conn, uint16 vuid) int i; for (i = 0; i < num_groups; i++) { - if (group_list[i] == conn->server_info->gid) { - gid = conn->server_info->gid; + if (group_list[i] + == conn->server_info->utok.gid) { + gid = conn->server_info->utok.gid; gid_to_sid(&conn->server_info->ptok ->user_sids[1], gid); break; } } } else { - gid = conn->server_info->gid; + gid = conn->server_info->utok.gid; gid_to_sid(&conn->server_info->ptok->user_sids[1], gid); } -- cgit