2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
29 char *InBuffer = NULL;
30 char *OutBuffer = NULL;
31 char *last_inbuf = NULL;
33 BOOL share_mode_pending = False;
35 /* the last message the was processed */
36 int last_message = -1;
38 /* a useful macro to debug the last message processed */
39 #define LAST_MESSAGE() smb_fn_name(last_message)
42 extern int DEBUGLEVEL;
43 extern int case_default;
44 extern BOOL case_sensitive;
45 extern BOOL case_preserve;
46 extern BOOL use_mangled_map;
47 extern BOOL short_case_preserve;
48 extern BOOL case_mangle;
49 extern time_t smb_last_time;
51 extern int smb_read_error;
53 extern pstring user_socket_options;
55 connection_struct Connections[MAX_CONNECTIONS];
56 files_struct Files[MAX_OPEN_FILES];
60 int maxxmit = BUFFER_SIZE;
62 /* a fnum to use when chaining */
65 /* number of open connections */
66 static int num_connections_open = 0;
68 extern fstring remote_machine;
71 /* these can be set by some functions to override the error codes */
72 int unix_ERR_class=SUCCESS;
76 extern int extra_time_offset;
78 extern pstring myhostname;
80 static int find_free_connection(int hash);
82 /* for readability... */
83 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
84 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
85 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
86 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
87 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
91 /****************************************************************************
92 change a dos mode to a unix mode
93 base permission for files:
94 everybody gets read bit set
95 dos readonly is represented in unix by removing everyone's write bit
96 dos archive is represented in unix by the user's execute bit
97 dos system is represented in unix by the group's execute bit
98 dos hidden is represented in unix by the other's execute bit
99 base permission for directories:
100 dos directory is represented in unix by unix's dir bit and the exec bit
101 ****************************************************************************/
102 mode_t unix_mode(int cnum,int dosmode)
104 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
106 if ( !IS_DOS_READONLY(dosmode) )
107 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
109 if (IS_DOS_DIR(dosmode))
110 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
112 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
115 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
118 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
121 result &= CREATE_MODE(cnum);
126 /****************************************************************************
127 change a unix mode to a dos mode
128 ****************************************************************************/
129 int dos_mode(int cnum,char *path,struct stat *sbuf)
132 extern struct current_user current_user;
134 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
135 if (!((sbuf->st_mode & S_IWOTH) ||
136 Connections[cnum].admin_user ||
137 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
138 ((sbuf->st_mode & S_IWGRP) &&
139 in_group(sbuf->st_gid,current_user.gid,
140 current_user.ngroups,current_user.igroups))))
143 if ((sbuf->st_mode & S_IWUSR) == 0)
147 if ((sbuf->st_mode & S_IXUSR) != 0)
150 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
153 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
156 if (S_ISDIR(sbuf->st_mode))
157 result = aDIR | (result & aRONLY);
160 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
164 /* hide files with a name starting with a . */
165 if (lp_hide_dot_files(SNUM(cnum)))
167 char *p = strrchr(path,'/');
173 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
181 /*******************************************************************
182 chmod a file - but preserve some bits
183 ********************************************************************/
184 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
193 if (sys_stat(fname,st)) return(-1);
196 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
198 if (dos_mode(cnum,fname,st) == dosmode) return(0);
200 unixmode = unix_mode(cnum,dosmode);
202 /* preserve the s bits */
203 mask |= (S_ISUID | S_ISGID);
205 /* preserve the t bit */
210 /* possibly preserve the x bits */
211 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
212 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
213 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
215 unixmode |= (st->st_mode & mask);
217 /* if we previously had any r bits set then leave them alone */
218 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
219 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
223 /* if we previously had any w bits set then leave them alone
224 if the new mode is not rdonly */
225 if (!IS_DOS_READONLY(dosmode) &&
226 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
227 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
231 return(sys_chmod(fname,unixmode));
235 /****************************************************************************
236 check if two filenames are equal
238 this needs to be careful about whether we are case sensitive
239 ****************************************************************************/
240 static BOOL fname_equal(char *name1, char *name2)
242 int l1 = strlen(name1);
243 int l2 = strlen(name2);
245 /* handle filenames ending in a single dot */
246 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
250 ret = fname_equal(name1,name2);
255 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
259 ret = fname_equal(name1,name2);
264 /* now normal filename handling */
266 return(strcmp(name1,name2) == 0);
268 return(strequal(name1,name2));
272 /****************************************************************************
273 mangle the 2nd name and check if it is then equal to the first name
274 ****************************************************************************/
275 static BOOL mangled_equal(char *name1, char *name2)
282 strcpy(tmpname,name2);
283 mangle_name_83(tmpname);
285 return(strequal(name1,tmpname));
289 /****************************************************************************
290 scan a directory to find a filename, matching without case sensitivity
292 If the name looks like a mangled name then try via the mangling functions
293 ****************************************************************************/
294 static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
301 mangled = is_mangled(name);
303 /* handle null paths */
307 if (docache && (dname = DirCacheCheck(path,name,snum))) {
313 check_mangled_stack(name);
315 /* open the directory */
316 if (!(cur_dir = OpenDir(path)))
318 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
322 /* now scan for matching names */
323 while ((dname = ReadDirName(cur_dir)))
326 (strequal(dname,".") || strequal(dname,"..")))
330 if (!name_map_mangle(name2,False,snum)) continue;
332 if ((mangled && mangled_equal(name,name2))
333 || fname_equal(name, name2))
335 /* we've found the file, change it's name and return */
336 if (docache) DirCacheAdd(path,name,dname,snum);
347 /****************************************************************************
348 This routine is called to convert names from the dos namespace to unix
349 namespace. It needs to handle any case conversions, mangling, format
352 We assume that we have already done a chdir() to the right "root" directory
355 The function will return False if some part of the name except for the last
356 part cannot be resolved
357 ****************************************************************************/
358 BOOL unix_convert(char *name,int cnum)
366 /* convert to basic unix format - removing \ chars and cleaning it up */
368 unix_clean_name(name);
370 if (!case_sensitive &&
371 (!case_preserve || (is_8_3(name) && !short_case_preserve)))
374 /* names must be relative to the root of the service - trim any leading /.
375 also trim trailing /'s */
376 trim_string(name,"/","/");
378 /* check if it's a printer file */
379 if (Connections[cnum].printer)
381 if ((! *name) || strchr(name,'/') || !is_8_3(name))
385 sprintf(name2,"%.6s.XXXXXX",remote_machine);
386 /* sanitise the name */
387 for (s=name2 ; *s ; s++)
388 if (!issafe(*s)) *s = '_';
389 strcpy(name,(char *)mktemp(name2));
394 /* stat the name - if it exists then we are all done! */
395 if (sys_stat(name,&st) == 0)
398 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
400 /* a special case - if we don't have any mangling chars and are case
401 sensitive then searching won't help */
402 if (case_sensitive && !is_mangled(name) &&
403 !lp_strip_dot() && !use_mangled_map)
406 /* now we need to recursively match the name against the real
407 directory structure */
410 while (strncmp(start,"./",2) == 0)
413 /* now match each part of the path name separately, trying the names
414 as is first, then trying to scan the directory for matching names */
415 for (;start;start = (end?end+1:(char *)NULL))
417 /* pinpoint the end of this section of the filename */
418 end = strchr(start, '/');
420 /* chop the name at this point */
423 /* check if the name exists up to this point */
424 if (sys_stat(name, &st) == 0)
426 /* it exists. it must either be a directory or this must be
427 the last part of the path for it to be OK */
428 if (end && !(st.st_mode & S_IFDIR))
430 /* an intermediate part of the name isn't a directory */
431 DEBUG(5,("Not a dir %s\n",start));
442 /* remember the rest of the pathname so it can be restored
444 if (end) strcpy(rest,end+1);
447 /* try to find this part of the path in the directory */
448 if (strchr(start,'?') || strchr(start,'*') ||
449 !scan_directory(dirpath, start, SNUM(cnum), end?True:False))
453 /* an intermediate part of the name can't be found */
454 DEBUG(5,("Intermediate not found %s\n",start));
459 /* just the last part of the name doesn't exist */
460 /* we may need to strupper() or strlower() it in case
461 this conversion is being used for file creation
463 /* if the filename is of mixed case then don't normalise it */
464 if (!case_preserve &&
465 (!strhasupper(start) || !strhaslower(start)))
468 /* check on the mangled stack to see if we can recover the
469 base of the filename */
470 if (is_mangled(start))
471 check_mangled_stack(start);
473 DEBUG(5,("New file %s\n",start));
477 /* restore the rest of the string */
480 strcpy(start+strlen(start)+1,rest);
481 end = start + strlen(start);
485 /* add to the dirpath that we have resolved so far */
486 if (*dirpath) strcat(dirpath,"/");
487 strcat(dirpath,start);
489 /* restore the / that we wiped out earlier */
493 /* the name has been resolved */
494 DEBUG(5,("conversion finished %s\n",name));
499 /****************************************************************************
500 normalise for DOS usage
501 ****************************************************************************/
502 static void disk_norm(int *bsize,int *dfree,int *dsize)
504 /* check if the disk is beyond the max disk size */
505 int maxdisksize = lp_maxdisksize();
507 /* convert to blocks - and don't overflow */
508 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
509 if (*dsize > maxdisksize) *dsize = maxdisksize;
510 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
515 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
520 if (*bsize > WORDMAX )
523 if (*dsize > WORDMAX)
525 if (*dfree > WORDMAX)
532 /****************************************************************************
533 return number of 1K blocks available on a path and total number
534 ****************************************************************************/
535 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
537 char *df_command = lp_dfree_command();
551 if (disk_quotas(path, bsize, dfree, dsize))
553 disk_norm(bsize,dfree,dsize);
554 return(((*bsize)/1024)*(*dfree));
559 /* possibly use system() to get the result */
560 if (df_command && *df_command)
566 sprintf(outfile,"/tmp/dfree.smb.%d",(int)getpid());
567 sprintf(syscmd,"%s %s",df_command,path);
568 standard_sub_basic(syscmd);
570 ret = smbrun(syscmd,outfile,False);
571 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
574 FILE *f = fopen(outfile,"r");
580 fscanf(f,"%d %d %d",dsize,dfree,bsize);
584 DEBUG(0,("Can't open %s\n",outfile));
588 disk_norm(bsize,dfree,dsize);
589 return(((*bsize)/1024)*(*dfree));
593 DEBUG(1,("Warning - no statfs function\n"));
597 if (statfs(path,&fs,sizeof(fs),0) != 0)
600 if (statvfs(path, &fs))
603 if (statfs(path,&fs,sizeof(fs)) == -1)
605 if (statfs(path,&fs) == -1)
607 #endif /* USE_STATVFS */
610 DEBUG(3,("dfree call failed code errno=%d\n",errno));
614 return(((*bsize)/1024)*(*dfree));
619 *dfree = fs.fd_req.bfree;
620 *dsize = fs.fd_req.btot;
623 *bsize = fs.f_frsize;
626 /* eg: osf1 has f_fsize = fundamental filesystem block size,
627 f_bsize = optimal transfer block size (MX: 94-04-19) */
632 #endif /* USE_STATVFS */
637 *dfree = fs.f_bavail;
639 *dsize = fs.f_blocks;
642 #if defined(SCO) || defined(ISC) || defined(MIPS)
646 /* handle rediculous bsize values - some OSes are broken */
647 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
649 disk_norm(bsize,dfree,dsize);
655 DEBUG(0,("dfree seems to be broken on your system\n"));
656 *dsize = 20*1024*1024/(*bsize);
657 *dfree = MAX(1,*dfree);
659 return(((*bsize)/1024)*(*dfree));
664 /****************************************************************************
665 wrap it to get filenames right
666 ****************************************************************************/
667 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
669 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
674 /****************************************************************************
675 check a filename - possibly caling reducename
677 This is called by every routine before it allows an operation on a filename.
678 It does any final confirmation necessary to ensure that the filename is
679 a valid one for the user to access.
680 ****************************************************************************/
681 BOOL check_name(char *name,int cnum)
687 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
689 DEBUG(5,("check_name on %s failed\n",name));
694 /****************************************************************************
695 check a filename - possibly caling reducename
696 ****************************************************************************/
697 static void check_for_pipe(char *fname)
699 /* special case of pipe opens */
703 if (strstr(s,"pipe/"))
705 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
706 unix_ERR_class = ERRSRV;
707 unix_ERR_code = ERRaccess;
712 /****************************************************************************
714 ****************************************************************************/
715 void open_file(int fnum,int cnum,char *fname1,int flags,int mode)
719 Files[fnum].open = False;
723 strcpy(fname,fname1);
725 /* check permissions */
726 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
728 DEBUG(3,("Permission denied opening %s\n",fname));
729 check_for_pipe(fname);
733 /* this handles a bug in Win95 - it doesn't say to create the file when it
735 if (Connections[cnum].printer)
739 if (flags == O_WRONLY)
740 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
744 /* XXXX - is this OK?? */
745 /* this works around a utime bug but can cause other problems */
746 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
751 Files[fnum].fd = sys_open(fname,flags,mode);
753 if ((Files[fnum].fd>=0) &&
754 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
759 p = strrchr(dname,'/');
761 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
762 lp_minprintspace(SNUM(cnum))) {
763 close(Files[fnum].fd);
772 /* Fix for files ending in '.' */
773 if((Files[fnum].fd == -1) && (errno == ENOENT) &&
774 (strchr(fname,'.')==NULL))
777 Files[fnum].fd = sys_open(fname,flags,mode);
780 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
781 if ((Files[fnum].fd == -1) && (errno == ENAMETOOLONG))
784 char *p = strrchr(fname, '/');
786 if (p == fname) /* name is "/xxx" */
788 max_len = pathconf("/", _PC_NAME_MAX);
791 else if ((p == NULL) || (p == fname))
794 max_len = pathconf(".", _PC_NAME_MAX);
799 max_len = pathconf(fname, _PC_NAME_MAX);
803 if (strlen(p) > max_len)
805 char tmp = p[max_len];
808 if ((Files[fnum].fd = sys_open(fname,flags,mode)) == -1)
814 if (Files[fnum].fd < 0)
816 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
817 fname,strerror(errno),flags));
818 check_for_pipe(fname);
822 if (Files[fnum].fd >= 0)
825 Connections[cnum].num_files_open++;
826 fstat(Files[fnum].fd,&st);
827 Files[fnum].mode = st.st_mode;
828 Files[fnum].open_time = time(NULL);
829 Files[fnum].size = 0;
830 Files[fnum].pos = -1;
831 Files[fnum].open = True;
832 Files[fnum].mmap_ptr = NULL;
833 Files[fnum].mmap_size = 0;
834 Files[fnum].can_lock = True;
835 Files[fnum].can_read = ((flags & O_WRONLY)==0);
836 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
837 Files[fnum].share_mode = 0;
838 Files[fnum].share_pending = False;
839 Files[fnum].print_file = Connections[cnum].printer;
840 Files[fnum].modified = False;
841 Files[fnum].cnum = cnum;
842 string_set(&Files[fnum].name,fname);
843 Files[fnum].wbmpx_ptr = NULL;
846 * If the printer is marked as postscript output a leading
847 * file identifier to ensure the file is treated as a raw
849 * This has a similar effect as CtrlD=0 in WIN.INI file.
850 * tim@fsg.com 09/06/94
852 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
853 Files[fnum].can_write)
855 DEBUG(3,("Writing postscript line\n"));
856 write_file(fnum,"%!\n",3);
859 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
860 timestring(),Connections[cnum].user,fname,
861 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
862 Connections[cnum].num_files_open,fnum));
867 /* mmap it if read-only */
868 if (!Files[fnum].can_write)
870 Files[fnum].mmap_size = file_size(fname);
871 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
872 PROT_READ,MAP_SHARED,Files[fnum].fd,0);
874 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
876 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
877 Files[fnum].mmap_ptr = NULL;
883 /*******************************************************************
885 ********************************************************************/
886 void sync_file(int fnum)
889 fsync(Files[fnum].fd);
893 /****************************************************************************
894 run a file if it is a magic script
895 ****************************************************************************/
896 static void check_magic(int fnum,int cnum)
898 if (!*lp_magicscript(SNUM(cnum)))
901 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
905 if (!(p = strrchr(Files[fnum].name,'/')))
906 p = Files[fnum].name;
910 if (!strequal(lp_magicscript(SNUM(cnum)),p))
916 pstring magic_output;
918 strcpy(fname,Files[fnum].name);
920 if (*lp_magicoutput(SNUM(cnum)))
921 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
923 sprintf(magic_output,"%s.out",fname);
926 ret = smbrun(fname,magic_output,False);
927 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
933 /****************************************************************************
934 close a file - possibly invalidating the read prediction
935 ****************************************************************************/
936 void close_file(int fnum)
938 int cnum = Files[fnum].cnum;
939 invalidate_read_prediction(Files[fnum].fd);
940 Files[fnum].open = False;
941 Connections[cnum].num_files_open--;
942 if(Files[fnum].wbmpx_ptr)
944 free((char *)Files[fnum].wbmpx_ptr);
945 Files[fnum].wbmpx_ptr = NULL;
949 if(Files[fnum].mmap_ptr)
951 munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size);
952 Files[fnum].mmap_ptr = NULL;
956 if (lp_share_modes(SNUM(cnum)))
957 del_share_mode(fnum);
959 close(Files[fnum].fd);
961 /* NT uses smbclose to start a print - weird */
962 if (Files[fnum].print_file)
965 /* check for magic scripts */
966 check_magic(fnum,cnum);
968 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
969 timestring(),Connections[cnum].user,Files[fnum].name,
970 Connections[cnum].num_files_open));
973 enum {AFAIL,AREAD,AWRITE,AALL};
975 /*******************************************************************
976 reproduce the share mode access table
977 ********************************************************************/
978 static int access_table(int new_deny,int old_deny,int old_mode,
979 int share_pid,char *fname)
981 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
983 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
984 if (old_deny == new_deny && share_pid == getpid())
987 if (old_mode == 0) return(AREAD);
989 /* the new smbpub.zip spec says that if the file extension is
990 .com, .dll, .exe or .sym then allow the open. I will force
991 it to read-only as this seems sensible although the spec is
992 a little unclear on this. */
993 if ((fname = strrchr(fname,'.'))) {
994 if (strequal(fname,".com") ||
995 strequal(fname,".dll") ||
996 strequal(fname,".exe") ||
997 strequal(fname,".sym"))
1007 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1008 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1009 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1012 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1013 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1014 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1017 if (old_deny==DENY_WRITE) return(AREAD);
1018 if (old_deny==DENY_READ) return(AWRITE);
1019 if (old_deny==DENY_NONE) return(AALL);
1025 /*******************************************************************
1026 check if the share mode on a file allows it to be deleted or unlinked
1027 return True if sharing doesn't prevent the operation
1028 ********************************************************************/
1029 BOOL check_file_sharing(int cnum,char *fname)
1032 int share_mode = get_share_mode_byname(cnum,fname,&pid);
1034 if (!pid || !share_mode) return(True);
1036 if (share_mode == DENY_DOS)
1037 return(pid == getpid());
1039 /* XXXX exactly what share mode combinations should be allowed for
1040 deleting/renaming? */
1044 /****************************************************************************
1046 Helper for open_file_shared.
1047 Truncate a file after checking locking; close file if locked.
1048 **************************************************************************/
1049 static void truncate_unless_locked(int fnum, int cnum)
1051 if (Files[fnum].can_write){
1052 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1055 unix_ERR_class = ERRDOS;
1056 unix_ERR_code = ERRlock;
1059 ftruncate(Files[fnum].fd,0);
1064 /****************************************************************************
1065 open a file with a share mode
1066 ****************************************************************************/
1067 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1068 int mode,int *Access,int *action)
1072 int deny_mode = (share_mode>>4)&7;
1074 BOOL file_existed = file_exist(fname,&sbuf);
1075 BOOL fcbopen = False;
1078 Files[fnum].open = False;
1079 Files[fnum].fd = -1;
1081 /* this is for OS/2 EAs - try and say we don't support them */
1082 if (strstr(fname,".+,;=[].")) {
1083 unix_ERR_class = ERRDOS;
1084 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1088 if ((ofun & 0x3) == 0 && file_existed) {
1095 if ((ofun & 0x3) == 2)
1098 /* note that we ignore the append flag as
1099 append does not mean the same thing under dos and unix */
1101 switch (share_mode&0xF)
1118 if (flags != O_RDONLY && file_existed &&
1119 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) {
1127 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
1128 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1133 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1135 if (lp_share_modes(SNUM(cnum))) {
1139 old_share = get_share_mode(cnum,&sbuf,&share_pid);
1142 /* someone else has a share lock on it, check to see
1144 int old_open_mode = old_share&0xF;
1145 int old_deny_mode = (old_share>>4)&7;
1147 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) {
1148 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1149 deny_mode,old_deny_mode,old_open_mode,fname));
1151 unix_ERR_class = ERRDOS;
1152 unix_ERR_code = ERRbadshare;
1157 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1160 if ((access_allowed == AFAIL) ||
1161 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1162 (access_allowed == AREAD && flags == O_WRONLY) ||
1163 (access_allowed == AWRITE && flags == O_RDONLY)) {
1164 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1165 deny_mode,old_deny_mode,old_open_mode,
1169 unix_ERR_class = ERRDOS;
1170 unix_ERR_code = ERRbadshare;
1174 if (access_allowed == AREAD)
1177 if (access_allowed == AWRITE)
1183 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1184 flags,flags2,mode));
1186 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode);
1187 if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) {
1189 open_file(fnum,cnum,fname,flags,mode);
1192 if (Files[fnum].open) {
1206 Files[fnum].share_mode = (deny_mode<<4) | open_mode;
1207 Files[fnum].share_pending = True;
1210 (*Access) = open_mode;
1214 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1215 if (!file_existed) *action = 2;
1216 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1220 share_mode_pending = True;
1222 if ((flags2&O_TRUNC) && file_existed)
1223 truncate_unless_locked(fnum,cnum);
1229 /*******************************************************************
1230 check for files that we should now set our share modes on
1231 ********************************************************************/
1232 static void check_share_modes(void)
1235 for (i=0;i<MAX_OPEN_FILES;i++)
1236 if(Files[i].open && Files[i].share_pending) {
1237 if (lp_share_modes(SNUM(Files[i].cnum))) {
1239 get_share_mode_by_fnum(Files[i].cnum,i,&pid);
1241 set_share_mode(i,Files[i].share_mode);
1242 Files[i].share_pending = False;
1245 Files[i].share_pending = False;
1251 /****************************************************************************
1252 seek a file. Try to avoid the seek if possible
1253 ****************************************************************************/
1254 int seek_file(int fnum,int pos)
1257 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1260 Files[fnum].pos = lseek(Files[fnum].fd,pos+offset,SEEK_SET) - offset;
1261 return(Files[fnum].pos);
1264 /****************************************************************************
1266 ****************************************************************************/
1267 int read_file(int fnum,char *data,int pos,int n)
1271 if (!Files[fnum].can_write)
1273 ret = read_predict(Files[fnum].fd,pos,data,NULL,n);
1281 if (Files[fnum].mmap_ptr)
1283 int num = MIN(n,Files[fnum].mmap_size-pos);
1286 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1298 if (seek_file(fnum,pos) != pos)
1300 DEBUG(3,("Failed to seek to %d\n",pos));
1305 readret = read(Files[fnum].fd,data,n);
1306 if (readret > 0) ret += readret;
1313 /****************************************************************************
1315 ****************************************************************************/
1316 int write_file(int fnum,char *data,int n)
1318 if (!Files[fnum].can_write) {
1323 if (!Files[fnum].modified) {
1325 Files[fnum].modified = True;
1326 if (fstat(Files[fnum].fd,&st) == 0) {
1327 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1328 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1329 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1334 return(write_data(Files[fnum].fd,data,n));
1338 /****************************************************************************
1339 load parameters specific to a connection/service
1340 ****************************************************************************/
1341 BOOL become_service(int cnum,BOOL do_chdir)
1343 extern char magic_char;
1344 static int last_cnum = -1;
1347 if (!OPEN_CNUM(cnum))
1353 Connections[cnum].lastused = smb_last_time;
1358 ChDir(Connections[cnum].connectpath) != 0 &&
1359 ChDir(Connections[cnum].origpath) != 0)
1361 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1362 Connections[cnum].connectpath,cnum));
1366 if (cnum == last_cnum)
1371 case_default = lp_defaultcase(snum);
1372 case_preserve = lp_preservecase(snum);
1373 short_case_preserve = lp_shortpreservecase(snum);
1374 case_mangle = lp_casemangle(snum);
1375 case_sensitive = lp_casesensitive(snum);
1376 magic_char = lp_magicchar(snum);
1377 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1382 /****************************************************************************
1383 find a service entry
1384 ****************************************************************************/
1385 int find_service(char *service)
1389 string_sub(service,"\\","/");
1391 iService = lp_servicenumber(service);
1393 /* now handle the special case of a home directory */
1396 char *phome_dir = get_home_dir(service);
1397 DEBUG(3,("checking for home directory %s gave %s\n",service,
1398 phome_dir?phome_dir:"(NULL)"));
1402 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1404 lp_add_home(service,iHomeService,phome_dir);
1405 iService = lp_servicenumber(service);
1410 /* If we still don't have a service, attempt to add it as a printer. */
1413 int iPrinterService;
1415 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1419 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1421 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1423 DEBUG(3,("%s is a valid printer name\n", service));
1424 DEBUG(3,("adding %s as a printer service\n", service));
1425 lp_add_printer(service,iPrinterService);
1426 iService = lp_servicenumber(service);
1428 DEBUG(0,("failed to add %s as a printer service!\n", service));
1431 DEBUG(3,("%s is not a valid printer name\n", service));
1435 /* just possibly it's a default service? */
1438 char *defservice = lp_defaultservice();
1439 if (defservice && *defservice && !strequal(defservice,service)) {
1440 iService = find_service(defservice);
1441 if (iService >= 0) {
1442 string_sub(service,"_","/");
1443 iService = lp_add_service(service,iService);
1449 if (!VALID_SNUM(iService))
1451 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1456 DEBUG(3,("find_service() failed to find service %s\n", service));
1462 /****************************************************************************
1463 create an error packet from a cached error.
1464 ****************************************************************************/
1465 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1467 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1469 int32 eclass = wbmpx->wr_errclass;
1470 int32 err = wbmpx->wr_error;
1472 /* We can now delete the auxiliary struct */
1473 free((char *)wbmpx);
1474 Files[fnum].wbmpx_ptr = NULL;
1475 return error_packet(inbuf,outbuf,eclass,err,line);
1484 } unix_smb_errmap[] =
1486 {EPERM,ERRDOS,ERRnoaccess},
1487 {EACCES,ERRDOS,ERRnoaccess},
1488 {ENOENT,ERRDOS,ERRbadfile},
1489 {EIO,ERRHRD,ERRgeneral},
1490 {EBADF,ERRSRV,ERRsrverror},
1491 {EINVAL,ERRSRV,ERRsrverror},
1492 {EEXIST,ERRDOS,ERRfilexists},
1493 {ENFILE,ERRDOS,ERRnofids},
1494 {EMFILE,ERRDOS,ERRnofids},
1495 {ENOSPC,ERRHRD,ERRdiskfull},
1497 {EDQUOT,ERRHRD,ERRdiskfull},
1500 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1503 {EXDEV,ERRDOS,ERRdiffdevice},
1505 {EROFS,ERRHRD,ERRnowrite},
1510 /****************************************************************************
1511 create an error packet from errno
1512 ****************************************************************************/
1513 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1515 int eclass=def_class;
1519 if (unix_ERR_class != SUCCESS)
1521 eclass = unix_ERR_class;
1522 ecode = unix_ERR_code;
1523 unix_ERR_class = SUCCESS;
1528 while (unix_smb_errmap[i].smbclass != 0)
1530 if (unix_smb_errmap[i].unixerror == errno)
1532 eclass = unix_smb_errmap[i].smbclass;
1533 ecode = unix_smb_errmap[i].smbcode;
1540 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1544 /****************************************************************************
1545 create an error packet. Normally called using the ERROR() macro
1546 ****************************************************************************/
1547 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1549 int outsize = set_message(outbuf,0,0,True);
1551 cmd = CVAL(inbuf,smb_com);
1553 CVAL(outbuf,smb_rcls) = error_class;
1554 SSVAL(outbuf,smb_err,error_code);
1556 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1559 (int)CVAL(inbuf,smb_com),
1560 smb_fn_name(CVAL(inbuf,smb_com)),
1565 DEBUG(3,("error string = %s\n",strerror(errno)));
1571 #ifndef SIGCLD_IGNORE
1572 /****************************************************************************
1573 this prevents zombie child processes
1574 ****************************************************************************/
1575 static int sig_cld()
1577 static int depth = 0;
1580 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1586 BlockSignals(True,SIGCLD);
1587 DEBUG(5,("got SIGCLD\n"));
1590 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1594 /* Stevens, Adv. Unix Prog. says that on system V you must call
1595 wait before reinstalling the signal handler, because the kernel
1596 calls the handler from within the signal-call when there is a
1597 child that has exited. This would lead to an infinite recursion
1598 if done vice versa. */
1600 #ifndef DONT_REINSTALL_SIG
1601 #ifdef SIGCLD_IGNORE
1602 signal(SIGCLD, SIG_IGN);
1604 signal(SIGCLD, SIGNAL_CAST sig_cld);
1609 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1612 BlockSignals(False,SIGCLD);
1617 /****************************************************************************
1618 this is called when the client exits abruptly
1619 **************************************************************************/
1620 static int sig_pipe()
1622 extern int password_client;
1623 BlockSignals(True,SIGPIPE);
1625 if (password_client != -1) {
1626 DEBUG(3,("lost connection to password server\n"));
1627 close(password_client);
1628 password_client = -1;
1629 #ifndef DONT_REINSTALL_SIG
1630 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1632 BlockSignals(False,SIGPIPE);
1636 exit_server("Got sigpipe\n");
1640 /****************************************************************************
1641 open the socket communication
1642 ****************************************************************************/
1643 static BOOL open_sockets(BOOL is_daemon,int port)
1650 struct sockaddr addr;
1651 int in_addrlen = sizeof(addr);
1654 #ifdef SIGCLD_IGNORE
1655 signal(SIGCLD, SIG_IGN);
1657 signal(SIGCLD, SIGNAL_CAST sig_cld);
1660 /* open an incoming socket */
1661 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
1665 /* ready to listen */
1666 if (listen(s, 5) == -1)
1668 DEBUG(0,("listen: %s",strerror(errno)));
1673 /* now accept incoming connections - forking a new process
1674 for each incoming connection */
1675 DEBUG(2,("waiting for a connection\n"));
1678 Client = accept(s,&addr,&in_addrlen);
1680 if (Client == -1 && errno == EINTR)
1685 DEBUG(0,("accept: %s",strerror(errno)));
1689 #ifdef NO_FORK_DEBUG
1690 #ifndef NO_SIGNAL_TEST
1691 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1692 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1696 if (Client != -1 && fork()==0)
1698 #ifndef NO_SIGNAL_TEST
1699 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1700 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1702 /* close the listening socket */
1705 /* close our standard file descriptors */
1708 set_socket_options(Client,"SO_KEEPALIVE");
1709 set_socket_options(Client,user_socket_options);
1713 close(Client); /* The parent doesn't need this socket */
1719 /* We will abort gracefully when the client or remote system
1721 #ifndef NO_SIGNAL_TEST
1722 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1726 /* close our standard file descriptors */
1729 set_socket_options(Client,"SO_KEEPALIVE");
1730 set_socket_options(Client,user_socket_options);
1737 /****************************************************************************
1738 check if a snum is in use
1739 ****************************************************************************/
1740 BOOL snum_used(int snum)
1743 for (i=0;i<MAX_CONNECTIONS;i++)
1744 if (OPEN_CNUM(i) && (SNUM(i) == snum))
1749 /****************************************************************************
1750 reload the services file
1751 **************************************************************************/
1752 BOOL reload_services(BOOL test)
1759 strcpy(fname,lp_configfile());
1760 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
1762 strcpy(servicesf,fname);
1769 if (test && !lp_file_list_changed())
1772 lp_killunused(snum_used);
1774 ret = lp_load(servicesf,False);
1776 /* perhaps the config filename is now set */
1778 reload_services(True);
1787 set_socket_options(Client,"SO_KEEPALIVE");
1788 set_socket_options(Client,user_socket_options);
1792 create_mangled_stack(lp_mangledstack());
1794 /* this forces service parameters to be flushed */
1795 become_service(-1,True);
1802 /****************************************************************************
1803 this prevents zombie child processes
1804 ****************************************************************************/
1805 static int sig_hup()
1807 BlockSignals(True,SIGHUP);
1808 DEBUG(0,("Got SIGHUP\n"));
1809 reload_services(False);
1810 #ifndef DONT_REINSTALL_SIG
1811 signal(SIGHUP,SIGNAL_CAST sig_hup);
1813 BlockSignals(False,SIGHUP);
1817 /****************************************************************************
1818 Setup the groups a user belongs to.
1819 ****************************************************************************/
1820 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
1821 int **p_igroups, gid_t **p_groups)
1823 if (-1 == initgroups(user,gid))
1827 DEBUG(0,("Unable to initgroups!\n"));
1828 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
1829 DEBUG(0,("This is probably a problem with the account %s\n",user));
1837 ngroups = getgroups(0,&grp);
1840 igroups = (int *)malloc(sizeof(int)*ngroups);
1841 for (i=0;i<ngroups;i++)
1842 igroups[i] = 0x42424242;
1843 ngroups = getgroups(ngroups,(gid_t *)igroups);
1845 if (igroups[0] == 0x42424242)
1848 *p_ngroups = ngroups;
1850 /* The following bit of code is very strange. It is due to the
1851 fact that some OSes use int* and some use gid_t* for
1852 getgroups, and some (like SunOS) use both, one in prototypes,
1853 and one in man pages and the actual code. Thus we detect it
1854 dynamically using some very ugly code */
1857 /* does getgroups return ints or gid_t ?? */
1858 static BOOL groups_use_ints = True;
1860 if (groups_use_ints &&
1862 SVAL(igroups,2) == 0x4242)
1863 groups_use_ints = False;
1865 for (i=0;groups_use_ints && i<ngroups;i++)
1866 if (igroups[i] == 0x42424242)
1867 groups_use_ints = False;
1869 if (groups_use_ints)
1871 *p_igroups = igroups;
1872 *p_groups = (gid_t *)igroups;
1876 gid_t *groups = (gid_t *)igroups;
1877 igroups = (int *)malloc(sizeof(int)*ngroups);
1878 for (i=0;i<ngroups;i++)
1879 igroups[i] = groups[i];
1880 *p_igroups = igroups;
1881 *p_groups = (gid_t *)groups;
1884 DEBUG(3,("%s is in %d groups\n",user,ngroups));
1885 for (i=0;i<ngroups;i++)
1886 DEBUG(3,("%d ",igroups[i]));
1892 /****************************************************************************
1893 make a connection to a service
1894 ****************************************************************************/
1895 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid)
1899 struct passwd *pass = NULL;
1900 connection_struct *pcon;
1903 static BOOL first_connection = True;
1907 snum = find_service(service);
1910 if (strequal(service,"IPC$"))
1912 DEBUG(3,("%s refusing IPC connection\n",timestring()));
1916 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
1920 if (strequal(service,HOMES_NAME))
1922 if (*user && Get_Pwnam(user,True))
1923 return(make_connection(user,user,password,pwlen,dev,vuid));
1925 if (validated_username(vuid))
1927 strcpy(user,validated_username(vuid));
1928 return(make_connection(user,user,password,pwlen,dev,vuid));
1932 if (!lp_snum_ok(snum) || !check_access(snum)) {
1936 /* you can only connect to the IPC$ service as an ipc device */
1937 if (strequal(service,"IPC$"))
1940 if (*dev == '?' || !*dev)
1942 if (lp_print_ok(snum))
1943 strcpy(dev,"LPT1:");
1948 /* if the request is as a printer and you can't print then refuse */
1950 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
1951 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
1955 /* lowercase the user name */
1958 /* add it as a possible user name */
1959 add_session_user(service);
1961 /* shall we let them in? */
1962 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
1964 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
1968 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
1971 DEBUG(0,("%s couldn't find free connection\n",timestring()));
1975 pcon = &Connections[cnum];
1976 bzero((char *)pcon,sizeof(*pcon));
1978 /* find out some info about the user */
1979 pass = Get_Pwnam(user,True);
1983 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
1987 pcon->read_only = lp_readonly(snum);
1991 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
1992 string_sub(list,"%S",service);
1994 if (user_in_list(user,list))
1995 pcon->read_only = True;
1997 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
1998 string_sub(list,"%S",service);
2000 if (user_in_list(user,list))
2001 pcon->read_only = False;
2004 /* admin user check */
2005 if (user_in_list(user,lp_admin_users(snum)) &&
2008 pcon->admin_user = True;
2009 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2012 pcon->admin_user = False;
2014 pcon->force_user = force;
2015 pcon->uid = pass->pw_uid;
2016 pcon->gid = pass->pw_gid;
2017 pcon->num_files_open = 0;
2018 pcon->lastused = time(NULL);
2019 pcon->service = snum;
2021 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2022 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2023 pcon->dirptr = NULL;
2024 string_set(&pcon->dirpath,"");
2025 string_set(&pcon->user,user);
2028 if (*lp_force_group(snum))
2030 struct group *gptr = (struct group *)getgrnam(lp_force_group(snum));
2033 pcon->gid = gptr->gr_gid;
2034 DEBUG(3,("Forced group %s\n",lp_force_group(snum)));
2037 DEBUG(1,("Couldn't find group %s\n",lp_force_group(snum)));
2041 if (*lp_force_user(snum))
2043 struct passwd *pass2;
2045 strcpy(fuser,lp_force_user(snum));
2046 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2049 pcon->uid = pass2->pw_uid;
2050 string_set(&pcon->user,fuser);
2052 pcon->force_user = True;
2053 DEBUG(3,("Forced user %s\n",fuser));
2056 DEBUG(1,("Couldn't find user %s\n",fuser));
2061 strcpy(s,lp_pathname(snum));
2062 standard_sub(cnum,s);
2063 string_set(&pcon->connectpath,s);
2064 DEBUG(3,("Connect path is %s\n",s));
2067 /* groups stuff added by ih */
2069 pcon->groups = NULL;
2073 /* Find all the groups this uid is in and store them. Used by become_user() */
2074 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2076 /* check number of connections */
2077 if (!claim_connection(cnum,
2078 lp_servicename(SNUM(cnum)),
2079 lp_max_connections(SNUM(cnum)),False))
2081 DEBUG(1,("too many connections - rejected\n"));
2085 if (lp_status(SNUM(cnum)))
2086 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2088 first_connection = False;
2093 /* execute any "root preexec = " line */
2094 if (*lp_rootpreexec(SNUM(cnum)))
2097 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2098 standard_sub(cnum,cmd);
2099 DEBUG(5,("cmd=%s\n",cmd));
2100 smbrun(cmd,NULL,False);
2103 if (!become_user(cnum,pcon->uid))
2105 DEBUG(0,("Can't become connected user!\n"));
2107 if (!IS_IPC(cnum)) {
2108 yield_connection(cnum,
2109 lp_servicename(SNUM(cnum)),
2110 lp_max_connections(SNUM(cnum)));
2111 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2116 if (ChDir(pcon->connectpath) != 0)
2118 DEBUG(0,("Can't change directory to %s (%s)\n",
2119 pcon->connectpath,strerror(errno)));
2122 if (!IS_IPC(cnum)) {
2123 yield_connection(cnum,
2124 lp_servicename(SNUM(cnum)),
2125 lp_max_connections(SNUM(cnum)));
2126 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2131 string_set(&pcon->origpath,pcon->connectpath);
2133 #if SOFTLINK_OPTIMISATION
2134 /* resolve any soft links early */
2137 strcpy(s,pcon->connectpath);
2139 string_set(&pcon->connectpath,s);
2140 ChDir(pcon->connectpath);
2144 num_connections_open++;
2145 add_session_user(user);
2147 /* execute any "preexec = " line */
2148 if (*lp_preexec(SNUM(cnum)))
2151 strcpy(cmd,lp_preexec(SNUM(cnum)));
2152 standard_sub(cnum,cmd);
2153 smbrun(cmd,NULL,False);
2156 /* we've finished with the sensitive stuff */
2160 extern struct from_host Client_info;
2161 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2163 Client_info.name,Client_info.addr,
2164 lp_servicename(SNUM(cnum)),user,
2174 /****************************************************************************
2175 find first available file slot
2176 ****************************************************************************/
2177 int find_free_file(void )
2180 /* we start at 1 here for an obscure reason I can't now remember,
2181 but I think is important :-) */
2182 for (i=1;i<MAX_OPEN_FILES;i++)
2185 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2189 /****************************************************************************
2190 find first available connection slot, starting from a random position.
2191 The randomisation stops problems with the server dieing and clients
2192 thinking the server is still available.
2193 ****************************************************************************/
2194 static int find_free_connection(int hash )
2198 hash = (hash % (MAX_CONNECTIONS-2))+1;
2202 for (i=hash+1;i!=hash;)
2204 if (!Connections[i].open && Connections[i].used == used)
2206 DEBUG(3,("found free connection number %d\n",i));
2210 if (i == MAX_CONNECTIONS)
2220 DEBUG(1,("ERROR! Out of connection structures\n"));
2225 /****************************************************************************
2226 reply for the core protocol
2227 ****************************************************************************/
2228 int reply_corep(char *outbuf)
2230 int outsize = set_message(outbuf,1,0,True);
2232 Protocol = PROTOCOL_CORE;
2238 /****************************************************************************
2239 reply for the coreplus protocol
2240 ****************************************************************************/
2241 int reply_coreplus(char *outbuf)
2243 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2244 int outsize = set_message(outbuf,13,0,True);
2245 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2246 readbraw and writebraw (possibly) */
2247 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2248 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2250 Protocol = PROTOCOL_COREPLUS;
2256 /****************************************************************************
2257 reply for the lanman 1.0 protocol
2258 ****************************************************************************/
2259 int reply_lanman1(char *outbuf)
2261 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2263 BOOL doencrypt = SMBENCRYPT();
2264 time_t t = time(NULL);
2266 if (lp_security()>=SEC_USER) secword |= 1;
2267 if (doencrypt) secword |= 2;
2269 set_message(outbuf,13,doencrypt?8:0,True);
2270 SSVAL(outbuf,smb_vwv1,secword);
2272 /* Create a token value and add it to the outgoing packet. */
2274 generate_next_challenge(smb_buf(outbuf));
2277 Protocol = PROTOCOL_LANMAN1;
2279 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2280 DEBUG(3,("using password server validation\n"));
2282 if (doencrypt) set_challenge(smb_buf(outbuf));
2286 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2287 SSVAL(outbuf,smb_vwv2,maxxmit);
2288 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2289 SSVAL(outbuf,smb_vwv4,1);
2290 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2291 readbraw writebraw (possibly) */
2292 SIVAL(outbuf,smb_vwv6,getpid());
2293 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2295 put_dos_date(outbuf,smb_vwv8,t);
2297 return (smb_len(outbuf)+4);
2301 /****************************************************************************
2302 reply for the lanman 2.0 protocol
2303 ****************************************************************************/
2304 int reply_lanman2(char *outbuf)
2306 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2308 BOOL doencrypt = SMBENCRYPT();
2309 time_t t = time(NULL);
2311 if (lp_security()>=SEC_USER) secword |= 1;
2312 if (doencrypt) secword |= 2;
2314 set_message(outbuf,13,doencrypt?8:0,True);
2315 SSVAL(outbuf,smb_vwv1,secword);
2317 /* Create a token value and add it to the outgoing packet. */
2319 generate_next_challenge(smb_buf(outbuf));
2322 SIVAL(outbuf,smb_vwv6,getpid());
2324 Protocol = PROTOCOL_LANMAN2;
2326 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2327 DEBUG(3,("using password server validation\n"));
2329 if (doencrypt) set_challenge(smb_buf(outbuf));
2333 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2334 SSVAL(outbuf,smb_vwv2,maxxmit);
2335 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2336 SSVAL(outbuf,smb_vwv4,1);
2337 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2338 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2339 put_dos_date(outbuf,smb_vwv8,t);
2341 return (smb_len(outbuf)+4);
2344 /****************************************************************************
2345 reply for the nt protocol
2346 ****************************************************************************/
2347 int reply_nt1(char *outbuf)
2349 int capabilities=0x300; /* has dual names + lock_and_read */
2351 BOOL doencrypt = SMBENCRYPT();
2352 time_t t = time(NULL);
2354 if (lp_security()>=SEC_USER) secword |= 1;
2355 if (doencrypt) secword |= 2;
2357 set_message(outbuf,17,doencrypt?8:0,True);
2358 CVAL(outbuf,smb_vwv1) = secword;
2360 /* Create a token value and add it to the outgoing packet. */
2362 generate_next_challenge(smb_buf(outbuf));
2363 /* Tell the nt machine how long the challenge is. */
2364 SSVALS(outbuf,smb_vwv16+1,8);
2368 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2370 Protocol = PROTOCOL_NT1;
2372 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2373 DEBUG(3,("using password server validation\n"));
2375 if (doencrypt) set_challenge(smb_buf(outbuf));
2379 if (lp_readraw() && lp_writeraw())
2382 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2383 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2384 SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
2385 SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
2386 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2387 put_long_date(outbuf+smb_vwv11+1,t);
2388 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2390 return (smb_len(outbuf)+4);
2394 /* these are the protocol lists used for auto architecture detection:
2397 protocol [PC NETWORK PROGRAM 1.0]
2398 protocol [XENIX CORE]
2399 protocol [MICROSOFT NETWORKS 1.03]
2400 protocol [LANMAN1.0]
2401 protocol [Windows for Workgroups 3.1a]
2402 protocol [LM1.2X002]
2403 protocol [LANMAN2.1]
2404 protocol [NT LM 0.12]
2407 protocol [PC NETWORK PROGRAM 1.0]
2408 protocol [XENIX CORE]
2409 protocol [MICROSOFT NETWORKS 1.03]
2410 protocol [LANMAN1.0]
2411 protocol [Windows for Workgroups 3.1a]
2412 protocol [LM1.2X002]
2413 protocol [LANMAN2.1]
2414 protocol [NT LM 0.12]
2417 protocol [PC NETWORK PROGRAM 1.0]
2418 protocol [XENIX CORE]
2419 protocol [LANMAN1.0]
2420 protocol [LM1.2X002]
2421 protocol [LANMAN2.1]
2425 * Modified to recognize the architecture of the remote machine better.
2427 * This appears to be the matrix of which protocol is used by which
2429 Protocol WfWg Win95 WinNT OS/2
2430 PC NETWORK PROGRAM 1.0 1 1 1 1
2432 MICROSOFT NETWORKS 3.0 2 2
2434 MICROSOFT NETWORKS 1.03 3
2437 Windows for Workgroups 3.1a 5 5 5
2442 * tim@fsg.com 09/29/95
2445 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2446 #define ARCH_WIN95 0x2
2447 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2448 #define ARCH_WINNT 0x8
2449 #define ARCH_SAMBA 0x10
2451 #define ARCH_ALL 0x1F
2453 /* List of supported protocols, most desired first */
2457 int (*proto_reply_fn)(char *);
2459 } supported_protocols[] = {
2460 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2461 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2462 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2463 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2464 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2465 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2466 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2467 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2468 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2473 /****************************************************************************
2475 ****************************************************************************/
2476 static int reply_negprot(char *inbuf,char *outbuf)
2478 extern fstring remote_arch;
2479 int outsize = set_message(outbuf,1,0,True);
2484 int bcc = SVAL(smb_buf(inbuf),-2);
2485 int arch = ARCH_ALL;
2487 p = smb_buf(inbuf)+1;
2488 while (p < (smb_buf(inbuf) + bcc))
2491 DEBUG(3,("Requested protocol [%s]\n",p));
2492 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2493 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2494 else if (strcsequal(p,"DOS LM1.2X002"))
2495 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2496 else if (strcsequal(p,"DOS LANMAN2.1"))
2497 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2498 else if (strcsequal(p,"NT LM 0.12"))
2499 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2500 else if (strcsequal(p,"LANMAN2.1"))
2501 arch &= ( ARCH_WINNT | ARCH_OS2 );
2502 else if (strcsequal(p,"LM1.2X002"))
2503 arch &= ( ARCH_WINNT | ARCH_OS2 );
2504 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2506 else if (strcsequal(p,"XENIX CORE"))
2507 arch &= ( ARCH_WINNT | ARCH_OS2 );
2508 else if (strcsequal(p,"Samba")) {
2518 strcpy(remote_arch,"Samba");
2521 strcpy(remote_arch,"WfWg");
2524 strcpy(remote_arch,"Win95");
2527 strcpy(remote_arch,"WinNT");
2530 strcpy(remote_arch,"OS2");
2533 strcpy(remote_arch,"UNKNOWN");
2537 /* possibly reload - change of architecture */
2538 reload_services(True);
2540 /* a special case to stop password server loops */
2541 if (Index == 1 && strequal(remote_machine,myhostname) &&
2542 lp_security()==SEC_SERVER)
2543 exit_server("Password server loop!");
2545 /* Check for protocols, most desirable first */
2546 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2548 p = smb_buf(inbuf)+1;
2550 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2551 while (p < (smb_buf(inbuf) + bcc))
2553 if (strequal(p,supported_protocols[protocol].proto_name))
2562 SSVAL(outbuf,smb_vwv0,choice);
2564 extern fstring remote_proto;
2565 strcpy(remote_proto,supported_protocols[protocol].short_name);
2566 reload_services(True);
2567 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
2568 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
2571 DEBUG(0,("No protocol supported !\n"));
2573 SSVAL(outbuf,smb_vwv0,choice);
2575 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
2581 /****************************************************************************
2582 close all open files for a connection
2583 ****************************************************************************/
2584 static void close_open_files(int cnum)
2587 for (i=0;i<MAX_OPEN_FILES;i++)
2588 if( Files[i].cnum == cnum && Files[i].open) {
2595 /****************************************************************************
2597 ****************************************************************************/
2598 void close_cnum(int cnum, int uid)
2600 extern struct from_host Client_info;
2602 DirCacheFlush(SNUM(cnum));
2606 if (!OPEN_CNUM(cnum))
2608 DEBUG(0,("Can't close cnum %d\n",cnum));
2612 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
2614 Client_info.name,Client_info.addr,
2615 lp_servicename(SNUM(cnum))));
2617 yield_connection(cnum,
2618 lp_servicename(SNUM(cnum)),
2619 lp_max_connections(SNUM(cnum)));
2621 if (lp_status(SNUM(cnum)))
2622 yield_connection(cnum,"STATUS.",MAXSTATUS);
2624 close_open_files(cnum);
2625 dptr_closecnum(cnum);
2627 /* execute any "postexec = " line */
2628 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,uid))
2631 strcpy(cmd,lp_postexec(SNUM(cnum)));
2632 standard_sub(cnum,cmd);
2633 smbrun(cmd,NULL,False);
2638 /* execute any "root postexec = " line */
2639 if (*lp_rootpostexec(SNUM(cnum)))
2642 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
2643 standard_sub(cnum,cmd);
2644 smbrun(cmd,NULL,False);
2647 Connections[cnum].open = False;
2648 num_connections_open--;
2649 if (Connections[cnum].ngroups && Connections[cnum].groups)
2651 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
2652 free(Connections[cnum].groups);
2653 free(Connections[cnum].igroups);
2654 Connections[cnum].groups = NULL;
2655 Connections[cnum].igroups = NULL;
2656 Connections[cnum].ngroups = 0;
2659 string_set(&Connections[cnum].user,"");
2660 string_set(&Connections[cnum].dirpath,"");
2661 string_set(&Connections[cnum].connectpath,"");
2665 /****************************************************************************
2666 simple routines to do connection counting
2667 ****************************************************************************/
2668 BOOL yield_connection(int cnum,char *name,int max_connections)
2670 struct connect_record crec;
2673 int mypid = getpid();
2676 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
2678 if (max_connections <= 0)
2681 bzero(&crec,sizeof(crec));
2683 strcpy(fname,lp_lockdir());
2684 standard_sub(cnum,fname);
2685 trim_string(fname,"","/");
2689 strcat(fname,".LCK");
2691 f = fopen(fname,"r+");
2694 DEBUG(2,("Coudn't open lock file %s (%s)\n",fname,strerror(errno)));
2698 fseek(f,0,SEEK_SET);
2700 /* find a free spot */
2701 for (i=0;i<max_connections;i++)
2703 if (fread(&crec,sizeof(crec),1,f) != 1)
2705 DEBUG(2,("Entry not found in lock file %s\n",fname));
2709 if (crec.pid == mypid && crec.cnum == cnum)
2713 if (crec.pid != mypid || crec.cnum != cnum)
2716 DEBUG(2,("Entry not found in lock file %s\n",fname));
2720 bzero((void *)&crec,sizeof(crec));
2722 /* remove our mark */
2723 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2724 fwrite(&crec,sizeof(crec),1,f) != 1)
2726 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
2731 DEBUG(3,("Yield successful\n"));
2738 /****************************************************************************
2739 simple routines to do connection counting
2740 ****************************************************************************/
2741 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
2743 struct connect_record crec;
2746 int snum = SNUM(cnum);
2750 if (max_connections <= 0)
2753 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
2755 strcpy(fname,lp_lockdir());
2756 standard_sub(cnum,fname);
2757 trim_string(fname,"","/");
2759 if (!directory_exist(fname,NULL))
2764 strcat(fname,".LCK");
2766 if (!file_exist(fname,NULL))
2768 int oldmask = umask(022);
2769 f = fopen(fname,"w");
2774 total_recs = file_size(fname) / sizeof(crec);
2776 f = fopen(fname,"r+");
2780 DEBUG(1,("couldn't open lock file %s\n",fname));
2784 /* find a free spot */
2785 for (i=0;i<max_connections;i++)
2788 if (i>=total_recs ||
2789 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2790 fread(&crec,sizeof(crec),1,f) != 1)
2792 if (foundi < 0) foundi = i;
2796 if (Clear && crec.pid && !process_exists(crec.pid))
2798 fseek(f,i*sizeof(crec),SEEK_SET);
2799 bzero((void *)&crec,sizeof(crec));
2800 fwrite(&crec,sizeof(crec),1,f);
2801 if (foundi < 0) foundi = i;
2804 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
2813 DEBUG(3,("no free locks in %s\n",fname));
2818 /* fill in the crec */
2819 bzero((void *)&crec,sizeof(crec));
2820 crec.magic = 0x280267;
2821 crec.pid = getpid();
2823 crec.uid = Connections[cnum].uid;
2824 crec.gid = Connections[cnum].gid;
2825 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
2826 crec.start = time(NULL);
2829 extern struct from_host Client_info;
2830 StrnCpy(crec.machine,Client_info.name,sizeof(crec.machine)-1);
2831 StrnCpy(crec.addr,Client_info.addr,sizeof(crec.addr)-1);
2835 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
2836 fwrite(&crec,sizeof(crec),1,f) != 1)
2847 /*******************************************************************
2848 prepare to dump a core file - carefully!
2849 ********************************************************************/
2850 static BOOL dump_core(void)
2854 strcpy(dname,debugf);
2855 if ((p=strrchr(dname,'/'))) *p=0;
2856 strcat(dname,"/corefiles");
2858 sys_chown(dname,getuid(),getgid());
2860 if (chdir(dname)) return(False);
2863 #ifndef NO_GETRLIMIT
2867 getrlimit(RLIMIT_CORE, &rlp);
2868 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
2869 setrlimit(RLIMIT_CORE, &rlp);
2870 getrlimit(RLIMIT_CORE, &rlp);
2871 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
2877 DEBUG(0,("Dumping core in %s\n",dname));
2882 /****************************************************************************
2884 ****************************************************************************/
2885 void exit_server(char *reason)
2887 static int firsttime=1;
2890 if (!firsttime) exit(0);
2894 DEBUG(2,("Closing connections\n"));
2895 for (i=0;i<MAX_CONNECTIONS;i++)
2896 if (Connections[i].open)
2899 if (dcelogin_atmost_once)
2903 int oldlevel = DEBUGLEVEL;
2905 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
2907 show_msg(last_inbuf);
2908 DEBUGLEVEL = oldlevel;
2909 DEBUG(0,("===============================================================\n"));
2911 if (dump_core()) return;
2914 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
2918 /****************************************************************************
2919 do some standard substitutions in a string
2920 ****************************************************************************/
2921 void standard_sub(int cnum,char *s)
2923 if (!strchr(s,'%')) return;
2925 if (VALID_CNUM(cnum))
2927 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
2928 string_sub(s,"%P",Connections[cnum].connectpath);
2929 string_sub(s,"%u",Connections[cnum].user);
2930 if (strstr(s,"%H")) {
2931 char *home = get_home_dir(Connections[cnum].user);
2932 if (home) string_sub(s,"%H",home);
2934 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
2936 standard_sub_basic(s);
2940 These flags determine some of the permissions required to do an operation
2942 Note that I don't set NEED_WRITE on some write operations because they
2943 are used by some brain-dead clients when printing, and I don't want to
2944 force write permissions on print services.
2946 #define AS_USER (1<<0)
2947 #define NEED_WRITE (1<<1)
2948 #define TIME_INIT (1<<2)
2949 #define CAN_IPC (1<<3)
2950 #define AS_GUEST (1<<5)
2954 define a list of possible SMB messages and their corresponding
2955 functions. Any message that has a NULL function is unimplemented -
2956 please feel free to contribute implementations!
2958 struct smb_message_struct
2972 {SMBnegprot,"SMBnegprot",reply_negprot,0},
2973 {SMBtcon,"SMBtcon",reply_tcon,0},
2974 {SMBtdis,"SMBtdis",reply_tdis,0},
2975 {SMBexit,"SMBexit",reply_exit,0},
2976 {SMBioctl,"SMBioctl",reply_ioctl,0},
2977 {SMBecho,"SMBecho",reply_echo,0},
2978 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
2979 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
2980 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0},
2981 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
2982 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
2983 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
2984 {SMBsearch,"SMBsearch",reply_search,AS_USER},
2985 {SMBopen,"SMBopen",reply_open,AS_USER},
2987 /* note that SMBmknew and SMBcreate are deliberately overloaded */
2988 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
2989 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
2991 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
2992 {SMBread,"SMBread",reply_read,AS_USER},
2993 {SMBwrite,"SMBwrite",reply_write,AS_USER},
2994 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
2995 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
2996 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
2997 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
2998 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3000 /* this is a Pathworks specific call, allowing the
3001 changing of the root path */
3002 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3004 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3005 {SMBflush,"SMBflush",reply_flush,AS_USER},
3006 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3007 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3008 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3009 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3010 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3011 {SMBlock,"SMBlock",reply_lock,AS_USER},
3012 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3014 /* CORE+ PROTOCOL FOLLOWS */
3016 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3017 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3018 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3019 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3020 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3022 /* LANMAN1.0 PROTOCOL FOLLOWS */
3024 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3025 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3026 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3027 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3028 {SMBwritec,"SMBwritec",NULL,AS_USER},
3029 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3030 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3031 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3032 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3033 {SMBioctls,"SMBioctls",NULL,AS_USER},
3034 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3035 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3037 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3038 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3039 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3040 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3042 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3043 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3044 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3046 /* LANMAN2.0 PROTOCOL FOLLOWS */
3047 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3048 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3049 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3050 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3052 /* messaging routines */
3053 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3054 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3055 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3056 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3058 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3060 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3061 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3062 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3063 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3066 /****************************************************************************
3067 return a string containing the function name of a SMB command
3068 ****************************************************************************/
3069 char *smb_fn_name(int type)
3071 static char *unknown_name = "SMBunknown";
3072 static int num_smb_messages =
3073 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3076 for (match=0;match<num_smb_messages;match++)
3077 if (smb_messages[match].code == type)
3080 if (match == num_smb_messages)
3081 return(unknown_name);
3083 return(smb_messages[match].name);
3087 /****************************************************************************
3088 do a switch on the message type, and return the response size
3089 ****************************************************************************/
3090 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3094 static int num_smb_messages =
3095 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3099 struct timeval msg_start_time;
3100 struct timeval msg_end_time;
3101 static unsigned long total_time = 0;
3103 GetTimeOfDay(&msg_start_time);
3110 last_message = type;
3112 /* make sure this is an SMB packet */
3113 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3115 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3119 for (match=0;match<num_smb_messages;match++)
3120 if (smb_messages[match].code == type)
3123 if (match == num_smb_messages)
3125 DEBUG(0,("Unknown message type %d!\n",type));
3126 outsize = reply_unknown(inbuf,outbuf);
3130 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3131 if (smb_messages[match].fn)
3133 int cnum = SVAL(inbuf,smb_tid);
3134 int flags = smb_messages[match].flags;
3135 int uid = SVAL(inbuf,smb_uid);
3137 /* does this protocol need to be run as root? */
3138 if (!(flags & AS_USER))
3141 /* does this protocol need to be run as the connected user? */
3142 if ((flags & AS_USER) && !become_user(cnum,uid)) {
3143 if (flags & AS_GUEST)
3146 return(ERROR(ERRSRV,ERRinvnid));
3148 /* this code is to work around a bug is MS client 3 without
3149 introducing a security hole - it needs to be able to do
3150 print queue checks as guest if it isn't logged in properly */
3151 if (flags & AS_USER)
3154 /* does it need write permission? */
3155 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3156 return(ERROR(ERRSRV,ERRaccess));
3158 /* ipc services are limited */
3159 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3160 return(ERROR(ERRSRV,ERRaccess));
3162 /* load service specific parameters */
3163 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3164 return(ERROR(ERRSRV,ERRaccess));
3166 /* does this protocol need to be run as guest? */
3167 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3168 return(ERROR(ERRSRV,ERRaccess));
3172 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3176 outsize = reply_unknown(inbuf,outbuf);
3181 GetTimeOfDay(&msg_end_time);
3182 if (!(smb_messages[match].flags & TIME_INIT))
3184 smb_messages[match].time = 0;
3185 smb_messages[match].flags |= TIME_INIT;
3188 unsigned long this_time =
3189 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3190 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3191 smb_messages[match].time += this_time;
3192 total_time += this_time;
3194 DEBUG(2,("TIME %s %d usecs %g pct\n",
3195 smb_fn_name(type),smb_messages[match].time,
3196 (100.0*smb_messages[match].time) / total_time));
3203 /****************************************************************************
3204 construct a chained reply and add it to the already made reply
3205 **************************************************************************/
3206 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3208 static char *orig_inbuf;
3209 static char *orig_outbuf;
3210 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3211 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3212 char *inbuf2, *outbuf2;
3214 char inbuf_saved[smb_wct];
3215 char outbuf_saved[smb_wct];
3216 extern int chain_size;
3217 int wct = CVAL(outbuf,smb_wct);
3218 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3220 /* maybe its not chained */
3221 if (smb_com2 == 0xFF) {
3222 CVAL(outbuf,smb_vwv0) = 0xFF;
3226 if (chain_size == 0) {
3227 /* this is the first part of the chain */
3229 orig_outbuf = outbuf;
3232 /* we need to tell the client where the next part of the reply will be */
3233 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3234 CVAL(outbuf,smb_vwv0) = smb_com2;
3236 /* remember how much the caller added to the chain, only counting stuff
3237 after the parameter words */
3238 chain_size += outsize - smb_wct;
3240 /* work out pointers into the original packets. The
3241 headers on these need to be filled in */
3242 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3243 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3245 /* remember the original command type */
3246 smb_com1 = CVAL(orig_inbuf,smb_com);
3248 /* save the data which will be overwritten by the new headers */
3249 memcpy(inbuf_saved,inbuf2,smb_wct);
3250 memcpy(outbuf_saved,outbuf2,smb_wct);
3252 /* give the new packet the same header as the last part of the SMB */
3253 memmove(inbuf2,inbuf,smb_wct);
3255 /* create the in buffer */
3256 CVAL(inbuf2,smb_com) = smb_com2;
3258 /* create the out buffer */
3259 bzero(outbuf2,smb_size);
3260 set_message(outbuf2,0,0,True);
3261 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3263 memcpy(outbuf2+4,inbuf2+4,4);
3264 CVAL(outbuf2,smb_rcls) = SUCCESS;
3265 CVAL(outbuf2,smb_reh) = 0;
3266 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3268 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3269 SSVAL(outbuf2,smb_err,SUCCESS);
3270 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3271 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3272 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3273 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3275 DEBUG(3,("Chained message\n"));
3278 /* process the request */
3279 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3280 bufsize-chain_size);
3282 /* copy the new reply and request headers over the old ones, but
3283 preserve the smb_com field */
3284 memmove(orig_outbuf,outbuf2,smb_wct);
3285 CVAL(orig_outbuf,smb_com) = smb_com1;
3287 /* restore the saved data, being careful not to overwrite any
3288 data from the reply header */
3289 memcpy(inbuf2,inbuf_saved,smb_wct);
3291 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3292 if (ofs < 0) ofs = 0;
3293 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3301 /****************************************************************************
3302 construct a reply to the incoming packet
3303 ****************************************************************************/
3304 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3306 int type = CVAL(inbuf,smb_com);
3308 int msg_type = CVAL(inbuf,0);
3309 extern int chain_size;
3311 smb_last_time = time(NULL);
3316 bzero(outbuf,smb_size);
3319 return(reply_special(inbuf,outbuf));
3321 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3322 set_message(outbuf,0,0,True);
3324 memcpy(outbuf+4,inbuf+4,4);
3325 CVAL(outbuf,smb_rcls) = SUCCESS;
3326 CVAL(outbuf,smb_reh) = 0;
3327 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3329 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3330 SSVAL(outbuf,smb_err,SUCCESS);
3331 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3332 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3333 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3334 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3336 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3338 outsize += chain_size;
3341 smb_setlen(outbuf,outsize - 4);
3346 /****************************************************************************
3347 process commands from the client
3348 ****************************************************************************/
3349 static void process(void)
3351 static int trans_num = 0;
3353 extern struct from_host Client_info;
3356 fromhost(Client,&Client_info);
3358 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3359 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3360 if ((InBuffer == NULL) || (OutBuffer == NULL))
3363 InBuffer += SMB_ALIGNMENT;
3364 OutBuffer += SMB_ALIGNMENT;
3367 DEBUG(3,("priming nmbd\n"));
3370 ip = *interpret_addr2("localhost");
3371 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3373 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3383 int deadtime = lp_deadtime()*60;
3385 int last_keepalive=0;
3388 deadtime = DEFAULT_SMBD_TIMEOUT;
3390 if (lp_readprediction())
3391 do_read_prediction();
3394 extern pstring share_del_pending;
3395 if (*share_del_pending) {
3397 if (!unlink(share_del_pending))
3398 DEBUG(3,("Share file deleted %s\n",share_del_pending));
3400 DEBUG(2,("Share del failed of %s\n",share_del_pending));
3401 share_del_pending[0] = 0;
3405 if (share_mode_pending) {
3407 check_share_modes();
3408 share_mode_pending=False;
3413 for (counter=SMBD_SELECT_LOOP;
3414 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3415 counter += SMBD_SELECT_LOOP)
3419 BOOL allidle = True;
3420 extern int keepalive;
3422 if (smb_read_error == READ_EOF) {
3423 DEBUG(3,("end of file from client\n"));
3427 if (smb_read_error == READ_ERROR) {
3428 DEBUG(3,("receive_smb error (%s) exiting\n",
3435 /* become root again if waiting */
3438 /* check for smb.conf reload */
3439 if (!(counter%SMBD_RELOAD_CHECK))
3440 reload_services(True);
3442 /* check the share modes every 10 secs */
3443 if (!(counter%SHARE_MODES_CHECK))
3444 check_share_modes();
3446 /* clean the share modes every 5 minutes */
3447 if (!(counter%SHARE_MODES_CLEAN))
3448 clean_share_modes();
3450 /* automatic timeout if all connections are closed */
3451 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3452 DEBUG(2,("%s Closing idle connection\n",timestring()));
3456 if (keepalive && (counter-last_keepalive)>keepalive) {
3457 extern int password_client;
3458 if (!send_keepalive(Client)) {
3459 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3462 /* also send a keepalive to the password server if its still
3464 if (password_client != -1)
3465 send_keepalive(password_client);
3466 last_keepalive = counter;
3469 /* check for connection timeouts */
3470 for (i=0;i<MAX_CONNECTIONS;i++)
3471 if (Connections[i].open)
3473 /* close dirptrs on connections that are idle */
3474 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3477 if (Connections[i].num_files_open > 0 ||
3478 (t-Connections[i].lastused)<deadtime)
3482 if (allidle && num_connections_open>0) {
3483 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3488 msg_type = CVAL(InBuffer,0);
3489 msg_flags = CVAL(InBuffer,1);
3490 type = CVAL(InBuffer,smb_com);
3492 len = smb_len(InBuffer);
3494 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3498 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3501 if(trans_num == 1 && VT_Check(InBuffer)) {
3511 nread = construct_reply(InBuffer,OutBuffer,nread,maxxmit);
3514 if (CVAL(OutBuffer,0) == 0)
3515 show_msg(OutBuffer);
3517 if (nread != smb_len(OutBuffer) + 4)
3519 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3521 smb_len(OutBuffer)));
3524 send_smb(Client,OutBuffer);
3531 /****************************************************************************
3532 initialise connect, service and file structs
3533 ****************************************************************************/
3534 static void init_structs(void )
3537 get_myname(myhostname,NULL);
3539 for (i=0;i<MAX_CONNECTIONS;i++)
3541 Connections[i].open = False;
3542 Connections[i].num_files_open=0;
3543 Connections[i].lastused=0;
3544 Connections[i].used=False;
3545 string_init(&Connections[i].user,"");
3546 string_init(&Connections[i].dirpath,"");
3547 string_init(&Connections[i].connectpath,"");
3548 string_init(&Connections[i].origpath,"");
3551 for (i=0;i<MAX_OPEN_FILES;i++)
3553 Files[i].open = False;
3554 string_init(&Files[i].name,"");
3560 /****************************************************************************
3561 usage on the program
3562 ****************************************************************************/
3563 static void usage(char *pname)
3565 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3567 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3568 printf("Version %s\n",VERSION);
3569 printf("\t-D become a daemon\n");
3570 printf("\t-p port listen on the specified port\n");
3571 printf("\t-d debuglevel set the debuglevel\n");
3572 printf("\t-l log basename. Basename for log/debug files\n");
3573 printf("\t-s services file. Filename of services file\n");
3574 printf("\t-P passive only\n");
3575 printf("\t-a overwrite log file, don't append\n");
3580 /****************************************************************************
3582 ****************************************************************************/
3583 int main(int argc,char *argv[])
3585 extern BOOL append_log;
3586 /* shall I run as a daemon */
3587 BOOL is_daemon = False;
3588 int port = SMB_PORT;
3590 extern char *optarg;
3592 #ifdef NEED_AUTH_PARAMETERS
3593 set_auth_parameters(argc,argv);
3604 strcpy(debugf,SMBLOGFILE);
3606 setup_logging(argv[0],False);
3608 charset_initialise();
3610 /* make absolutely sure we run as root - to handle cases whre people
3611 are crazy enough to have it setuid */
3621 fault_setup(exit_server);
3623 /* we want total control over the permissions on created files,
3624 so set our umask to 0 */
3629 /* this is for people who can't start the program correctly */
3630 while (argc > 1 && (*argv[1] != '-'))
3636 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPa")) != EOF)
3640 strcpy(user_socket_options,optarg);
3643 strcpy(scope,optarg);
3647 extern BOOL passive;
3652 strcpy(servicesf,optarg);
3655 strcpy(debugf,optarg);
3659 extern BOOL append_log;
3660 append_log = !append_log;
3670 DEBUGLEVEL = atoi(optarg);
3673 port = atoi(optarg);
3686 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
3687 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
3689 #ifndef NO_GETRLIMIT
3690 #ifdef RLIMIT_NOFILE
3693 getrlimit(RLIMIT_NOFILE, &rlp);
3694 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
3695 setrlimit(RLIMIT_NOFILE, &rlp);
3696 getrlimit(RLIMIT_NOFILE, &rlp);
3697 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
3703 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
3704 getuid(),getgid(),geteuid(),getegid()));
3706 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
3708 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
3714 if (!reload_services(False))
3717 #ifndef NO_SIGNAL_TEST
3718 signal(SIGHUP,SIGNAL_CAST sig_hup);
3721 DEBUG(3,("%s loaded services\n",timestring()));
3723 if (!is_daemon && !is_a_socket(0))
3725 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
3731 DEBUG(3,("%s becoming a daemon\n",timestring()));
3735 if (!open_sockets(is_daemon,port))
3738 #if FAST_SHARE_MODES
3739 if (!start_share_mode_mgmt())
3743 /* possibly reload the services file. */
3744 reload_services(True);
3746 maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
3750 if (sys_chroot(lp_rootdir()) == 0)
3751 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
3757 #if FAST_SHARE_MODES
3758 stop_share_mode_mgmt();
3761 exit_server("normal exit");