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/chgpasswd.c | 58 +++---- source3/smbd/dfree.c | 231 +++++++++++++++++++++++++++ source3/smbd/dir.c | 301 ++--------------------------------- source3/smbd/ipc.c | 4 +- source3/smbd/password.c | 107 ++++--------- source3/smbd/quotas.c | 6 +- source3/smbd/server.c | 403 +++++++---------------------------------------- source3/smbd/smbrun.c | 9 +- source3/smbd/ssl.c | 6 +- source3/smbd/uid.c | 279 +++++++++----------------------- source3/smbd/vt_mode.c | 12 +- 11 files changed, 440 insertions(+), 976 deletions(-) create mode 100644 source3/smbd/dfree.c (limited to 'source3/smbd') diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 560d989b47..af6746a699 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -51,25 +51,20 @@ extern int DEBUGLEVEL; -#ifdef ALLOW_CHANGE_PASSWORD - +#if ALLOW_CHANGE_PASSWORD #define MINPASSWDLENGTH 5 #define BUFSIZE 512 static int findpty(char **slave) { int master; -#if defined(USE_GRANTPT) -#if defined(SVR4) || defined(SUNOS5) - extern char *ptsname(); -#endif /* defined(SVR4) || defined(SUNOS5) */ -#else /* USE_GRANTPT */ +#ifndef HAVE_GRANTPT static fstring line; void *dirp; char *dpname; -#endif /* USE_GRANTPT */ +#endif /* !HAVE_GRANTPT */ -#if defined(USE_GRANTPT) +#if defined(HAVE_GRANTPT) if ((master = open("/dev/ptmx", O_RDWR)) >= 1) { grantpt(master); unlockpt(master); @@ -82,7 +77,7 @@ static int findpty(char **slave) return (master); } } -#else /* USE_GRANTPT */ +#else /* HAVE_GRANTPT */ fstrcpy( line, "/dev/ptyXX" ); dirp = OpenDir(-1, "/dev", False); @@ -102,7 +97,7 @@ static int findpty(char **slave) } } CloseDir(dirp); -#endif /* USE_GRANTPT */ +#endif /* HAVE_GRANTPT */ return (-1); } @@ -122,11 +117,11 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram, gid = pass->pw_gid; uid = pass->pw_uid; -#ifdef USE_SETRES +#ifdef HAVE_SETRESUID setresuid(0,0,0); -#else /* USE_SETRES */ +#else setuid(0); -#endif /* USE_SETRES */ +#endif /* Start new session - gets rid of controlling terminal. */ if (setsid() < 0) { @@ -140,17 +135,15 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram, slavedev)); return(False); } -#if defined(SVR4) || defined(SUNOS5) || defined(SCO) +#ifdef I_PUSH ioctl(slave, I_PUSH, "ptem"); ioctl(slave, I_PUSH, "ldterm"); -#else /* defined(SVR4) || defined(SUNOS5) || defined(SCO) */ -#if defined(TIOCSCTTY) +#elif defined(TIOCSCTTY) if (ioctl(slave,TIOCSCTTY,0) <0) { DEBUG(3,("Error in ioctl call for slave pty\n")); /* return(False); */ } -#endif /* defined(TIOCSCTTY) */ -#endif /* defined(SVR4) || defined(SUNOS5) || defined(SCO) */ +#endif /* Close master. */ close(master); @@ -188,18 +181,18 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram, /* make us completely into the right uid */ if(!as_root) { -#ifdef USE_SETRES - setresgid(0,0,0); - setresuid(0,0,0); - setresgid(gid,gid,gid); - setresuid(uid,uid,uid); +#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); + setuid(0); + seteuid(0); + setgid(gid); + setegid(gid); + setuid(uid); + seteuid(uid); #endif } @@ -391,13 +384,8 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root) return (False); /* inform the user */ } -#if (defined(PASSWD_PROGRAM) && defined(PASSWD_CHAT)) - pstrcpy(passwordprogram,PASSWD_PROGRAM); - pstrcpy(chatsequence,PASSWD_CHAT); -#else pstrcpy(passwordprogram,lp_passwd_program()); pstrcpy(chatsequence,lp_passwd_chat()); -#endif if (!*chatsequence) { DEBUG(2,("Null chat sequence - no password changing\n")); diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c new file mode 100644 index 0000000000..799ff6a24c --- /dev/null +++ b/source3/smbd/dfree.c @@ -0,0 +1,231 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + functions to calculate the free disk space + Copyright (C) Andrew Tridgell 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 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" + + +extern int DEBUGLEVEL; + +/**************************************************************************** +normalise for DOS usage +****************************************************************************/ +static void disk_norm(int *bsize,int *dfree,int *dsize) +{ + /* check if the disk is beyond the max disk size */ + int maxdisksize = lp_maxdisksize(); + if (maxdisksize) { + /* convert to blocks - and don't overflow */ + maxdisksize = ((maxdisksize*1024)/(*bsize))*1024; + if (*dsize > maxdisksize) *dsize = maxdisksize; + if (*dfree > maxdisksize) *dfree = maxdisksize-1; + /* the -1 should stop applications getting div by 0 + errors */ + } + + while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) { + *dfree /= 2; + *dsize /= 2; + *bsize *= 2; + if (*bsize > WORDMAX) { + *bsize = WORDMAX; + if (*dsize > WORDMAX) + *dsize = WORDMAX; + if (*dfree > WORDMAX) + *dfree = WORDMAX; + break; + } + } +} + + +/* Return the number of TOSIZE-byte blocks used by + BLOCKS FROMSIZE-byte blocks, rounding away from zero. + TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */ +static int adjust_blocks(int blocks, int fromsize, int tosize) +{ + if (tosize <= 0 || fromsize <= 0) { + return -1; + } + + if (fromsize == tosize) /* e.g., from 512 to 512 */ + return blocks; + else if (fromsize > tosize) /* e.g., from 2048 to 512 */ + return blocks * (fromsize / tosize); + else /* e.g., from 256 to 512 */ + return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); +} + +/* this does all of the system specific guff to get the free disk space. + It is derived from code in the GNU fileutils package, but has been + considerably mangled for use here + + results are returned in *dfree and *dsize, in 512 byte units +*/ +static int fsusage(const char *path, int *dfree, int *dsize) +{ +#ifdef STAT_STATFS3_OSF1 +#define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512) + struct statfs fsd; + + if (statfs (path, &fsd, sizeof (struct statfs)) != 0) + return -1; +#endif /* STAT_STATFS3_OSF1 */ + +#ifdef STAT_STATFS2_FS_DATA /* Ultrix */ +#define CONVERT_BLOCKS(B) adjust_blocks ((B), 1024, 512) + struct fs_data fsd; + + if (statfs (path, &fsd) != 1) + return -1; + + (*dsize) = CONVERT_BLOCKS (fsd.fd_req.btot); + (*dfree) = CONVERT_BLOCKS (fsd.fd_req.bfreen); +#endif /* STAT_STATFS2_FS_DATA */ + +#ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */ +#define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512) + struct statfs fsd; + + if (statfs (path, &fsd) < 0) + return -1; + +#ifdef STATFS_TRUNCATES_BLOCK_COUNTS + /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the + struct statfs are truncated to 2GB. These conditions detect that + truncation, presumably without botching the 4.1.1 case, in which + the values are not truncated. The correct counts are stored in + undocumented spare fields. */ + if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0) { + fsd.f_blocks = fsd.f_spare[0]; + fsd.f_bfree = fsd.f_spare[1]; + fsd.f_bavail = fsd.f_spare[2]; + } +#endif /* STATFS_TRUNCATES_BLOCK_COUNTS */ +#endif /* STAT_STATFS2_BSIZE */ + + +#ifdef STAT_STATFS2_FSIZE /* 4.4BSD */ +#define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_fsize, 512) + + struct statfs fsd; + + if (statfs (path, &fsd) < 0) + return -1; +#endif /* STAT_STATFS2_FSIZE */ + +#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */ +# if _AIX || defined(_CRAY) +# define CONVERT_BLOCKS(B) adjust_blocks ((B), fsd.f_bsize, 512) +# ifdef _CRAY +# define f_bavail f_bfree +# endif +# else +# define CONVERT_BLOCKS(B) (B) +# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx */ +# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */ +# define f_bavail f_bfree +# endif +# endif +# endif + + struct statfs fsd; + + if (statfs (path, &fsd, sizeof fsd, 0) < 0) + return -1; + /* Empirically, the block counts on most SVR3 and SVR3-derived + systems seem to always be in terms of 512-byte blocks, + no matter what value f_bsize has. */ + +#endif /* STAT_STATFS4 */ + +#ifdef STAT_STATVFS /* SVR4 */ +# define CONVERT_BLOCKS(B) \ + adjust_blocks ((B), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512) + + struct statvfs fsd; + + if (statvfs (path, &fsd) < 0) + return -1; + /* f_frsize isn't guaranteed to be supported. */ + +#endif /* STAT_STATVFS */ + +#ifndef CONVERT_BLOCKS + /* we don't have any dfree code! */ + return -1; +#else +#if !defined(STAT_STATFS2_FS_DATA) + /* !Ultrix */ + (*dsize) = CONVERT_BLOCKS (fsd.f_blocks); + (*dfree) = CONVERT_BLOCKS (fsd.f_bavail); +#endif /* not STAT_STATFS2_FS_DATA */ +#endif + + return 0; +} + +/**************************************************************************** + return number of 1K blocks available on a path and total number +****************************************************************************/ +static int disk_free(char *path,int *bsize,int *dfree,int *dsize) +{ + int dfree_retval; + + (*dfree) = (*dsize) = 0; + (*bsize) = 512; + + fsusage(path, dfree, dsize); + + if (*bsize < 256) { + *bsize = 512; + } + + if ((*dsize)<1) { + static int done; + if (!done) { + DEBUG(0,("WARNING: dfree is broken on this system\n")); + done=1; + } + *dsize = 20*1024*1024/(*bsize); + *dfree = MAX(1,*dfree); + } + + disk_norm(bsize,dfree,dsize); + + if ((*bsize) < 1024) { + dfree_retval = (*dfree)/(1024/(*bsize)); + } else { + dfree_retval = ((*bsize)/1024)*(*dfree); + } + + return(dfree_retval); +} + + +/**************************************************************************** +wrap it to get filenames right +****************************************************************************/ +int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize) +{ + return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize)); +} + + diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ceb9ae7633..44e0556f20 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -30,7 +30,7 @@ extern connection_struct Connections[]; -uint32 dircounter = 0; +static uint32 dircounter = 0; #define NUMDIRPTRS 256 @@ -723,7 +723,7 @@ char *DirCacheCheck( char *path, char *name, int snum ) return(NULL); } /* DirCacheCheck */ -void DirCacheFlush( int snum ) +void DirCacheFlush(int snum) /* ------------------------------------------------------------------------ ** * Remove all cache entries which have an snum that matches the input. * @@ -733,18 +733,18 @@ void DirCacheFlush( int snum ) * * ------------------------------------------------------------------------ ** */ - { - dir_cache_entry *entry; - ubi_dlNodePtr next; - - for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); NULL != entry; ) - { - next = ubi_dlNext( entry ); - if( entry->snum == snum ) - free( ubi_dlRemThis( dir_cache, entry ) ); - entry = (dir_cache_entry *)next; - } - } /* DirCacheFlush */ +{ + dir_cache_entry *entry; + ubi_dlNodePtr next; + + for(entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); + NULL != entry; ) { + next = ubi_dlNext( entry ); + if( entry->snum == snum ) + free( ubi_dlRemThis( dir_cache, entry ) ); + entry = (dir_cache_entry *)next; + } +} /* DirCacheFlush */ /* -------------------------------------------------------------------------- ** * End of the section that manages the global directory cache. @@ -752,276 +752,3 @@ void DirCacheFlush( int snum ) */ -#ifdef REPLACE_GETWD -/* This is getcwd.c from bash. It is needed in Interactive UNIX. To - * add support for another OS you need to determine which of the - * conditional compilation macros you need to define. All the options - * are defined for Interactive UNIX. - */ -#ifdef ISC -#define HAVE_UNISTD_H -#define USGr3 -#define USG -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (__STDC__) -# define CONST const -# define PTR void * -#else /* !__STDC__ */ -# define CONST -# define PTR char * -#endif /* !__STDC__ */ - -#if !defined (PATH_MAX) -# if defined (MAXPATHLEN) -# define PATH_MAX MAXPATHLEN -# else /* !MAXPATHLEN */ -# define PATH_MAX 1024 -# endif /* !MAXPATHLEN */ -#endif /* !PATH_MAX */ - -#if defined (_POSIX_VERSION) || defined (USGr3) || defined (HAVE_DIRENT_H) -# if !defined (HAVE_DIRENT) -# define HAVE_DIRENT -# endif /* !HAVE_DIRENT */ -#endif /* _POSIX_VERSION || USGr3 || HAVE_DIRENT_H */ - -#if defined (HAVE_DIRENT) -# define D_NAMLEN(d) (strlen ((d)->d_name)) -#else -# define D_NAMLEN(d) ((d)->d_namlen) -#endif /* ! (_POSIX_VERSION || USGr3) */ - -#if defined (USG) || defined (USGr3) -# define d_fileno d_ino -#endif - -#if !defined (alloca) -extern char *alloca (); -#endif /* alloca */ - -/* Get the pathname of the current working directory, - and put it in SIZE bytes of BUF. Returns NULL if the - directory couldn't be determined or SIZE was too small. - If successful, returns BUF. In GNU, if BUF is NULL, - an array is allocated with `malloc'; the array is SIZE - bytes long, unless SIZE <= 0, in which case it is as - big as necessary. */ -#if defined (__STDC__) -char * -getcwd (char *buf, size_t size) -#else /* !__STDC__ */ -char * -getcwd (buf, size) - char *buf; - int size; -#endif /* !__STDC__ */ -{ - static CONST char dots[] - = "../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../.."; - CONST char *dotp, *dotlist; - size_t dotsize; - dev_t rootdev, thisdev; - ino_t rootino, thisino; - char path[PATH_MAX + 1]; - register char *pathp; - char *pathbuf; - size_t pathsize; - struct stat st; - - if (buf != NULL && size == 0) - { - errno = EINVAL; - return ((char *)NULL); - } - - pathsize = sizeof (path); - pathp = &path[pathsize]; - *--pathp = '\0'; - pathbuf = path; - - if (stat (".", &st) < 0) - return ((char *)NULL); - thisdev = st.st_dev; - thisino = st.st_ino; - - if (stat ("/", &st) < 0) - return ((char *)NULL); - rootdev = st.st_dev; - rootino = st.st_ino; - - dotsize = sizeof (dots) - 1; - dotp = &dots[sizeof (dots)]; - dotlist = dots; - while (!(thisdev == rootdev && thisino == rootino)) - { - register DIR *dirstream; - register struct dirent *d; - dev_t dotdev; - ino_t dotino; - char mount_point; - int namlen; - - /* Look at the parent directory. */ - if (dotp == dotlist) - { - /* My, what a deep directory tree you have, Grandma. */ - char *new; - if (dotlist == dots) - { - new = malloc (dotsize * 2 + 1); - if (new == NULL) - goto lose; - memcpy (new, dots, dotsize); - } - else - { - new = realloc ((PTR) dotlist, dotsize * 2 + 1); - if (new == NULL) - goto lose; - } - memcpy (&new[dotsize], new, dotsize); - dotp = &new[dotsize]; - dotsize *= 2; - new[dotsize] = '\0'; - dotlist = new; - } - - dotp -= 3; - - /* Figure out if this directory is a mount point. */ - if (stat (dotp, &st) < 0) - goto lose; - dotdev = st.st_dev; - dotino = st.st_ino; - mount_point = dotdev != thisdev; - - /* Search for the last directory. */ - dirstream = opendir(dotp); - if (dirstream == NULL) - goto lose; - while ((d = (struct dirent *)readdir(dirstream)) != NULL) - { - if (d->d_name[0] == '.' && - (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; - if (mount_point || d->d_fileno == thisino) - { - char *name; - - namlen = D_NAMLEN(d); - name = (char *) - alloca (dotlist + dotsize - dotp + 1 + namlen + 1); - memcpy (name, dotp, dotlist + dotsize - dotp); - name[dotlist + dotsize - dotp] = '/'; - memcpy (&name[dotlist + dotsize - dotp + 1], - d->d_name, namlen + 1); - if (lstat (name, &st) < 0) - { - int save = errno; - closedir(dirstream); - errno = save; - goto lose; - } - if (st.st_dev == thisdev && st.st_ino == thisino) - break; - } - } - if (d == NULL) - { - int save = errno; - closedir(dirstream); - errno = save; - goto lose; - } - else - { - size_t space; - - while ((space = pathp - pathbuf) <= namlen) - { - char *new; - - if (pathbuf == path) - { - new = malloc (pathsize * 2); - if (!new) - goto lose; - } - else - { - new = realloc ((PTR) pathbuf, (pathsize * 2)); - if (!new) - goto lose; - pathp = new + space; - } - (void) memcpy (new + pathsize + space, pathp, pathsize - space); - pathp = new + pathsize + space; - pathbuf = new; - pathsize *= 2; - } - - pathp -= namlen; - (void) memcpy (pathp, d->d_name, namlen); - *--pathp = '/'; - closedir(dirstream); - } - - thisdev = dotdev; - thisino = dotino; - } - - if (pathp == &path[sizeof(path) - 1]) - *--pathp = '/'; - - if (dotlist != dots) - free ((PTR) dotlist); - - { - size_t len = pathbuf + pathsize - pathp; - if (buf == NULL) - { - if (len < (size_t) size) - len = size; - buf = (char *) malloc (len); - if (buf == NULL) - goto lose2; - } - else if ((size_t) size < len) - { - errno = ERANGE; - goto lose2; - } - (void) memcpy((PTR) buf, (PTR) pathp, len); - } - - if (pathbuf != path) - free (pathbuf); - - return (buf); - - lose: - if ((dotlist != dots) && dotlist) - { - int e = errno; - free ((PTR) dotlist); - errno = e; - } - - lose2: - if ((pathbuf != path) && pathbuf) - { - int e = errno; - free ((PTR) pathbuf); - errno = e; - } - return ((char *)NULL); -} -#endif diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 8b06fc91a3..adc3fcdcb5 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -342,7 +342,7 @@ static BOOL init_package(struct pack_desc* p, int count, int subcount) return(p->errcode == NERR_Success); } -#ifdef __STDC__ +#ifdef HAVE_STDARG_H static int package(struct pack_desc* p, ...) { #else @@ -357,7 +357,7 @@ va_dcl int is_string=0, stringused; int32 temp; -#ifdef __STDC__ +#ifdef HAVE_STDARG_H va_start(args,p); #else va_start(args); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 711729f86d..aae398dbda 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,7 @@ #include "includes.h" -#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) #include "rpcsvc/ypclnt.h" #endif @@ -347,44 +347,6 @@ void add_session_user(char *user) } -#ifdef NO_GETSPNAM -/* a fake shadow password routine which just fills a fake spwd struct - * with the sp_pwdp field. (sreiz@aie.nl) - */ -static struct spwd *getspnam(char *username) /* fake shadow password routine */ -{ - FILE *f; - char line[1024]; - static fstring pw; - static struct spwd static_spwd; - - static_spwd.sp_pwdp=0; - if (!(f=fopen("/etc/master.passwd", "r"))) - return 0; - while (fgets(line, 1024, f)) { - if (!strncmp(line, username, strlen(username)) && - line[strlen(username)]==':') { /* found entry */ - char *p, *q; - - p=line+strlen(username)+1; - if ((q=strchr(p, ':'))) { - *q=0; - if (q-p+1>20) - break; - fstrcpy(pw, p); - static_spwd.sp_pwdp=pw; - } - break; - } - } - fclose(f); - if (static_spwd.sp_pwdp) - return &static_spwd; - return 0; -} -#endif - - #ifdef OSF1_ENH_SEC /**************************************************************************** an enhanced crypt for OSF1 @@ -480,7 +442,7 @@ static void update_protected_database( char *user, BOOL result) } -#ifdef USE_PAM +#ifdef HAVE_PAM /******************************************************************* check on PAM authentication ********************************************************************/ @@ -583,7 +545,7 @@ static BOOL pam_auth(char *this_user,char *password) #endif -#ifdef AFS_AUTH +#ifdef WITH_AFS /******************************************************************* check on AFS authentication ********************************************************************/ @@ -610,7 +572,7 @@ static BOOL afs_auth(char *this_user,char *password) #endif -#ifdef DFS_AUTH +#ifdef WITH_DFS /***************************************************************** This new version of the DFS_AUTH code was donated by Karsten Muuss @@ -645,7 +607,7 @@ static BOOL dfs_auth(char *this_user,char *password) if (dcelogin_atmost_once) return(False); -#ifndef NO_CRYPT +#ifdef HAVE_CRYPT /* * We only go for a DCE login context if the given password * matches that stored in the local password file.. @@ -1099,24 +1061,24 @@ core of password checking routine BOOL password_check(char *password) { -#ifdef USE_PAM +#ifdef HAVE_PAM /* This falls through if the password check fails - - if NO_CRYPT is defined this causes an error msg + - if HAVE_CRYPT is not defined this causes an error msg saying Warning - no crypt available - - if NO_CRYPT is NOT defined this is a potential security hole + - if HAVE_CRYPT is defined this is a potential security hole as it may authenticate via the crypt call when PAM settings say it should fail. - if (pam_auth(this_user,password)) return(True); -Hence we make a direct return to avoid a second chance!!! + if (pam_auth(this_user,password)) return(True); + Hence we make a direct return to avoid a second chance!!! */ return (pam_auth(this_user,password)); #endif -#ifdef AFS_AUTH +#ifdef WITH_AFS if (afs_auth(this_user,password)) return(True); #endif -#ifdef DFS_AUTH +#ifdef WITH_DFS if (dfs_auth(this_user,password)) return(True); #endif @@ -1128,11 +1090,6 @@ Hence we make a direct return to avoid a second chance!!! if (krb4_auth(this_user,password)) return(True); #endif -#ifdef PWDAUTH - if (pwdauth(this_user,password) == 0) - return(True); -#endif - #ifdef OSF1_ENH_SEC { BOOL ret = (strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); @@ -1152,11 +1109,11 @@ Hence we make a direct return to avoid a second chance!!! return(linux_bigcrypt(password,this_salt,this_crypted)); #endif -#ifdef HPUX_10_TRUSTED +#ifdef HAVE_BIGCRYPT return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0); #endif -#ifdef NO_CRYPT +#ifndef HAVE_CRYPT DEBUG(1,("Warning - no crypt available\n")); return(False); #else @@ -1364,7 +1321,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } -#ifdef SHADOW_PWD +#ifdef HAVE_GETSPNAM { struct spwd *spass; @@ -1388,15 +1345,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) } #endif -#ifdef SecureWare - { - struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); - if (pr_pw && pr_pw->ufld.fd_encrypt) - pass->pw_passwd = pr_pw->ufld.fd_encrypt; - } -#endif - -#ifdef HPUX_10_TRUSTED +#ifdef HAVE_GETPRPWNAM { struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); if (pr_pw && pr_pw->ufld.fd_encrypt) @@ -1436,23 +1385,21 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) /* extract relevant info */ fstrcpy(this_user,pass->pw_name); fstrcpy(this_salt,pass->pw_passwd); -#ifdef HPUX - /* The crypt on HPUX won't work with more than 2 salt characters. */ + /* crypt on some platforms (HPUX in particular) + won't work with more than 2 salt characters. */ this_salt[2] = 0; -#endif /* HPUX */ + fstrcpy(this_crypted,pass->pw_passwd); if (!*this_crypted) { if (!lp_null_passwords()) { - DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); - return(False); + DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); + return(False); } -#ifndef PWDAUTH if (!*password) { - DEBUG(3,("Allowing access to %s with null password\n",this_user)); - return(True); + DEBUG(3,("Allowing access to %s with null password\n",this_user)); + return(True); } -#endif } /* try it as it came to us */ @@ -1551,7 +1498,7 @@ validate a group username entry. Return the username or NULL ****************************************************************************/ static char *validate_group(char *group,char *password,int pwlen,int snum) { -#ifdef NETGROUP +#ifdef HAVE_NETGROUP { char *host, *user, *domain; setnetgrent(group); @@ -1568,7 +1515,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) } #endif -#if HAVE_GETGRNAM +#ifdef HAVE_GETGRNAM { struct group *gptr = (struct group *)getgrnam(group); char **member; @@ -1824,7 +1771,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { BOOL host_ok = False; -#ifdef NETGROUP +#ifdef HAVE_NETGROUP if (is_group) { static char *mydomain = NULL; @@ -1836,7 +1783,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) #else if (is_group) { - DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n")); + DEBUG(1,("Netgroups not configured\n")); continue; } #endif diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index ee08e48e65..dbdbd49921 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -581,7 +581,7 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) euser_id = geteuid(); -#ifdef USE_SETRES +#ifdef HPUX { uid_t user_id; @@ -592,7 +592,7 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) if (setresuid(user_id,-1,-1)) DEBUG(5,("Unable to reset uid to %d\n", user_id)); } -#else /* USE_SETRES */ +#else #if defined(__FreeBSD__) || defined(__OpenBSD__) { /* FreeBSD patches from Marty Moll */ @@ -620,7 +620,7 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ -#endif /* USE_SETRES */ +#endif /* HAVE_SETRES */ /* Use softlimit to determine disk space, except when it has been exceeded */ #if defined(__FreeBSD__) || defined(__OpenBSD__) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 151a6d7ded..3469e45732 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -33,7 +33,6 @@ char *OutBuffer = NULL; char *last_inbuf = NULL; int am_parent = 1; -int atexit_set = 0; /* the last message the was processed */ int last_message = -1; @@ -56,9 +55,9 @@ extern int smb_read_error; extern pstring user_socket_options; -#ifdef DFS_AUTH +#ifdef WITH_DFS extern int dcelogin_atmost_once; -#endif /* DFS_AUTH */ +#endif /* WITH_DFS */ /* * This is set on startup - it defines the SID for this @@ -695,236 +694,6 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa } -/**************************************************************************** -normalise for DOS usage -****************************************************************************/ -static void disk_norm(int *bsize,int *dfree,int *dsize) -{ - /* check if the disk is beyond the max disk size */ - int maxdisksize = lp_maxdisksize(); - if (maxdisksize) { - /* convert to blocks - and don't overflow */ - maxdisksize = ((maxdisksize*1024)/(*bsize))*1024; - if (*dsize > maxdisksize) *dsize = maxdisksize; - if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop - applications getting - div by 0 errors */ - } - - while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) - { - *dfree /= 2; - *dsize /= 2; - *bsize *= 2; - if (*bsize > WORDMAX ) - { - *bsize = WORDMAX; - if (*dsize > WORDMAX) - *dsize = WORDMAX; - if (*dfree > WORDMAX) - *dfree = WORDMAX; - break; - } - } -} - -/**************************************************************************** - return number of 1K blocks available on a path and total number -****************************************************************************/ -int disk_free(char *path,int *bsize,int *dfree,int *dsize) -{ - char *df_command = lp_dfree_command(); - int dfree_retval; -#ifdef QUOTAS - int dfreeq_retval; - int dfreeq = 0; - int bsizeq = *bsize; - int dsizeq = *dsize; -#endif - -#ifndef NO_STATFS -#ifdef USE_STATVFS - struct statvfs fs; -#else -#ifdef ULTRIX - struct fs_data fs; -#else - struct statfs fs; -#endif -#endif -#endif - - /* possibly use system() to get the result */ - if (df_command && *df_command) - { - int ret; - pstring syscmd; - pstring outfile; - - slprintf(outfile,sizeof(outfile)-1, "%s/dfree.smb.%d",tmpdir(),(int)getpid()); - slprintf(syscmd,sizeof(syscmd)-1,"%s %s",df_command,path); - standard_sub_basic(syscmd); - - ret = smbrun(syscmd,outfile,False); - DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); - - { - FILE *f = fopen(outfile,"r"); - *dsize = 0; - *dfree = 0; - *bsize = 1024; - if (f) - { - fscanf(f,"%d %d %d",dsize,dfree,bsize); - fclose(f); - } - else - DEBUG(0,("Can't open %s\n",outfile)); - } - - unlink(outfile); - disk_norm(bsize,dfree,dsize); - dfree_retval = ((*bsize)/1024)*(*dfree); -#ifdef QUOTAS - /* Ensure we return the min value between the users quota and - what's free on the disk. Thanks to Albrecht Gebhardt - for this fix. - */ - if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq)) - { - disk_norm(&bsizeq, &dfreeq, &dsizeq); - dfreeq_retval = ((bsizeq)/1024)*(dfreeq); - dfree_retval = ( dfree_retval < dfreeq_retval ) ? - dfree_retval : dfreeq_retval ; - /* maybe dfree and dfreeq are calculated using different bsizes - so convert dfree from bsize into bsizeq */ - /* avoid overflows due to multiplication, so do not: - *dfree = ((*dfree) * (*bsize)) / (bsizeq); - bsize and bsizeq are powers of 2 so its better to - to divide them getting a multiplication or division factor - for dfree. Rene Nieuwenhuizen (07-10-1997) */ - if (*bsize >= bsizeq) - *dfree = *dfree * (*bsize / bsizeq); - else - *dfree = *dfree / (bsizeq / *bsize); - *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; - *bsize = bsizeq; - *dsize = dsizeq; - } -#endif - return(dfree_retval); - } - -#ifdef NO_STATFS - DEBUG(1,("Warning - no statfs function\n")); - return(1); -#else -#ifdef STATFS4 - if (statfs(path,&fs,sizeof(fs),0) != 0) -#else -#ifdef USE_STATVFS - if (statvfs(path, &fs)) -#else -#ifdef STATFS3 - if (statfs(path,&fs,sizeof(fs)) == -1) -#else - if (statfs(path,&fs) == -1) -#endif /* STATFS3 */ -#endif /* USE_STATVFS */ -#endif /* STATFS4 */ - { - DEBUG(3,("dfree call failed code errno=%d\n",errno)); - *bsize = 1024; - *dfree = 1; - *dsize = 1; - return(((*bsize)/1024)*(*dfree)); - } - -#ifdef ULTRIX - *bsize = 1024; - *dfree = fs.fd_req.bfree; - *dsize = fs.fd_req.btot; -#else -#ifdef USE_STATVFS - *bsize = fs.f_frsize; -#else -#ifdef USE_F_FSIZE - /* eg: osf1 has f_fsize = fundamental filesystem block size, - f_bsize = optimal transfer block size (MX: 94-04-19) */ - *bsize = fs.f_fsize; -#else - *bsize = fs.f_bsize; -#endif /* STATFS3 */ -#endif /* USE_STATVFS */ - -#ifdef STATFS4 - *dfree = fs.f_bfree; -#else - *dfree = fs.f_bavail; -#endif /* STATFS4 */ - *dsize = fs.f_blocks; -#endif /* ULTRIX */ - -#if defined(SCO) || defined(ISC) || defined(MIPS) - *bsize = 512; -#endif - -/* handle rediculous bsize values - some OSes are broken */ -if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024; - - disk_norm(bsize,dfree,dsize); - - if (*bsize < 256) - *bsize = 512; - if ((*dsize)<1) - { - DEBUG(0,("dfree seems to be broken on your system\n")); - *dsize = 20*1024*1024/(*bsize); - *dfree = MAX(1,*dfree); - } - dfree_retval = ((*bsize)/1024)*(*dfree); -#ifdef QUOTAS - /* Ensure we return the min value between the users quota and - what's free on the disk. Thanks to Albrecht Gebhardt - for this fix. - */ - if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq)) - { - disk_norm(&bsizeq, &dfreeq, &dsizeq); - dfreeq_retval = ((bsizeq)/1024)*(dfreeq); - dfree_retval = ( dfree_retval < dfreeq_retval ) ? - dfree_retval : dfreeq_retval ; - /* maybe dfree and dfreeq are calculated using different bsizes - so convert dfree from bsize into bsizeq */ - /* avoid overflows due to multiplication, so do not: - *dfree = ((*dfree) * (*bsize)) / (bsizeq); - bsize and bsizeq are powers of 2 so its better to - to divide them getting a multiplication or division factor - for dfree. Rene Nieuwenhuizen (07-10-1997) */ - if (*bsize >= bsizeq) - *dfree = *dfree * (*bsize / bsizeq); - else - *dfree = *dfree / (bsizeq / *bsize); - *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; - *bsize = bsizeq; - *dsize = dsizeq; - } -#endif - return(dfree_retval); -#endif -} - - -/**************************************************************************** -wrap it to get filenames right -****************************************************************************/ -int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize) -{ - return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize)); -} - - - /**************************************************************************** check a filename - possibly caling reducename @@ -1541,7 +1310,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct } -#if USE_MMAP +#if WITH_MMAP /* mmap it if read-only */ if (!fsp->can_write) { @@ -1563,9 +1332,9 @@ sync a file ********************************************************************/ void sync_file(int cnum, int fnum) { -#ifndef NO_FSYNC - if(lp_strict_sync(SNUM(cnum))) - fsync(Files[fnum].fd_ptr->fd); +#ifdef HAVE_FSYNC + if(lp_strict_sync(SNUM(cnum))) + fsync(Files[fnum].fd_ptr->fd); #endif } @@ -1627,7 +1396,7 @@ static void close_filestruct(files_struct *fs_p) fs_p->wbmpx_ptr = NULL; } -#if USE_MMAP +#if WITH_MMAP if(fs_p->mmap_ptr) { munmap(fs_p->mmap_ptr,fs_p->mmap_size); @@ -2303,7 +2072,7 @@ int read_file(int fnum,char *data,uint32 pos,int n) } #endif -#if USE_MMAP +#if WITH_MMAP if (Files[fnum].mmap_ptr) { int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1; @@ -2627,52 +2396,6 @@ int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int } -#ifndef SIGCLD_IGNORE -/**************************************************************************** -this prevents zombie child processes -****************************************************************************/ -static int sig_cld(void) -{ - static int depth = 0; - if (depth != 0) - { - DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n")); - depth=0; - return(0); - } - depth++; - - BlockSignals(True,SIGCLD); - DEBUG(5,("got SIGCLD\n")); - -#ifdef USE_WAITPID - while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0); -#endif - - /* Stop zombies */ - /* Stevens, Adv. Unix Prog. says that on system V you must call - wait before reinstalling the signal handler, because the kernel - calls the handler from within the signal-call when there is a - child that has exited. This would lead to an infinite recursion - if done vice versa. */ - -#ifndef DONT_REINSTALL_SIG -#ifdef SIGCLD_IGNORE - signal(SIGCLD, SIG_IGN); -#else - signal(SIGCLD, SIGNAL_CAST sig_cld); -#endif -#endif - -#ifndef USE_WAITPID - while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0); -#endif - depth--; - BlockSignals(False,SIGCLD); - return 0; -} -#endif - /**************************************************************************** this is called when the client exits abruptly **************************************************************************/ @@ -2684,9 +2407,6 @@ static int sig_pipe(void) if ((cli = server_client()) && cli->initialised) { DEBUG(3,("lost connection to password server\n")); cli_shutdown(cli); -#ifndef DONT_REINSTALL_SIG - signal(SIGPIPE, SIGNAL_CAST sig_pipe); -#endif BlockSignals(False,SIGPIPE); return 0; } @@ -2710,15 +2430,17 @@ static BOOL open_sockets(BOOL is_daemon,int port) int s; int i; - /* Stop zombies */ -#ifdef SIGCLD_IGNORE - signal(SIGCLD, SIG_IGN); -#else - signal(SIGCLD, SIGNAL_CAST sig_cld); +#ifdef HAVE_ATEXIT + static int atexit_set; + if(atexit_set == 0) { + atexit_set=1; + atexit(killkids); + } #endif - if(atexit_set == 0) - atexit(killkids); + /* Stop zombies */ + CatchChild(); + FD_ZERO(&listen_set); @@ -2825,21 +2547,12 @@ max can be %d\n", num_interfaces, FD_SETSIZE)); continue; } -#ifdef NO_FORK_DEBUG -#ifndef NO_SIGNAL_TEST - signal(SIGPIPE, SIGNAL_CAST sig_pipe); - signal(SIGCLD, SIGNAL_CAST SIG_DFL); -#endif /* NO_SIGNAL_TEST */ - return True; -#else /* NO_FORK_DEBUG */ if (Client != -1 && fork()==0) { /* Child code ... */ -#ifndef NO_SIGNAL_TEST - signal(SIGPIPE, SIGNAL_CAST sig_pipe); - signal(SIGCLD, SIGNAL_CAST SIG_DFL); -#endif /* NO_SIGNAL_TEST */ + CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe); + /* close the listening socket(s) */ for(i = 0; i < num_interfaces; i++) close(fd_listenset[i]); @@ -2860,20 +2573,19 @@ max can be %d\n", num_interfaces, FD_SETSIZE)); } close(Client); /* The parent doesn't need this socket */ - /* - * Force parent to check log size after spawning child. - * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De. - * The parent smbd will log to logserver.smb. - * It writes only two messages for each child - * started/finished. But each child writes, say, 50 messages also in - * logserver.smb, begining with the debug_count of the parent, before the - * child opens its own log file logserver.client. In a worst case - * scenario the size of logserver.smb would be checked after about - * 50*50=2500 messages (ca. 100kb). - */ - force_check_log_size(); - -#endif /* NO_FORK_DEBUG */ + /* + * Force parent to check log size after spawning child. + * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De. + * The parent smbd will log to logserver.smb. + * It writes only two messages for each child + * started/finished. But each child writes, say, 50 messages also in + * logserver.smb, begining with the debug_count of the parent, before the + * child opens its own log file logserver.client. In a worst case + * scenario the size of logserver.smb would be checked after about + * 50*50=2500 messages (ca. 100kb). + */ + force_check_log_size(); + } /* end for num */ } /* end while 1 */ } /* end if is_daemon */ @@ -2882,9 +2594,7 @@ max can be %d\n", num_interfaces, FD_SETSIZE)); /* Started from inetd. fd 0 is the socket. */ /* We will abort gracefully when the client or remote system goes away */ -#ifndef NO_SIGNAL_TEST - signal(SIGPIPE, SIGNAL_CAST sig_pipe); -#endif + CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe); Client = dup(0); /* close our standard file descriptors */ @@ -2905,10 +2615,10 @@ max can be %d\n", num_interfaces, FD_SETSIZE)); static void process_smb(char *inbuf, char *outbuf) { extern int Client; -#ifdef USE_SSL +#ifdef WITH_SSL extern BOOL sslEnabled; /* don't use function for performance reasons */ static int sslConnected = 0; -#endif /* USE_SSL */ +#endif /* WITH_SSL */ static int trans_num; int msg_type = CVAL(inbuf,0); int32 len = smb_len(inbuf); @@ -2933,7 +2643,7 @@ static void process_smb(char *inbuf, char *outbuf) DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len)); DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread)); -#ifdef USE_SSL +#ifdef WITH_SSL if(sslEnabled && !sslConnected){ sslConnected = sslutil_negotiate_ssl(Client, msg_type); if(sslConnected < 0){ /* an error occured */ @@ -2943,7 +2653,7 @@ static void process_smb(char *inbuf, char *outbuf) return; } } -#endif /* USE_SSL */ +#endif /* WITH_SSL */ #ifdef WITH_VTP if(trans_num == 1 && VT_Check(inbuf)) @@ -3641,9 +3351,6 @@ static int sig_hup(void) */ reload_after_sighup = True; -#ifndef DONT_REINSTALL_SIG - signal(SIGHUP,SIGNAL_CAST sig_hup); -#endif BlockSignals(False,SIGHUP); return(0); } @@ -3811,7 +3518,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de string_set(&pcon->dirpath,""); string_set(&pcon->user,user); -#if HAVE_GETGRNAM +#ifdef HAVE_GETGRNAM if (*lp_force_group(snum)) { struct group *gptr; @@ -4596,7 +4303,7 @@ static BOOL dump_core(void) if (chdir(dname)) return(False); umask(~(0700)); -#ifndef NO_GETRLIMIT +#ifdef HAVE_GETRLIMIT #ifdef RLIMIT_CORE { struct rlimit rlp; @@ -4631,7 +4338,7 @@ void exit_server(char *reason) for (i=0;i @@ -261,6 +261,6 @@ char *reqHosts, *resignHosts; return 1; } -#else /* USE_SSL */ +#else /* WITH_SSL */ void ssl_dummy(void) {;} /* So some compilers don't complain. */ -#endif /* USE_SSL */ +#endif /* WITH_SSL */ 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) diff --git a/source3/smbd/vt_mode.c b/source3/smbd/vt_mode.c index 19f8259464..6e95bac3c2 100644 --- a/source3/smbd/vt_mode.c +++ b/source3/smbd/vt_mode.c @@ -156,7 +156,7 @@ void VT_SigCLD(int sig) if(wait(NULL) == VT_ChildPID) VT_ChildDied = True; else - signal(SIGCLD, VT_SigCLD); + CatchSignal(SIGCLD, VT_SigCLD); } @@ -305,12 +305,12 @@ int VT_Start(void) VT_ChildDied = False; VT_Fd = master; - signal(SIGCLD, VT_SigCLD); + CatchSignal(SIGCLD, VT_SigCLD); - signal(SIGHUP, VT_SigEXIT); - signal(SIGTERM, VT_SigEXIT); - signal(SIGINT, VT_SigEXIT); - signal(SIGQUIT, VT_SigEXIT); + CatchSignal(SIGHUP, VT_SigEXIT); + CatchSignal(SIGTERM, VT_SigEXIT); + CatchSignal(SIGINT, VT_SigEXIT); + CatchSignal(SIGQUIT, VT_SigEXIT); memset(OutBuf, 0, sizeof(OutBuf)); OutBuf [4] = 0x06; -- cgit