summaryrefslogtreecommitdiff
path: root/source/smbd/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/server.c')
-rw-r--r--source/smbd/server.c714
1 files changed, 100 insertions, 614 deletions
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 5d8facef33f..e582ea735ab 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -20,13 +20,9 @@
*/
#include "includes.h"
-#include "loadparm.h"
-#include "pcap.h"
#include "trans2.h"
-#include "reply.h"
pstring servicesf = CONFIGFILE;
-pstring OriginalDir ="/";
extern pstring debugf;
extern pstring sesssetup_user;
@@ -34,16 +30,8 @@ char *InBuffer = NULL;
char *OutBuffer = NULL;
char *last_inbuf = NULL;
-int initial_uid = 0;
-int initial_gid = 0;
-
BOOL share_mode_pending = False;
-/* have I done a become_user? */
-static struct {
- int cnum, uid;
-} last_user;
-
/* the last message the was processed */
int last_message = -1;
@@ -60,6 +48,8 @@ extern BOOL short_case_preserve;
extern BOOL case_mangle;
extern time_t smb_last_time;
+extern int smb_read_error;
+
extern pstring user_socket_options;
connection_struct Connections[MAX_CONNECTIONS];
@@ -88,16 +78,9 @@ int unix_ERR_code=0;
extern int extra_time_offset;
extern pstring myhostname;
-extern struct in_addr myip;
-
static int find_free_connection(int hash);
-#ifdef SMB_PASSWD
-extern void generate_next_challenge(char *challenge);
-extern void set_challenge(char *challenge);
-#endif
-
/* for readability... */
#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
@@ -148,31 +131,20 @@ mode_t unix_mode(int cnum,int dosmode)
int dos_mode(int cnum,char *path,struct stat *sbuf)
{
int result = 0;
+ extern struct current_user current_user;
-#if OLD_DOS_MODE
- if (!CAN_WRITE(cnum) || !((sbuf->st_mode & S_IWOTH) ||
- Connections[cnum].admin_user ||
- ((sbuf->st_mode & S_IWUSR) &&
- Connections[cnum].uid==sbuf->st_uid) ||
- ((sbuf->st_mode & S_IWGRP) &&
- in_group(sbuf->st_gid,Connections[cnum].gid,
- Connections[cnum].ngroups,
- Connections[cnum].igroups))))
- result |= aRONLY;
-#else
if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
if (!((sbuf->st_mode & S_IWOTH) ||
Connections[cnum].admin_user ||
- ((sbuf->st_mode & S_IWUSR) && Connections[cnum].uid==sbuf->st_uid) ||
+ ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
((sbuf->st_mode & S_IWGRP) &&
- in_group(sbuf->st_gid,Connections[cnum].gid,
- Connections[cnum].ngroups,Connections[cnum].igroups))))
+ in_group(sbuf->st_gid,current_user.gid,
+ current_user.ngroups,current_user.igroups))))
result |= aRONLY;
} else {
if ((sbuf->st_mode & S_IWUSR) == 0)
result |= aRONLY;
}
-#endif
if ((sbuf->st_mode & S_IXUSR) != 0)
result |= aARCH;
@@ -257,7 +229,7 @@ int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
unixmode |= tmp;
}
-
+
return(chmod(fname,unixmode));
}
@@ -326,7 +298,7 @@ static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
void *cur_dir;
char *dname;
BOOL mangled;
- fstring name2;
+ pstring name2;
mangled = is_mangled(name);
@@ -410,8 +382,12 @@ BOOL unix_convert(char *name,int cnum)
{
if ((! *name) || strchr(name,'/') || !is_8_3(name))
{
+ char *s;
fstring name2;
sprintf(name2,"%.6s.XXXXXX",remote_machine);
+ /* sanitise the name */
+ for (s=name2 ; *s ; s++)
+ if (!issafe(*s)) *s = '_';
strcpy(name,(char *)mktemp(name2));
}
return(True);
@@ -522,251 +498,6 @@ BOOL unix_convert(char *name,int cnum)
}
-
-
-#ifdef QUOTAS
-#ifdef LINUX
-/****************************************************************************
-try to get the disk space from disk quotas (LINUX version)
-****************************************************************************/
-/*
-If you didn't make the symlink to the quota package, too bad :(
-*/
-#include "quota/quotactl.c"
-#include "quota/hasquota.c"
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t euser_id;
- struct dqblk D;
- struct stat S;
- dev_t devno ;
- struct mntent *mnt;
- FILE *fp;
- int found ;
- int qcmd, fd ;
- char *qfpathname;
-
- /* find the block device file */
-
- if ( stat(path, &S) == -1 )
- return(False) ;
-
- devno = S.st_dev ;
-
- fp = setmntent(MOUNTED,"r");
- found = False ;
-
- while ((mnt = getmntent(fp)) != (struct mntent *) 0) {
- if ( stat(mnt->mnt_dir,&S) == -1 )
- continue ;
- if (S.st_dev == devno) {
- found = True ;
- break ;
- }
- }
- endmntent(fp) ;
-
- if ( ! found )
- return(False) ;
-
- qcmd = QCMD(Q_GETQUOTA, USRQUOTA);
-
- if (hasmntopt(mnt, MNTOPT_NOAUTO) || hasmntopt(mnt, MNTOPT_NOQUOTA))
- return(False) ;
-
- if (!hasquota(mnt, USRQUOTA, &qfpathname))
- return(False) ;
-
- euser_id = geteuid();
- seteuid(0);
-
- if (quotactl(qcmd, mnt->mnt_fsname, euser_id, (caddr_t)&D) != 0) {
- if ((fd = open(qfpathname, O_RDONLY)) < 0) {
- seteuid(euser_id);
- return(False);
- }
- lseek(fd, (long) dqoff(euser_id), L_SET);
- switch (read(fd, &D, sizeof(struct dqblk))) {
- case 0:/* EOF */
- memset((caddr_t)&D, 0, sizeof(struct dqblk));
- break;
- case sizeof(struct dqblk): /* OK */
- break;
- default: /* ERROR */
- close(fd);
- seteuid(euser_id);
- return(False);
- }
- }
- seteuid(euser_id);
- *bsize=1024;
-
- if (D.dqb_bsoftlimit==0)
- return(False);
- if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curinodes>D.dqb_isoftlimit))
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
-}
-#else
-#ifndef CRAY
-/****************************************************************************
-try to get the disk space from disk quotas
-****************************************************************************/
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t user_id, euser_id;
- int r;
- char dev_disk[256];
- struct dqblk D;
- struct stat S;
- /* find the block device file */
- if ((stat(path, &S)<0) ||
- (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) return (False);
-
- euser_id = geteuid();
-
-#ifdef USE_SETRES
- /* for HPUX, real uid must be same as euid to execute quotactl for euid */
- user_id = getuid();
- setresuid(euser_id,-1,-1);
-#endif
- r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
- #ifdef USE_SETRES
- if (setresuid(user_id,-1,-1))
- DEBUG(5,("Unable to reset uid to %d\n", user_id));
- #endif
- /* Use softlimit to determine disk space, except when it has been exceeded */
- *bsize = 1024;
- if (r)
- {
- if (errno == EDQUOT)
- {
- *dfree =0;
- *dsize =D.dqb_curblocks;
- return (True);
- }
- else return(False);
- }
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curfiles>D.dqb_fsoftlimit))
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
-}
-#else
-/****************************************************************************
-try to get the disk space from disk quotas (CRAY VERSION)
-****************************************************************************/
-static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- struct mntent *mnt;
- FILE *fd;
- struct stat sbuf;
- dev_t devno ;
- static dev_t devno_cached = 0 ;
- static char name[MNTMAXSTR] ;
- struct q_request request ;
- struct qf_header header ;
- static int quota_default = 0 ;
- int found ;
-
- if ( stat(path,&sbuf) == -1 )
- return(False) ;
-
- devno = sbuf.st_dev ;
-
- if ( devno != devno_cached ) {
-
- devno_cached = devno ;
-
- if ((fd = setmntent(KMTAB)) == NULL)
- return(False) ;
-
- found = False ;
-
- while ((mnt = getmntent(fd)) != NULL) {
-
- if ( stat(mnt->mnt_dir,&sbuf) == -1 )
- continue ;
-
- if (sbuf.st_dev == devno) {
-
- found = True ;
- break ;
-
- }
-
- }
-
- strcpy(name,mnt->mnt_dir) ;
- endmntent(fd) ;
-
- if ( ! found )
- return(False) ;
- }
-
- request.qf_magic = QF_MAGIC ;
- request.qf_entry.id = geteuid() ;
-
- if (quotactl(name, Q_GETQUOTA, &request) == -1)
- return(False) ;
-
- if ( ! request.user )
- return(False) ;
-
- if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
-
- if ( ! quota_default ) {
-
- if ( quotactl(name, Q_GETHEADER, &header) == -1 )
- return(False) ;
- else
- quota_default = header.user_h.def_fq ;
- }
-
- *dfree = quota_default ;
-
- }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
-
- *dfree = 0 ;
-
- }else{
-
- *dfree = request.qf_entry.user_q.f_quota ;
-
- }
-
- *dsize = request.qf_entry.user_q.f_use ;
-
- if ( *dfree )
- *dfree -= *dsize ;
-
- if ( *dfree < 0 )
- *dfree = 0 ;
-
- *bsize = 4096 ; /* Cray blocksize */
-
- return(True) ;
-
-}
-#endif /* CRAY */
-#endif /* LINUX */
-#endif /* QUOTAS */
-
-
/****************************************************************************
normalise for DOS usage
****************************************************************************/
@@ -1227,16 +958,6 @@ void close_file(int fnum)
if (lp_share_modes(SNUM(cnum)))
del_share_mode(fnum);
- if (Files[fnum].modified) {
- struct stat st;
- if (fstat(Files[fnum].fd,&st) == 0) {
- int dosmode = dos_mode(cnum,Files[fnum].name,&st);
- if (!IS_DOS_ARCHIVE(dosmode)) {
- dos_chmod(cnum,Files[fnum].name,dosmode | aARCH,&st);
- }
- }
- }
-
close(Files[fnum].fd);
/* NT uses smbclose to start a print - weird */
@@ -1544,41 +1265,35 @@ int seek_file(int fnum,int pos)
/****************************************************************************
read from a file
****************************************************************************/
-int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact)
+int read_file(int fnum,char *data,int pos,int n)
{
- int ret=0;
+ int ret=0,readret;
if (!Files[fnum].can_write)
{
- ret = read_predict(Files[fnum].fd,
- pos,
- data,
- NULL,
- maxcnt);
+ ret = read_predict(Files[fnum].fd,pos,data,NULL,n);
data += ret;
- maxcnt -= ret;
- mincnt = MAX(mincnt-ret,0);
+ n -= ret;
pos += ret;
}
#if USE_MMAP
if (Files[fnum].mmap_ptr)
{
- int num = MIN(maxcnt,Files[fnum].mmap_size-pos);
+ int num = MIN(n,Files[fnum].mmap_size-pos);
if (num > 0)
{
memcpy(data,Files[fnum].mmap_ptr+pos,num);
data += num;
pos += num;
- maxcnt -= num;
- mincnt = MAX(mincnt-num,0);
+ n -= num;
ret += num;
}
}
#endif
- if (maxcnt <= 0)
+ if (n <= 0)
return(ret);
if (seek_file(fnum,pos) != pos)
@@ -1587,13 +1302,10 @@ int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL
return(ret);
}
- if (maxcnt > 0)
- ret += read_with_timeout(Files[fnum].fd,
- data,
- mincnt,
- maxcnt,
- timeout,
- exact);
+ if (n > 0) {
+ readret = read(Files[fnum].fd,data,n);
+ if (readret > 0) ret += readret;
+ }
return(ret);
}
@@ -1609,14 +1321,21 @@ int write_file(int fnum,char *data,int n)
return(0);
}
- Files[fnum].modified = True;
+ if (!Files[fnum].modified) {
+ struct stat st;
+ Files[fnum].modified = True;
+ if (fstat(Files[fnum].fd,&st) == 0) {
+ int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
+ if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
+ dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
+ }
+ }
+ }
return(write_data(Files[fnum].fd,data,n));
}
-static int old_umask = 022;
-
/****************************************************************************
load parameters specific to a connection/service
****************************************************************************/
@@ -1662,261 +1381,6 @@ BOOL become_service(int cnum,BOOL do_chdir)
/****************************************************************************
- 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)
-#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);
- }
-
- 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)
-#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);
- }
-
- 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
-****************************************************************************/
-static 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;i<Connections[cnum].uid_cache.entries;i++)
- if (Connections[cnum].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;
-
- 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);
-#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 (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);
-}
-
-/****************************************************************************
find a service entry
****************************************************************************/
int find_service(char *service)
@@ -2222,6 +1686,9 @@ static BOOL open_sockets(BOOL is_daemon,int port)
signal(SIGPIPE, SIGNAL_CAST sig_pipe);
signal(SIGCLD, SIGNAL_CAST SIG_DFL);
#endif
+ /* close the listening socket */
+ close(s);
+
/* close our standard file descriptors */
close_low_fds();
@@ -2299,6 +1766,8 @@ BOOL reload_services(BOOL test)
reopen_logs();
+ load_interfaces();
+
{
extern int Client;
if (Client != -1) {
@@ -2633,7 +2102,8 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
if (ChDir(pcon->connectpath) != 0)
{
- DEBUG(0,("Can't change directory to %s\n",pcon->connectpath));
+ DEBUG(0,("Can't change directory to %s (%s)\n",
+ pcon->connectpath,strerror(errno)));
pcon->open = False;
unbecome_user();
if (!IS_IPC(cnum)) {
@@ -2694,6 +2164,8 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
int find_free_file(void )
{
int i;
+ /* we start at 1 here for an obscure reason I can't now remember,
+ but I think is important :-) */
for (i=1;i<MAX_OPEN_FILES;i++)
if (!Files[i].open)
return(i);
@@ -2864,6 +2336,7 @@ int reply_nt1(char *outbuf)
int capabilities=0x300; /* has dual names + lock_and_read */
int secword=0;
BOOL doencrypt = SMBENCRYPT();
+ time_t t = time(NULL);
if (lp_security()>=SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
@@ -2898,8 +2371,8 @@ int reply_nt1(char *outbuf)
SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
- put_long_date(outbuf+smb_vwv11+1,time(NULL));
- SSVALS(outbuf,smb_vwv15+1,TimeDiff(time(NULL))/60);
+ put_long_date(outbuf+smb_vwv11+1,t);
+ SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
return (smb_len(outbuf)+4);
}
@@ -3884,7 +3357,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
/****************************************************************************
process commands from the client
****************************************************************************/
-void process(void )
+static void process(void)
{
static int trans_num = 0;
int nread;
@@ -3908,12 +3381,10 @@ void process(void )
ip = *interpret_addr2("localhost");
if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
*OutBuffer = 0;
- send_one_packet(OutBuffer,1,ip,137,SOCK_DGRAM);
+ send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
}
#endif
- last_user.cnum = -1;
-
while (True)
{
int32 len;
@@ -3959,14 +3430,40 @@ void process(void )
BOOL allidle = True;
extern int keepalive;
- /* check for socket failure */
- if (errno == EBADF) {
- DEBUG(3,("%s Bad file descriptor - exiting\n",timestring()));
+ if (smb_read_error == READ_EOF) {
+ DEBUG(3,("end of file from client\n"));
+ return;
+ }
+
+ if (smb_read_error == READ_ERROR) {
+ DEBUG(3,("receive_smb error (%s) exiting\n",
+ strerror(errno)));
return;
}
t = time(NULL);
+ {
+ /* the following bit of code was added to combat smbd
+ looping chewing lots of CPU time. It should never
+ actually be needed, but it seems that some systems
+ don't set error correctly, which is used to distinguish
+ a select() timeout from a read error
+
+ we exit if receive_smb() returns false 3 times in one second.
+ */
+ static int error_count=0;
+ static time_t error_time=0;
+ if (error_count==0) {
+ error_time = t;
+ } else if (error_time != t) {
+ error_count = 0;
+ } else if (error_count++ > 2) {
+ exit_server("looping in process()\n");
+ }
+ }
+
+
/* become root again if waiting */
unbecome_user();
@@ -3989,10 +3486,15 @@ void process(void )
}
if (keepalive && (counter-last_keepalive)>keepalive) {
+ extern int password_client;
if (!send_keepalive(Client)) {
DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
return;
- }
+ }
+ /* also send a keepalive to the password server if its still
+ connected */
+ if (password_client != -1)
+ send_keepalive(password_client);
last_keepalive = counter;
}
@@ -4064,7 +3566,7 @@ void process(void )
static void init_structs(void )
{
int i;
- get_myname(myhostname,&myip);
+ get_myname(myhostname,NULL);
for (i=0;i<MAX_CONNECTIONS;i++)
{
@@ -4090,7 +3592,7 @@ static void init_structs(void )
/****************************************************************************
usage on the program
****************************************************************************/
-void usage(char *pname)
+static void usage(char *pname)
{
DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
@@ -4110,12 +3612,12 @@ void usage(char *pname)
/****************************************************************************
main program
****************************************************************************/
-int main(int argc,char *argv[])
+ int main(int argc,char *argv[])
{
extern BOOL append_log;
/* shall I run as a daemon */
BOOL is_daemon = False;
- int port = 139;
+ int port = SMB_PORT;
int opt;
extern char *optarg;
@@ -4152,22 +3654,7 @@ int main(int argc,char *argv[])
umask(0777 & ~DEF_CREATE_MASK);
- initial_uid = geteuid();
- initial_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();
-
+ init_uid();
/* this is for people who can't start the program correctly */
while (argc > 1 && (*argv[1] != '-'))
@@ -4229,8 +3716,6 @@ int main(int argc,char *argv[])
DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
- GetWd(OriginalDir);
-
#ifndef NO_GETRLIMIT
#ifdef RLIMIT_NOFILE
{
@@ -4277,22 +3762,23 @@ int main(int argc,char *argv[])
become_daemon();
}
- if (open_sockets(is_daemon,port))
- {
- /* possibly reload the services file. */
- reload_services(True);
+ if (!open_sockets(is_daemon,port))
+ exit(1);
- maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
+ /* possibly reload the services file. */
+ reload_services(True);
- if (*lp_rootdir())
- {
- if (sys_chroot(lp_rootdir()) == 0)
- DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
- }
+ maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
- process();
- close_sockets();
+ if (*lp_rootdir())
+ {
+ if (sys_chroot(lp_rootdir()) == 0)
+ DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
}
+
+ process();
+ close_sockets();
+
exit_server("normal exit");
return(0);
}