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.
28 pstring servicesf = CONFIGFILE;
29 extern pstring debugf;
30 extern pstring sesssetup_user;
32 char *InBuffer = NULL;
33 char *OutBuffer = NULL;
34 char *last_inbuf = NULL;
36 BOOL share_mode_pending = False;
38 /* the last message the was processed */
39 int last_message = -1;
41 /* a useful macro to debug the last message processed */
42 #define LAST_MESSAGE() smb_fn_name(last_message)
45 extern int DEBUGLEVEL;
46 extern int case_default;
47 extern BOOL case_sensitive;
48 extern BOOL case_preserve;
49 extern BOOL use_mangled_map;
50 extern BOOL short_case_preserve;
51 extern BOOL case_mangle;
52 extern time_t smb_last_time;
54 extern pstring user_socket_options;
56 connection_struct Connections[MAX_CONNECTIONS];
57 files_struct Files[MAX_OPEN_FILES];
61 int maxxmit = BUFFER_SIZE;
65 /* a fnum to use when chaining */
68 /* number of open connections */
69 static int num_connections_open = 0;
71 extern fstring remote_machine;
74 /* these can be set by some functions to override the error codes */
75 int unix_ERR_class=SUCCESS;
79 extern int extra_time_offset;
81 extern pstring myhostname;
82 extern struct in_addr myip;
85 static int find_free_connection(int hash);
88 extern void generate_next_challenge(char *challenge);
89 extern void set_challenge(char *challenge);
92 /* for readability... */
93 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
94 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
95 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
96 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
97 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
101 /****************************************************************************
102 change a dos mode to a unix mode
103 base permission for files:
104 everybody gets read bit set
105 dos readonly is represented in unix by removing everyone's write bit
106 dos archive is represented in unix by the user's execute bit
107 dos system is represented in unix by the group's execute bit
108 dos hidden is represented in unix by the other's execute bit
109 base permission for directories:
110 dos directory is represented in unix by unix's dir bit and the exec bit
111 ****************************************************************************/
112 mode_t unix_mode(int cnum,int dosmode)
114 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
116 if ( !IS_DOS_READONLY(dosmode) )
117 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
119 if (IS_DOS_DIR(dosmode))
120 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
122 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
125 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
128 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
131 result &= CREATE_MODE(cnum);
136 /****************************************************************************
137 change a unix mode to a dos mode
138 ****************************************************************************/
139 int dos_mode(int cnum,char *path,struct stat *sbuf)
144 if (!CAN_WRITE(cnum) || !((sbuf->st_mode & S_IWOTH) ||
145 Connections[cnum].admin_user ||
146 ((sbuf->st_mode & S_IWUSR) &&
147 Connections[cnum].uid==sbuf->st_uid) ||
148 ((sbuf->st_mode & S_IWGRP) &&
149 in_group(sbuf->st_gid,Connections[cnum].gid,
150 Connections[cnum].ngroups,
151 Connections[cnum].igroups))))
154 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
155 if (!((sbuf->st_mode & S_IWOTH) ||
156 Connections[cnum].admin_user ||
157 ((sbuf->st_mode & S_IWUSR) && Connections[cnum].uid==sbuf->st_uid) ||
158 ((sbuf->st_mode & S_IWGRP) &&
159 in_group(sbuf->st_gid,Connections[cnum].gid,
160 Connections[cnum].ngroups,Connections[cnum].igroups))))
163 if ((sbuf->st_mode & S_IWUSR) == 0)
168 if ((sbuf->st_mode & S_IXUSR) != 0)
171 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
174 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
177 if (S_ISDIR(sbuf->st_mode))
178 result = aDIR | (result & aRONLY);
181 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
185 /* hide files with a name starting with a . */
186 if (lp_hide_dot_files(SNUM(cnum)))
188 char *p = strrchr(path,'/');
194 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
202 /*******************************************************************
203 chmod a file - but preserve some bits
204 ********************************************************************/
205 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
214 if (sys_stat(fname,st)) return(-1);
217 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
219 if (dos_mode(cnum,fname,st) == dosmode) return(0);
221 unixmode = unix_mode(cnum,dosmode);
223 /* preserve the s bits */
224 mask |= (S_ISUID | S_ISGID);
226 /* preserve the t bit */
231 /* possibly preserve the x bits */
232 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
233 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
234 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
236 unixmode |= (st->st_mode & mask);
238 /* if we previously had any r bits set then leave them alone */
239 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
240 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
244 /* if we previously had any w bits set then leave them alone
245 if the new mode is not rdonly */
246 if (!IS_DOS_READONLY(dosmode) &&
247 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
248 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
252 return(chmod(fname,unixmode));
256 /****************************************************************************
257 check if two filenames are equal
259 this needs to be careful about whether we are case sensitive
260 ****************************************************************************/
261 static BOOL fname_equal(char *name1, char *name2)
263 int l1 = strlen(name1);
264 int l2 = strlen(name2);
266 /* handle filenames ending in a single dot */
267 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
271 ret = fname_equal(name1,name2);
276 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
280 ret = fname_equal(name1,name2);
285 /* now normal filename handling */
287 return(strcmp(name1,name2) == 0);
289 return(strequal(name1,name2));
293 /****************************************************************************
294 mangle the 2nd name and check if it is then equal to the first name
295 ****************************************************************************/
296 static BOOL mangled_equal(char *name1, char *name2)
303 strcpy(tmpname,name2);
304 mangle_name_83(tmpname);
306 return(strequal(name1,tmpname));
310 /****************************************************************************
311 scan a directory to find a filename, matching without case sensitivity
313 If the name looks like a mangled name then try via the mangling functions
314 ****************************************************************************/
315 static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
322 mangled = is_mangled(name);
324 /* handle null paths */
328 if (docache && (dname = DirCacheCheck(path,name,snum))) {
334 check_mangled_stack(name);
336 /* open the directory */
337 if (!(cur_dir = OpenDir(path)))
339 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
343 /* now scan for matching names */
344 while ((dname = ReadDirName(cur_dir)))
347 (strequal(dname,".") || strequal(dname,"..")))
351 if (!name_map_mangle(name2,False,snum)) continue;
353 if ((mangled && mangled_equal(name,name2))
354 || fname_equal(name, name2))
356 /* we've found the file, change it's name and return */
357 if (docache) DirCacheAdd(path,name,dname,snum);
368 /****************************************************************************
369 This routine is called to convert names from the dos namespace to unix
370 namespace. It needs to handle any case conversions, mangling, format
373 We assume that we have already done a chdir() to the right "root" directory
376 The function will return False if some part of the name except for the last
377 part cannot be resolved
378 ****************************************************************************/
379 BOOL unix_convert(char *name,int cnum)
387 /* convert to basic unix format - removing \ chars and cleaning it up */
389 unix_clean_name(name);
391 if (!case_sensitive &&
392 (!case_preserve || (is_8_3(name) && !short_case_preserve)))
395 /* names must be relative to the root of the service - trim any leading /.
396 also trim trailing /'s */
397 trim_string(name,"/","/");
399 /* check if it's a printer file */
400 if (Connections[cnum].printer)
402 if ((! *name) || strchr(name,'/') || !is_8_3(name))
406 sprintf(name2,"%.6s.XXXXXX",remote_machine);
407 /* sanitise the name */
408 for (s=name2 ; *s ; s++)
409 if (!issafe(*s)) *s = '_';
410 strcpy(name,(char *)mktemp(name2));
415 /* stat the name - if it exists then we are all done! */
416 if (sys_stat(name,&st) == 0)
419 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
421 /* a special case - if we don't have any mangling chars and are case
422 sensitive then searching won't help */
423 if (case_sensitive && !is_mangled(name) &&
424 !lp_strip_dot() && !use_mangled_map)
427 /* now we need to recursively match the name against the real
428 directory structure */
431 while (strncmp(start,"./",2) == 0)
434 /* now match each part of the path name separately, trying the names
435 as is first, then trying to scan the directory for matching names */
436 for (;start;start = (end?end+1:(char *)NULL))
438 /* pinpoint the end of this section of the filename */
439 end = strchr(start, '/');
441 /* chop the name at this point */
444 /* check if the name exists up to this point */
445 if (sys_stat(name, &st) == 0)
447 /* it exists. it must either be a directory or this must be
448 the last part of the path for it to be OK */
449 if (end && !(st.st_mode & S_IFDIR))
451 /* an intermediate part of the name isn't a directory */
452 DEBUG(5,("Not a dir %s\n",start));
463 /* remember the rest of the pathname so it can be restored
465 if (end) strcpy(rest,end+1);
468 /* try to find this part of the path in the directory */
469 if (strchr(start,'?') || strchr(start,'*') ||
470 !scan_directory(dirpath, start, SNUM(cnum), end?True:False))
474 /* an intermediate part of the name can't be found */
475 DEBUG(5,("Intermediate not found %s\n",start));
480 /* just the last part of the name doesn't exist */
481 /* we may need to strupper() or strlower() it in case
482 this conversion is being used for file creation
484 /* if the filename is of mixed case then don't normalise it */
485 if (!case_preserve &&
486 (!strhasupper(start) || !strhaslower(start)))
489 /* check on the mangled stack to see if we can recover the
490 base of the filename */
491 if (is_mangled(start))
492 check_mangled_stack(start);
494 DEBUG(5,("New file %s\n",start));
498 /* restore the rest of the string */
501 strcpy(start+strlen(start)+1,rest);
502 end = start + strlen(start);
506 /* add to the dirpath that we have resolved so far */
507 if (*dirpath) strcat(dirpath,"/");
508 strcat(dirpath,start);
510 /* restore the / that we wiped out earlier */
514 /* the name has been resolved */
515 DEBUG(5,("conversion finished %s\n",name));
520 /****************************************************************************
521 normalise for DOS usage
522 ****************************************************************************/
523 static void disk_norm(int *bsize,int *dfree,int *dsize)
525 /* check if the disk is beyond the max disk size */
526 int maxdisksize = lp_maxdisksize();
528 /* convert to blocks - and don't overflow */
529 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
530 if (*dsize > maxdisksize) *dsize = maxdisksize;
531 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
536 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
541 if (*bsize > WORDMAX )
544 if (*dsize > WORDMAX)
546 if (*dfree > WORDMAX)
553 /****************************************************************************
554 return number of 1K blocks available on a path and total number
555 ****************************************************************************/
556 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
558 char *df_command = lp_dfree_command();
572 if (disk_quotas(path, bsize, dfree, dsize))
574 disk_norm(bsize,dfree,dsize);
575 return(((*bsize)/1024)*(*dfree));
580 /* possibly use system() to get the result */
581 if (df_command && *df_command)
587 sprintf(outfile,"/tmp/dfree.smb.%d",(int)getpid());
588 sprintf(syscmd,"%s %s",df_command,path);
589 standard_sub_basic(syscmd);
591 ret = smbrun(syscmd,outfile);
592 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
595 FILE *f = fopen(outfile,"r");
601 fscanf(f,"%d %d %d",dsize,dfree,bsize);
605 DEBUG(0,("Can't open %s\n",outfile));
609 disk_norm(bsize,dfree,dsize);
610 return(((*bsize)/1024)*(*dfree));
614 DEBUG(1,("Warning - no statfs function\n"));
618 if (statfs(path,&fs,sizeof(fs),0) != 0)
621 if (statvfs(path, &fs))
624 if (statfs(path,&fs,sizeof(fs)) == -1)
626 if (statfs(path,&fs) == -1)
628 #endif /* USE_STATVFS */
631 DEBUG(3,("dfree call failed code errno=%d\n",errno));
635 return(((*bsize)/1024)*(*dfree));
640 *dfree = fs.fd_req.bfree;
641 *dsize = fs.fd_req.btot;
644 *bsize = fs.f_frsize;
647 /* eg: osf1 has f_fsize = fundamental filesystem block size,
648 f_bsize = optimal transfer block size (MX: 94-04-19) */
653 #endif /* USE_STATVFS */
658 *dfree = fs.f_bavail;
660 *dsize = fs.f_blocks;
663 #if defined(SCO) || defined(ISC) || defined(MIPS)
667 /* handle rediculous bsize values - some OSes are broken */
668 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
670 disk_norm(bsize,dfree,dsize);
676 DEBUG(0,("dfree seems to be broken on your system\n"));
677 *dsize = 20*1024*1024/(*bsize);
678 *dfree = MAX(1,*dfree);
680 return(((*bsize)/1024)*(*dfree));
685 /****************************************************************************
686 wrap it to get filenames right
687 ****************************************************************************/
688 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
690 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
695 /****************************************************************************
696 check a filename - possibly caling reducename
698 This is called by every routine before it allows an operation on a filename.
699 It does any final confirmation necessary to ensure that the filename is
700 a valid one for the user to access.
701 ****************************************************************************/
702 BOOL check_name(char *name,int cnum)
708 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
710 DEBUG(5,("check_name on %s failed\n",name));
715 /****************************************************************************
716 check a filename - possibly caling reducename
717 ****************************************************************************/
718 static void check_for_pipe(char *fname)
720 /* special case of pipe opens */
724 if (strstr(s,"pipe/"))
726 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
727 unix_ERR_class = ERRSRV;
728 unix_ERR_code = ERRaccess;
733 /****************************************************************************
735 ****************************************************************************/
736 void open_file(int fnum,int cnum,char *fname1,int flags,int mode)
740 Files[fnum].open = False;
744 strcpy(fname,fname1);
746 /* check permissions */
747 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
749 DEBUG(3,("Permission denied opening %s\n",fname));
750 check_for_pipe(fname);
754 /* this handles a bug in Win95 - it doesn't say to create the file when it
756 if (Connections[cnum].printer)
760 if (flags == O_WRONLY)
761 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
765 /* XXXX - is this OK?? */
766 /* this works around a utime bug but can cause other problems */
767 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
772 Files[fnum].fd = sys_open(fname,flags,mode);
774 if ((Files[fnum].fd>=0) &&
775 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
780 p = strrchr(dname,'/');
782 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
783 lp_minprintspace(SNUM(cnum))) {
784 close(Files[fnum].fd);
793 /* Fix for files ending in '.' */
794 if((Files[fnum].fd == -1) && (errno == ENOENT) &&
795 (strchr(fname,'.')==NULL))
798 Files[fnum].fd = sys_open(fname,flags,mode);
801 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
802 if ((Files[fnum].fd == -1) && (errno == ENAMETOOLONG))
805 char *p = strrchr(fname, '/');
807 if (p == fname) /* name is "/xxx" */
809 max_len = pathconf("/", _PC_NAME_MAX);
812 else if ((p == NULL) || (p == fname))
815 max_len = pathconf(".", _PC_NAME_MAX);
820 max_len = pathconf(fname, _PC_NAME_MAX);
824 if (strlen(p) > max_len)
826 char tmp = p[max_len];
829 if ((Files[fnum].fd = sys_open(fname,flags,mode)) == -1)
835 if (Files[fnum].fd < 0)
837 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
838 fname,strerror(errno),flags));
839 check_for_pipe(fname);
843 if (Files[fnum].fd >= 0)
846 Connections[cnum].num_files_open++;
847 fstat(Files[fnum].fd,&st);
848 Files[fnum].mode = st.st_mode;
849 Files[fnum].open_time = time(NULL);
850 Files[fnum].size = 0;
851 Files[fnum].pos = -1;
852 Files[fnum].open = True;
853 Files[fnum].mmap_ptr = NULL;
854 Files[fnum].mmap_size = 0;
855 Files[fnum].can_lock = True;
856 Files[fnum].can_read = ((flags & O_WRONLY)==0);
857 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
858 Files[fnum].share_mode = 0;
859 Files[fnum].share_pending = False;
860 Files[fnum].print_file = Connections[cnum].printer;
861 Files[fnum].modified = False;
862 Files[fnum].cnum = cnum;
863 string_set(&Files[fnum].name,fname);
864 Files[fnum].wbmpx_ptr = NULL;
867 * If the printer is marked as postscript output a leading
868 * file identifier to ensure the file is treated as a raw
870 * This has a similar effect as CtrlD=0 in WIN.INI file.
871 * tim@fsg.com 09/06/94
873 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
874 Files[fnum].can_write)
876 DEBUG(3,("Writing postscript line\n"));
877 write_file(fnum,"%!\n",3);
880 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
881 timestring(),Connections[cnum].user,fname,
882 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
883 Connections[cnum].num_files_open,fnum));
888 /* mmap it if read-only */
889 if (!Files[fnum].can_write)
891 Files[fnum].mmap_size = file_size(fname);
892 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
893 PROT_READ,MAP_SHARED,Files[fnum].fd,0);
895 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
897 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
898 Files[fnum].mmap_ptr = NULL;
904 /*******************************************************************
906 ********************************************************************/
907 void sync_file(int fnum)
910 fsync(Files[fnum].fd);
914 /****************************************************************************
915 run a file if it is a magic script
916 ****************************************************************************/
917 static void check_magic(int fnum,int cnum)
919 if (!*lp_magicscript(SNUM(cnum)))
922 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
926 if (!(p = strrchr(Files[fnum].name,'/')))
927 p = Files[fnum].name;
931 if (!strequal(lp_magicscript(SNUM(cnum)),p))
937 pstring magic_output;
939 strcpy(fname,Files[fnum].name);
941 if (*lp_magicoutput(SNUM(cnum)))
942 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
944 sprintf(magic_output,"%s.out",fname);
947 ret = smbrun(fname,magic_output);
948 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
954 /****************************************************************************
955 close a file - possibly invalidating the read prediction
956 ****************************************************************************/
957 void close_file(int fnum)
959 int cnum = Files[fnum].cnum;
960 invalidate_read_prediction(Files[fnum].fd);
961 Files[fnum].open = False;
962 Connections[cnum].num_files_open--;
963 if(Files[fnum].wbmpx_ptr)
965 free((char *)Files[fnum].wbmpx_ptr);
966 Files[fnum].wbmpx_ptr = NULL;
970 if(Files[fnum].mmap_ptr)
972 munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size);
973 Files[fnum].mmap_ptr = NULL;
977 if (lp_share_modes(SNUM(cnum)))
978 del_share_mode(fnum);
980 close(Files[fnum].fd);
982 /* NT uses smbclose to start a print - weird */
983 if (Files[fnum].print_file)
986 /* check for magic scripts */
987 check_magic(fnum,cnum);
989 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
990 timestring(),Connections[cnum].user,Files[fnum].name,
991 Connections[cnum].num_files_open));
994 enum {AFAIL,AREAD,AWRITE,AALL};
996 /*******************************************************************
997 reproduce the share mode access table
998 ********************************************************************/
999 static int access_table(int new_deny,int old_deny,int old_mode,
1000 int share_pid,char *fname)
1002 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1004 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1005 if (old_deny == new_deny && share_pid == getpid())
1008 if (old_mode == 0) return(AREAD);
1010 /* the new smbpub.zip spec says that if the file extension is
1011 .com, .dll, .exe or .sym then allow the open. I will force
1012 it to read-only as this seems sensible although the spec is
1013 a little unclear on this. */
1014 if ((fname = strrchr(fname,'.'))) {
1015 if (strequal(fname,".com") ||
1016 strequal(fname,".dll") ||
1017 strequal(fname,".exe") ||
1018 strequal(fname,".sym"))
1028 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1029 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1030 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1033 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1034 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1035 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1038 if (old_deny==DENY_WRITE) return(AREAD);
1039 if (old_deny==DENY_READ) return(AWRITE);
1040 if (old_deny==DENY_NONE) return(AALL);
1046 /*******************************************************************
1047 check if the share mode on a file allows it to be deleted or unlinked
1048 return True if sharing doesn't prevent the operation
1049 ********************************************************************/
1050 BOOL check_file_sharing(int cnum,char *fname)
1053 int share_mode = get_share_mode_byname(cnum,fname,&pid);
1055 if (!pid || !share_mode) return(True);
1057 if (share_mode == DENY_DOS)
1058 return(pid == getpid());
1060 /* XXXX exactly what share mode combinations should be allowed for
1061 deleting/renaming? */
1065 /****************************************************************************
1067 Helper for open_file_shared.
1068 Truncate a file after checking locking; close file if locked.
1069 **************************************************************************/
1070 static void truncate_unless_locked(int fnum, int cnum)
1072 if (Files[fnum].can_write){
1073 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1076 unix_ERR_class = ERRDOS;
1077 unix_ERR_code = ERRlock;
1080 ftruncate(Files[fnum].fd,0);
1085 /****************************************************************************
1086 open a file with a share mode
1087 ****************************************************************************/
1088 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1089 int mode,int *Access,int *action)
1093 int deny_mode = (share_mode>>4)&7;
1095 BOOL file_existed = file_exist(fname,&sbuf);
1096 BOOL fcbopen = False;
1099 Files[fnum].open = False;
1100 Files[fnum].fd = -1;
1102 /* this is for OS/2 EAs - try and say we don't support them */
1103 if (strstr(fname,".+,;=[].")) {
1104 unix_ERR_class = ERRDOS;
1105 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1109 if ((ofun & 0x3) == 0 && file_existed) {
1116 if ((ofun & 0x3) == 2)
1119 /* note that we ignore the append flag as
1120 append does not mean the same thing under dos and unix */
1122 switch (share_mode&0xF)
1139 if (flags != O_RDONLY && file_existed &&
1140 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) {
1148 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
1149 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1154 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1156 if (lp_share_modes(SNUM(cnum))) {
1160 old_share = get_share_mode(cnum,&sbuf,&share_pid);
1163 /* someone else has a share lock on it, check to see
1165 int old_open_mode = old_share&0xF;
1166 int old_deny_mode = (old_share>>4)&7;
1168 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) {
1169 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1170 deny_mode,old_deny_mode,old_open_mode,fname));
1172 unix_ERR_class = ERRDOS;
1173 unix_ERR_code = ERRbadshare;
1178 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1181 if ((access_allowed == AFAIL) ||
1182 (access_allowed == AREAD && flags == O_WRONLY) ||
1183 (access_allowed == AWRITE && flags == O_RDONLY)) {
1184 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1185 deny_mode,old_deny_mode,old_open_mode,
1189 unix_ERR_class = ERRDOS;
1190 unix_ERR_code = ERRbadshare;
1194 if (access_allowed == AREAD)
1197 if (access_allowed == AWRITE)
1203 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1204 flags,flags2,mode));
1206 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode);
1207 if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) {
1209 open_file(fnum,cnum,fname,flags,mode);
1212 if (Files[fnum].open) {
1226 Files[fnum].share_mode = (deny_mode<<4) | open_mode;
1227 Files[fnum].share_pending = True;
1230 (*Access) = open_mode;
1234 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1235 if (!file_existed) *action = 2;
1236 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1240 share_mode_pending = True;
1242 if ((flags2&O_TRUNC) && file_existed)
1243 truncate_unless_locked(fnum,cnum);
1249 /*******************************************************************
1250 check for files that we should now set our share modes on
1251 ********************************************************************/
1252 static void check_share_modes(void)
1255 for (i=0;i<MAX_OPEN_FILES;i++)
1256 if(Files[i].open && Files[i].share_pending) {
1257 if (lp_share_modes(SNUM(Files[i].cnum))) {
1259 get_share_mode_by_fnum(Files[i].cnum,i,&pid);
1261 set_share_mode(i,Files[i].share_mode);
1262 Files[i].share_pending = False;
1265 Files[i].share_pending = False;
1271 /****************************************************************************
1272 seek a file. Try to avoid the seek if possible
1273 ****************************************************************************/
1274 int seek_file(int fnum,int pos)
1277 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1280 Files[fnum].pos = lseek(Files[fnum].fd,pos+offset,SEEK_SET) - offset;
1281 return(Files[fnum].pos);
1284 /****************************************************************************
1286 ****************************************************************************/
1287 int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact)
1291 if (!Files[fnum].can_write)
1293 ret = read_predict(Files[fnum].fd,
1301 mincnt = MAX(mincnt-ret,0);
1306 if (Files[fnum].mmap_ptr)
1308 int num = MIN(maxcnt,Files[fnum].mmap_size-pos);
1311 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1315 mincnt = MAX(mincnt-num,0);
1324 if (seek_file(fnum,pos) != pos)
1326 DEBUG(3,("Failed to seek to %d\n",pos));
1331 ret += read_with_timeout(Files[fnum].fd,
1342 /****************************************************************************
1344 ****************************************************************************/
1345 int write_file(int fnum,char *data,int n)
1347 if (!Files[fnum].can_write) {
1352 if (!Files[fnum].modified) {
1354 Files[fnum].modified = True;
1355 if (fstat(Files[fnum].fd,&st) == 0) {
1356 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1357 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1358 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1363 return(write_data(Files[fnum].fd,data,n));
1367 /****************************************************************************
1368 load parameters specific to a connection/service
1369 ****************************************************************************/
1370 BOOL become_service(int cnum,BOOL do_chdir)
1372 extern char magic_char;
1373 static int last_cnum = -1;
1376 if (!OPEN_CNUM(cnum))
1382 Connections[cnum].lastused = smb_last_time;
1387 ChDir(Connections[cnum].connectpath) != 0 &&
1388 ChDir(Connections[cnum].origpath) != 0)
1390 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1391 Connections[cnum].connectpath,cnum));
1395 if (cnum == last_cnum)
1400 case_default = lp_defaultcase(snum);
1401 case_preserve = lp_preservecase(snum);
1402 short_case_preserve = lp_shortpreservecase(snum);
1403 case_mangle = lp_casemangle(snum);
1404 case_sensitive = lp_casesensitive(snum);
1405 magic_char = lp_magicchar(snum);
1406 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1411 /****************************************************************************
1412 find a service entry
1413 ****************************************************************************/
1414 int find_service(char *service)
1418 string_sub(service,"\\","/");
1420 iService = lp_servicenumber(service);
1422 /* now handle the special case of a home directory */
1425 char *phome_dir = get_home_dir(service);
1426 DEBUG(3,("checking for home directory %s gave %s\n",service,
1427 phome_dir?phome_dir:"(NULL)"));
1431 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1433 lp_add_home(service,iHomeService,phome_dir);
1434 iService = lp_servicenumber(service);
1439 /* If we still don't have a service, attempt to add it as a printer. */
1442 int iPrinterService;
1444 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1448 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1450 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1452 DEBUG(3,("%s is a valid printer name\n", service));
1453 DEBUG(3,("adding %s as a printer service\n", service));
1454 lp_add_printer(service,iPrinterService);
1455 iService = lp_servicenumber(service);
1457 DEBUG(0,("failed to add %s as a printer service!\n", service));
1460 DEBUG(3,("%s is not a valid printer name\n", service));
1464 /* just possibly it's a default service? */
1467 char *defservice = lp_defaultservice();
1468 if (defservice && *defservice && !strequal(defservice,service)) {
1469 iService = find_service(defservice);
1470 if (iService >= 0) {
1471 string_sub(service,"_","/");
1472 iService = lp_add_service(service,iService);
1478 if (!VALID_SNUM(iService))
1480 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1485 DEBUG(3,("find_service() failed to find service %s\n", service));
1491 /****************************************************************************
1492 create an error packet from a cached error.
1493 ****************************************************************************/
1494 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1496 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1498 int32 eclass = wbmpx->wr_errclass;
1499 int32 err = wbmpx->wr_error;
1501 /* We can now delete the auxiliary struct */
1502 free((char *)wbmpx);
1503 Files[fnum].wbmpx_ptr = NULL;
1504 return error_packet(inbuf,outbuf,eclass,err,line);
1513 } unix_smb_errmap[] =
1515 {EPERM,ERRDOS,ERRnoaccess},
1516 {EACCES,ERRDOS,ERRnoaccess},
1517 {ENOENT,ERRDOS,ERRbadfile},
1518 {EIO,ERRHRD,ERRgeneral},
1519 {EBADF,ERRSRV,ERRsrverror},
1520 {EINVAL,ERRSRV,ERRsrverror},
1521 {EEXIST,ERRDOS,ERRfilexists},
1522 {ENFILE,ERRDOS,ERRnofids},
1523 {EMFILE,ERRDOS,ERRnofids},
1524 {ENOSPC,ERRHRD,ERRdiskfull},
1526 {EDQUOT,ERRHRD,ERRdiskfull},
1529 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1532 {EXDEV,ERRDOS,ERRdiffdevice},
1534 {EROFS,ERRHRD,ERRnowrite},
1539 /****************************************************************************
1540 create an error packet from errno
1541 ****************************************************************************/
1542 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1544 int eclass=def_class;
1548 if (unix_ERR_class != SUCCESS)
1550 eclass = unix_ERR_class;
1551 ecode = unix_ERR_code;
1552 unix_ERR_class = SUCCESS;
1557 while (unix_smb_errmap[i].smbclass != 0)
1559 if (unix_smb_errmap[i].unixerror == errno)
1561 eclass = unix_smb_errmap[i].smbclass;
1562 ecode = unix_smb_errmap[i].smbcode;
1569 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1573 /****************************************************************************
1574 create an error packet. Normally called using the ERROR() macro
1575 ****************************************************************************/
1576 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1578 int outsize = set_message(outbuf,0,0,True);
1580 cmd = CVAL(inbuf,smb_com);
1582 CVAL(outbuf,smb_rcls) = error_class;
1583 SSVAL(outbuf,smb_err,error_code);
1585 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1588 (int)CVAL(inbuf,smb_com),
1589 smb_fn_name(CVAL(inbuf,smb_com)),
1594 DEBUG(3,("error string = %s\n",strerror(errno)));
1600 #ifndef SIGCLD_IGNORE
1601 /****************************************************************************
1602 this prevents zombie child processes
1603 ****************************************************************************/
1604 static int sig_cld()
1606 static int depth = 0;
1609 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1616 DEBUG(5,("got SIGCLD\n"));
1619 while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1623 /* Stevens, Adv. Unix Prog. says that on system V you must call
1624 wait before reinstalling the signal handler, because the kernel
1625 calls the handler from within the signal-call when there is a
1626 child that has exited. This would lead to an infinite recursion
1627 if done vice versa. */
1629 #ifndef DONT_REINSTALL_SIG
1630 #ifdef SIGCLD_IGNORE
1631 signal(SIGCLD, SIG_IGN);
1633 signal(SIGCLD, SIGNAL_CAST sig_cld);
1638 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1641 BlockSignals(False);
1646 /****************************************************************************
1647 this is called when the client exits abruptly
1648 **************************************************************************/
1649 static int sig_pipe()
1651 exit_server("Got sigpipe\n");
1655 /****************************************************************************
1656 open the socket communication
1657 ****************************************************************************/
1658 static BOOL open_sockets(BOOL is_daemon,int port)
1665 struct sockaddr addr;
1666 int in_addrlen = sizeof(addr);
1669 #ifdef SIGCLD_IGNORE
1670 signal(SIGCLD, SIG_IGN);
1672 signal(SIGCLD, SIGNAL_CAST sig_cld);
1675 /* open an incoming socket */
1676 s = open_socket_in(SOCK_STREAM, port, 0);
1680 /* ready to listen */
1681 if (listen(s, 5) == -1)
1683 DEBUG(0,("listen: %s",strerror(errno)));
1688 /* now accept incoming connections - forking a new process
1689 for each incoming connection */
1690 DEBUG(2,("waiting for a connection\n"));
1693 Client = accept(s,&addr,&in_addrlen);
1695 if (Client == -1 && errno == EINTR)
1700 DEBUG(0,("accept: %s",strerror(errno)));
1704 #ifdef NO_FORK_DEBUG
1705 #ifndef NO_SIGNAL_TEST
1706 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1707 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1711 if (Client != -1 && fork()==0)
1713 #ifndef NO_SIGNAL_TEST
1714 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1715 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1717 /* close the listening socket */
1720 /* close our standard file descriptors */
1723 set_socket_options(Client,"SO_KEEPALIVE");
1724 set_socket_options(Client,user_socket_options);
1728 close(Client); /* The parent doesn't need this socket */
1734 /* We will abort gracefully when the client or remote system
1736 #ifndef NO_SIGNAL_TEST
1737 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1741 /* close our standard file descriptors */
1744 set_socket_options(Client,"SO_KEEPALIVE");
1745 set_socket_options(Client,user_socket_options);
1752 /****************************************************************************
1753 check if a snum is in use
1754 ****************************************************************************/
1755 BOOL snum_used(int snum)
1758 for (i=0;i<MAX_CONNECTIONS;i++)
1759 if (OPEN_CNUM(i) && (SNUM(i) == snum))
1764 /****************************************************************************
1765 reload the services file
1766 **************************************************************************/
1767 BOOL reload_services(BOOL test)
1774 strcpy(fname,lp_configfile());
1775 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
1777 strcpy(servicesf,fname);
1784 if (test && !lp_file_list_changed())
1787 lp_killunused(snum_used);
1789 ret = lp_load(servicesf,False);
1791 /* perhaps the config filename is now set */
1793 reload_services(True);
1800 set_socket_options(Client,"SO_KEEPALIVE");
1801 set_socket_options(Client,user_socket_options);
1805 create_mangled_stack(lp_mangledstack());
1807 /* this forces service parameters to be flushed */
1808 become_service(-1,True);
1815 /****************************************************************************
1816 this prevents zombie child processes
1817 ****************************************************************************/
1818 static int sig_hup()
1821 DEBUG(0,("Got SIGHUP\n"));
1822 reload_services(False);
1823 #ifndef DONT_REINSTALL_SIG
1824 signal(SIGHUP,SIGNAL_CAST sig_hup);
1826 BlockSignals(False);
1830 /****************************************************************************
1831 Setup the groups a user belongs to.
1832 ****************************************************************************/
1833 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
1834 int **p_igroups, gid_t **p_groups)
1836 if (-1 == initgroups(user,gid))
1840 DEBUG(0,("Unable to initgroups!\n"));
1841 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
1842 DEBUG(0,("This is probably a problem with the account %s\n",user));
1850 ngroups = getgroups(0,&grp);
1853 igroups = (int *)malloc(sizeof(int)*ngroups);
1854 for (i=0;i<ngroups;i++)
1855 igroups[i] = 0x42424242;
1856 ngroups = getgroups(ngroups,(gid_t *)igroups);
1858 if (igroups[0] == 0x42424242)
1861 *p_ngroups = ngroups;
1863 /* The following bit of code is very strange. It is due to the
1864 fact that some OSes use int* and some use gid_t* for
1865 getgroups, and some (like SunOS) use both, one in prototypes,
1866 and one in man pages and the actual code. Thus we detect it
1867 dynamically using some very ugly code */
1870 /* does getgroups return ints or gid_t ?? */
1871 static BOOL groups_use_ints = True;
1873 if (groups_use_ints &&
1875 SVAL(igroups,2) == 0x4242)
1876 groups_use_ints = False;
1878 for (i=0;groups_use_ints && i<ngroups;i++)
1879 if (igroups[i] == 0x42424242)
1880 groups_use_ints = False;
1882 if (groups_use_ints)
1884 *p_igroups = igroups;
1885 *p_groups = (gid_t *)igroups;
1889 gid_t *groups = (gid_t *)igroups;
1890 igroups = (int *)malloc(sizeof(int)*ngroups);
1891 for (i=0;i<ngroups;i++)
1892 igroups[i] = groups[i];
1893 *p_igroups = igroups;
1894 *p_groups = (gid_t *)groups;
1897 DEBUG(3,("%s is in %d groups\n",user,ngroups));
1898 for (i=0;i<ngroups;i++)
1899 DEBUG(3,("%d ",igroups[i]));
1905 /****************************************************************************
1906 make a connection to a service
1907 ****************************************************************************/
1908 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid)
1912 struct passwd *pass = NULL;
1913 connection_struct *pcon;
1916 static BOOL first_connection = True;
1920 snum = find_service(service);
1923 if (strequal(service,"IPC$"))
1925 DEBUG(3,("%s refusing IPC connection\n",timestring()));
1929 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
1933 if (strequal(service,HOMES_NAME))
1935 if (*user && Get_Pwnam(user,True))
1936 return(make_connection(user,user,password,pwlen,dev,vuid));
1938 if (validated_username(vuid))
1940 strcpy(user,validated_username(vuid));
1941 return(make_connection(user,user,password,pwlen,dev,vuid));
1945 if (!lp_snum_ok(snum) || !check_access(snum)) {
1949 /* you can only connect to the IPC$ service as an ipc device */
1950 if (strequal(service,"IPC$"))
1953 if (*dev == '?' || !*dev)
1955 if (lp_print_ok(snum))
1956 strcpy(dev,"LPT1:");
1961 /* if the request is as a printer and you can't print then refuse */
1963 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
1964 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
1968 /* lowercase the user name */
1971 /* add it as a possible user name */
1972 add_session_user(service);
1974 /* shall we let them in? */
1975 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
1977 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
1981 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
1984 DEBUG(0,("%s couldn't find free connection\n",timestring()));
1988 pcon = &Connections[cnum];
1989 bzero((char *)pcon,sizeof(*pcon));
1991 /* find out some info about the user */
1992 pass = Get_Pwnam(user,True);
1996 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2000 pcon->read_only = lp_readonly(snum);
2004 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2005 string_sub(list,"%S",service);
2007 if (user_in_list(user,list))
2008 pcon->read_only = True;
2010 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2011 string_sub(list,"%S",service);
2013 if (user_in_list(user,list))
2014 pcon->read_only = False;
2017 /* admin user check */
2018 if (user_in_list(user,lp_admin_users(snum)) &&
2021 pcon->admin_user = True;
2022 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2025 pcon->admin_user = False;
2027 pcon->force_user = force;
2028 pcon->uid = pass->pw_uid;
2029 pcon->gid = pass->pw_gid;
2030 pcon->num_files_open = 0;
2031 pcon->lastused = time(NULL);
2032 pcon->service = snum;
2034 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2035 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2036 pcon->dirptr = NULL;
2037 string_set(&pcon->dirpath,"");
2038 string_set(&pcon->user,user);
2041 if (*lp_force_group(snum))
2043 struct group *gptr = (struct group *)getgrnam(lp_force_group(snum));
2046 pcon->gid = gptr->gr_gid;
2047 DEBUG(3,("Forced group %s\n",lp_force_group(snum)));
2050 DEBUG(1,("Couldn't find group %s\n",lp_force_group(snum)));
2054 if (*lp_force_user(snum))
2056 struct passwd *pass2;
2058 strcpy(fuser,lp_force_user(snum));
2059 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2062 pcon->uid = pass2->pw_uid;
2063 string_set(&pcon->user,fuser);
2065 pcon->force_user = True;
2066 DEBUG(3,("Forced user %s\n",fuser));
2069 DEBUG(1,("Couldn't find user %s\n",fuser));
2074 strcpy(s,lp_pathname(snum));
2075 standard_sub(cnum,s);
2076 string_set(&pcon->connectpath,s);
2077 DEBUG(3,("Connect path is %s\n",s));
2080 /* groups stuff added by ih */
2082 pcon->groups = NULL;
2086 /* Find all the groups this uid is in and store them. Used by become_user() */
2087 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2089 /* check number of connections */
2090 if (!claim_connection(cnum,
2091 lp_servicename(SNUM(cnum)),
2092 lp_max_connections(SNUM(cnum)),False))
2094 DEBUG(1,("too many connections - rejected\n"));
2098 if (lp_status(SNUM(cnum)))
2099 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2101 first_connection = False;
2106 /* execute any "root preexec = " line */
2107 if (*lp_rootpreexec(SNUM(cnum)))
2110 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2111 standard_sub(cnum,cmd);
2112 DEBUG(5,("cmd=%s\n",cmd));
2116 if (!become_user(cnum,pcon->uid))
2118 DEBUG(0,("Can't become connected user!\n"));
2120 if (!IS_IPC(cnum)) {
2121 yield_connection(cnum,
2122 lp_servicename(SNUM(cnum)),
2123 lp_max_connections(SNUM(cnum)));
2124 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2129 if (ChDir(pcon->connectpath) != 0)
2131 DEBUG(0,("Can't change directory to %s (%s)\n",
2132 pcon->connectpath,strerror(errno)));
2135 if (!IS_IPC(cnum)) {
2136 yield_connection(cnum,
2137 lp_servicename(SNUM(cnum)),
2138 lp_max_connections(SNUM(cnum)));
2139 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2144 string_set(&pcon->origpath,pcon->connectpath);
2146 #if SOFTLINK_OPTIMISATION
2147 /* resolve any soft links early */
2150 strcpy(s,pcon->connectpath);
2152 string_set(&pcon->connectpath,s);
2153 ChDir(pcon->connectpath);
2157 num_connections_open++;
2158 add_session_user(user);
2160 /* execute any "preexec = " line */
2161 if (*lp_preexec(SNUM(cnum)))
2164 strcpy(cmd,lp_preexec(SNUM(cnum)));
2165 standard_sub(cnum,cmd);
2169 /* we've finished with the sensitive stuff */
2173 extern struct from_host Client_info;
2174 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2176 Client_info.name,Client_info.addr,
2177 lp_servicename(SNUM(cnum)),user,
2187 /****************************************************************************
2188 find first available file slot
2189 ****************************************************************************/
2190 int find_free_file(void )
2193 /* we start at 1 here for an obscure reason I can't now remember,
2194 but I think is important :-) */
2195 for (i=1;i<MAX_OPEN_FILES;i++)
2198 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2202 /****************************************************************************
2203 find first available connection slot, starting from a random position.
2204 The randomisation stops problems with the server dieing and clients
2205 thinking the server is still available.
2206 ****************************************************************************/
2207 static int find_free_connection(int hash )
2211 hash = (hash % (MAX_CONNECTIONS-2))+1;
2215 for (i=hash+1;i!=hash;)
2217 if (!Connections[i].open && Connections[i].used == used)
2219 DEBUG(3,("found free connection number %d\n",i));
2223 if (i == MAX_CONNECTIONS)
2233 DEBUG(1,("ERROR! Out of connection structures\n"));
2238 /****************************************************************************
2239 reply for the core protocol
2240 ****************************************************************************/
2241 int reply_corep(char *outbuf)
2243 int outsize = set_message(outbuf,1,0,True);
2245 Protocol = PROTOCOL_CORE;
2251 /****************************************************************************
2252 reply for the coreplus protocol
2253 ****************************************************************************/
2254 int reply_coreplus(char *outbuf)
2256 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2257 int outsize = set_message(outbuf,13,0,True);
2258 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2259 readbraw and writebraw (possibly) */
2260 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2261 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2263 Protocol = PROTOCOL_COREPLUS;
2269 /****************************************************************************
2270 reply for the lanman 1.0 protocol
2271 ****************************************************************************/
2272 int reply_lanman1(char *outbuf)
2274 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2276 BOOL doencrypt = SMBENCRYPT();
2277 time_t t = time(NULL);
2279 if (lp_security()>=SEC_USER) secword |= 1;
2280 if (doencrypt) secword |= 2;
2282 set_message(outbuf,13,doencrypt?8:0,True);
2283 SSVAL(outbuf,smb_vwv1,secword);
2285 /* Create a token value and add it to the outgoing packet. */
2287 generate_next_challenge(smb_buf(outbuf));
2290 Protocol = PROTOCOL_LANMAN1;
2292 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2293 DEBUG(3,("using password server validation\n"));
2295 if (doencrypt) set_challenge(smb_buf(outbuf));
2299 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2300 SSVAL(outbuf,smb_vwv2,maxxmit);
2301 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2302 SSVAL(outbuf,smb_vwv4,1);
2303 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2304 readbraw writebraw (possibly) */
2305 SIVAL(outbuf,smb_vwv6,getpid());
2306 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2308 put_dos_date(outbuf,smb_vwv8,t);
2310 return (smb_len(outbuf)+4);
2314 /****************************************************************************
2315 reply for the lanman 2.0 protocol
2316 ****************************************************************************/
2317 int reply_lanman2(char *outbuf)
2319 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2321 BOOL doencrypt = SMBENCRYPT();
2322 time_t t = time(NULL);
2324 if (lp_security()>=SEC_USER) secword |= 1;
2325 if (doencrypt) secword |= 2;
2327 set_message(outbuf,13,doencrypt?8:0,True);
2328 SSVAL(outbuf,smb_vwv1,secword);
2330 /* Create a token value and add it to the outgoing packet. */
2332 generate_next_challenge(smb_buf(outbuf));
2335 SIVAL(outbuf,smb_vwv6,getpid());
2337 Protocol = PROTOCOL_LANMAN2;
2339 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2340 DEBUG(3,("using password server validation\n"));
2342 if (doencrypt) set_challenge(smb_buf(outbuf));
2346 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2347 SSVAL(outbuf,smb_vwv2,maxxmit);
2348 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2349 SSVAL(outbuf,smb_vwv4,1);
2350 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2351 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2352 put_dos_date(outbuf,smb_vwv8,t);
2354 return (smb_len(outbuf)+4);
2357 /****************************************************************************
2358 reply for the nt protocol
2359 ****************************************************************************/
2360 int reply_nt1(char *outbuf)
2362 int capabilities=0x300; /* has dual names + lock_and_read */
2364 BOOL doencrypt = SMBENCRYPT();
2365 time_t t = time(NULL);
2367 if (lp_security()>=SEC_USER) secword |= 1;
2368 if (doencrypt) secword |= 2;
2370 set_message(outbuf,17,doencrypt?8:0,True);
2371 CVAL(outbuf,smb_vwv1) = secword;
2373 /* Create a token value and add it to the outgoing packet. */
2375 generate_next_challenge(smb_buf(outbuf));
2376 /* Tell the nt machine how long the challenge is. */
2377 SSVALS(outbuf,smb_vwv16+1,8);
2381 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2383 Protocol = PROTOCOL_NT1;
2385 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2386 DEBUG(3,("using password server validation\n"));
2388 if (doencrypt) set_challenge(smb_buf(outbuf));
2392 if (lp_readraw() && lp_writeraw())
2395 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2396 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2397 SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
2398 SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
2399 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2400 put_long_date(outbuf+smb_vwv11+1,t);
2401 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2403 return (smb_len(outbuf)+4);
2407 /* these are the protocol lists used for auto architecture detection:
2410 protocol [PC NETWORK PROGRAM 1.0]
2411 protocol [XENIX CORE]
2412 protocol [MICROSOFT NETWORKS 1.03]
2413 protocol [LANMAN1.0]
2414 protocol [Windows for Workgroups 3.1a]
2415 protocol [LM1.2X002]
2416 protocol [LANMAN2.1]
2417 protocol [NT LM 0.12]
2420 protocol [PC NETWORK PROGRAM 1.0]
2421 protocol [XENIX CORE]
2422 protocol [MICROSOFT NETWORKS 1.03]
2423 protocol [LANMAN1.0]
2424 protocol [Windows for Workgroups 3.1a]
2425 protocol [LM1.2X002]
2426 protocol [LANMAN2.1]
2427 protocol [NT LM 0.12]
2430 protocol [PC NETWORK PROGRAM 1.0]
2431 protocol [XENIX CORE]
2432 protocol [LANMAN1.0]
2433 protocol [LM1.2X002]
2434 protocol [LANMAN2.1]
2438 * Modified to recognize the architecture of the remote machine better.
2440 * This appears to be the matrix of which protocol is used by which
2442 Protocol WfWg Win95 WinNT OS/2
2443 PC NETWORK PROGRAM 1.0 1 1 1 1
2445 MICROSOFT NETWORKS 3.0 2 2
2447 MICROSOFT NETWORKS 1.03 3
2450 Windows for Workgroups 3.1a 5 5 5
2455 * tim@fsg.com 09/29/95
2458 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2459 #define ARCH_WIN95 0x2
2460 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2461 #define ARCH_WINNT 0x8
2462 #define ARCH_SAMBA 0x10
2464 #define ARCH_ALL 0x1F
2466 /* List of supported protocols, most desired first */
2470 int (*proto_reply_fn)(char *);
2472 } supported_protocols[] = {
2473 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2474 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2475 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2476 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2477 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2478 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2479 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2480 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2481 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2486 /****************************************************************************
2488 ****************************************************************************/
2489 static int reply_negprot(char *inbuf,char *outbuf)
2491 extern fstring remote_arch;
2492 int outsize = set_message(outbuf,1,0,True);
2497 int bcc = SVAL(smb_buf(inbuf),-2);
2498 int arch = ARCH_ALL;
2500 p = smb_buf(inbuf)+1;
2501 while (p < (smb_buf(inbuf) + bcc))
2504 DEBUG(3,("Requested protocol [%s]\n",p));
2505 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2506 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2507 else if (strcsequal(p,"DOS LM1.2X002"))
2508 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2509 else if (strcsequal(p,"DOS LANMAN2.1"))
2510 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2511 else if (strcsequal(p,"NT LM 0.12"))
2512 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2513 else if (strcsequal(p,"LANMAN2.1"))
2514 arch &= ( ARCH_WINNT | ARCH_OS2 );
2515 else if (strcsequal(p,"LM1.2X002"))
2516 arch &= ( ARCH_WINNT | ARCH_OS2 );
2517 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2519 else if (strcsequal(p,"XENIX CORE"))
2520 arch &= ( ARCH_WINNT | ARCH_OS2 );
2521 else if (strcsequal(p,"Samba")) {
2531 strcpy(remote_arch,"Samba");
2534 strcpy(remote_arch,"WfWg");
2537 strcpy(remote_arch,"Win95");
2540 strcpy(remote_arch,"WinNT");
2543 strcpy(remote_arch,"OS2");
2546 strcpy(remote_arch,"UNKNOWN");
2550 /* possibly reload - change of architecture */
2551 reload_services(True);
2553 /* a special case to stop password server loops */
2554 if (Index == 1 && strequal(remote_machine,myhostname) &&
2555 lp_security()==SEC_SERVER)
2556 exit_server("Password server loop!");
2558 /* Check for protocols, most desirable first */
2559 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2561 p = smb_buf(inbuf)+1;
2563 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2564 while (p < (smb_buf(inbuf) + bcc))
2566 if (strequal(p,supported_protocols[protocol].proto_name))
2575 SSVAL(outbuf,smb_vwv0,choice);
2577 extern fstring remote_proto;
2578 strcpy(remote_proto,supported_protocols[protocol].short_name);
2579 reload_services(True);
2580 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
2581 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
2584 DEBUG(0,("No protocol supported !\n"));
2586 SSVAL(outbuf,smb_vwv0,choice);
2588 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
2594 /****************************************************************************
2595 parse a connect packet
2596 ****************************************************************************/
2597 void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev)
2599 char *p = smb_buf(buf) + 1;
2602 DEBUG(4,("parsing connect string %s\n",p));
2604 p2 = strrchr(p,'\\');
2608 strcpy(service,p2+1);
2613 *pwlen = strlen(password);
2620 p = strchr(service,'%');
2629 /****************************************************************************
2630 close all open files for a connection
2631 ****************************************************************************/
2632 static void close_open_files(int cnum)
2635 for (i=0;i<MAX_OPEN_FILES;i++)
2636 if( Files[i].cnum == cnum && Files[i].open) {
2643 /****************************************************************************
2645 ****************************************************************************/
2646 void close_cnum(int cnum, int uid)
2648 extern struct from_host Client_info;
2650 DirCacheFlush(SNUM(cnum));
2654 if (!OPEN_CNUM(cnum))
2656 DEBUG(0,("Can't close cnum %d\n",cnum));
2660 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
2662 Client_info.name,Client_info.addr,
2663 lp_servicename(SNUM(cnum))));
2665 yield_connection(cnum,
2666 lp_servicename(SNUM(cnum)),
2667 lp_max_connections(SNUM(cnum)));
2669 if (lp_status(SNUM(cnum)))
2670 yield_connection(cnum,"STATUS.",MAXSTATUS);
2672 close_open_files(cnum);
2673 dptr_closecnum(cnum);
2675 /* execute any "postexec = " line */
2676 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,uid))
2679 strcpy(cmd,lp_postexec(SNUM(cnum)));
2680 standard_sub(cnum,cmd);
2686 /* execute any "root postexec = " line */
2687 if (*lp_rootpostexec(SNUM(cnum)))
2690 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
2691 standard_sub(cnum,cmd);
2695 Connections[cnum].open = False;
2696 num_connections_open--;
2697 if (Connections[cnum].ngroups && Connections[cnum].groups)
2699 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
2700 free(Connections[cnum].groups);
2701 free(Connections[cnum].igroups);
2702 Connections[cnum].groups = NULL;
2703 Connections[cnum].igroups = NULL;
2704 Connections[cnum].ngroups = 0;
2707 string_set(&Connections[cnum].user,"");
2708 string_set(&Connections[cnum].dirpath,"");
2709 string_set(&Connections[cnum].connectpath,"");
2713 /****************************************************************************
2714 simple routines to do connection counting
2715 ****************************************************************************/
2716 BOOL yield_connection(int cnum,char *name,int max_connections)
2718 struct connect_record crec;
2721 int mypid = getpid();
2724 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
2726 if (max_connections <= 0)
2729 bzero(&crec,sizeof(crec));
2731 strcpy(fname,lp_lockdir());
2732 standard_sub(cnum,fname);
2733 trim_string(fname,"","/");
2737 strcat(fname,".LCK");
2739 f = fopen(fname,"r+");
2742 DEBUG(2,("Coudn't open lock file %s (%s)\n",fname,strerror(errno)));
2746 fseek(f,0,SEEK_SET);
2748 /* find a free spot */
2749 for (i=0;i<max_connections;i++)
2751 if (fread(&crec,sizeof(crec),1,f) != 1)
2753 DEBUG(2,("Entry not found in lock file %s\n",fname));
2757 if (crec.pid == mypid && crec.cnum == cnum)
2761 if (crec.pid != mypid || crec.cnum != cnum)
2764 DEBUG(2,("Entry not found in lock file %s\n",fname));
2768 bzero((void *)&crec,sizeof(crec));
2770 /* remove our mark */
2771 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2772 fwrite(&crec,sizeof(crec),1,f) != 1)
2774 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
2779 DEBUG(3,("Yield successful\n"));
2786 /****************************************************************************
2787 simple routines to do connection counting
2788 ****************************************************************************/
2789 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
2791 struct connect_record crec;
2794 int snum = SNUM(cnum);
2798 if (max_connections <= 0)
2801 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
2803 strcpy(fname,lp_lockdir());
2804 standard_sub(cnum,fname);
2805 trim_string(fname,"","/");
2807 if (!directory_exist(fname,NULL))
2812 strcat(fname,".LCK");
2814 if (!file_exist(fname,NULL))
2816 f = fopen(fname,"w");
2820 total_recs = file_size(fname) / sizeof(crec);
2822 f = fopen(fname,"r+");
2826 DEBUG(1,("couldn't open lock file %s\n",fname));
2830 /* find a free spot */
2831 for (i=0;i<max_connections;i++)
2834 if (i>=total_recs ||
2835 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2836 fread(&crec,sizeof(crec),1,f) != 1)
2838 if (foundi < 0) foundi = i;
2842 if (Clear && crec.pid && !process_exists(crec.pid))
2844 fseek(f,i*sizeof(crec),SEEK_SET);
2845 bzero((void *)&crec,sizeof(crec));
2846 fwrite(&crec,sizeof(crec),1,f);
2847 if (foundi < 0) foundi = i;
2850 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
2859 DEBUG(3,("no free locks in %s\n",fname));
2864 /* fill in the crec */
2865 bzero((void *)&crec,sizeof(crec));
2866 crec.magic = 0x280267;
2867 crec.pid = getpid();
2869 crec.uid = Connections[cnum].uid;
2870 crec.gid = Connections[cnum].gid;
2871 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
2872 crec.start = time(NULL);
2875 extern struct from_host Client_info;
2876 StrnCpy(crec.machine,Client_info.name,sizeof(crec.machine)-1);
2877 StrnCpy(crec.addr,Client_info.addr,sizeof(crec.addr)-1);
2881 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
2882 fwrite(&crec,sizeof(crec),1,f) != 1)
2893 /*******************************************************************
2894 prepare to dump a core file - carefully!
2895 ********************************************************************/
2896 static BOOL dump_core(void)
2900 strcpy(dname,debugf);
2901 if ((p=strrchr(dname,'/'))) *p=0;
2902 strcat(dname,"/corefiles");
2904 sys_chown(dname,getuid(),getgid());
2906 if (chdir(dname)) return(False);
2909 #ifndef NO_GETRLIMIT
2913 getrlimit(RLIMIT_CORE, &rlp);
2914 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
2915 setrlimit(RLIMIT_CORE, &rlp);
2916 getrlimit(RLIMIT_CORE, &rlp);
2917 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
2923 DEBUG(0,("Dumping core in %s\n",dname));
2928 /****************************************************************************
2930 ****************************************************************************/
2931 void exit_server(char *reason)
2933 static int firsttime=1;
2936 if (!firsttime) exit(0);
2940 DEBUG(2,("Closing connections\n"));
2941 for (i=0;i<MAX_CONNECTIONS;i++)
2942 if (Connections[i].open)
2945 if (dcelogin_atmost_once)
2949 int oldlevel = DEBUGLEVEL;
2951 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
2953 show_msg(last_inbuf);
2954 DEBUGLEVEL = oldlevel;
2955 DEBUG(0,("===============================================================\n"));
2957 if (dump_core()) return;
2960 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
2964 /****************************************************************************
2965 do some standard substitutions in a string
2966 ****************************************************************************/
2967 void standard_sub(int cnum,char *s)
2969 if (!strchr(s,'%')) return;
2971 if (VALID_CNUM(cnum))
2973 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
2974 string_sub(s,"%P",Connections[cnum].connectpath);
2975 string_sub(s,"%u",Connections[cnum].user);
2976 if (strstr(s,"%H")) {
2977 char *home = get_home_dir(Connections[cnum].user);
2978 if (home) string_sub(s,"%H",home);
2980 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
2982 standard_sub_basic(s);
2986 These flags determine some of the permissions required to do an operation
2988 Note that I don't set NEED_WRITE on some write operations because they
2989 are used by some brain-dead clients when printing, and I don't want to
2990 force write permissions on print services.
2992 #define AS_USER (1<<0)
2993 #define NEED_WRITE (1<<1)
2994 #define TIME_INIT (1<<2)
2995 #define CAN_IPC (1<<3)
2996 #define AS_GUEST (1<<5)
3000 define a list of possible SMB messages and their corresponding
3001 functions. Any message that has a NULL function is unimplemented -
3002 please feel free to contribute implementations!
3004 struct smb_message_struct
3018 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3019 {SMBtcon,"SMBtcon",reply_tcon,0},
3020 {SMBtdis,"SMBtdis",reply_tdis,0},
3021 {SMBexit,"SMBexit",reply_exit,0},
3022 {SMBioctl,"SMBioctl",reply_ioctl,0},
3023 {SMBecho,"SMBecho",reply_echo,0},
3024 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3025 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3026 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0},
3027 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3028 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3029 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3030 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3031 {SMBopen,"SMBopen",reply_open,AS_USER},
3033 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3034 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3035 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3037 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3038 {SMBread,"SMBread",reply_read,AS_USER},
3039 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3040 {SMBclose,"SMBclose",reply_close,AS_USER},
3041 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3042 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3043 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3044 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3046 /* this is a Pathworks specific call, allowing the
3047 changing of the root path */
3048 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3050 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3051 {SMBflush,"SMBflush",reply_flush,AS_USER},
3052 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3053 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3054 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3055 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER},
3056 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3057 {SMBlock,"SMBlock",reply_lock,AS_USER},
3058 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3060 /* CORE+ PROTOCOL FOLLOWS */
3062 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3063 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3064 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3065 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3066 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3068 /* LANMAN1.0 PROTOCOL FOLLOWS */
3070 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3071 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3072 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3073 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3074 {SMBwritec,"SMBwritec",NULL,AS_USER},
3075 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3076 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3077 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3078 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3079 {SMBioctls,"SMBioctls",NULL,AS_USER},
3080 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3081 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3083 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER},
3084 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3085 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3086 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3088 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3089 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3090 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3092 /* LANMAN2.0 PROTOCOL FOLLOWS */
3093 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3094 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3095 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3096 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3098 /* messaging routines */
3099 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3100 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3101 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3102 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3104 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3106 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3107 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3108 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3109 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3112 /****************************************************************************
3113 return a string containing the function name of a SMB command
3114 ****************************************************************************/
3115 char *smb_fn_name(int type)
3117 static char *unknown_name = "SMBunknown";
3118 static int num_smb_messages =
3119 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3122 for (match=0;match<num_smb_messages;match++)
3123 if (smb_messages[match].code == type)
3126 if (match == num_smb_messages)
3127 return(unknown_name);
3129 return(smb_messages[match].name);
3133 /****************************************************************************
3134 do a switch on the message type, and return the response size
3135 ****************************************************************************/
3136 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3140 static int num_smb_messages =
3141 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3145 struct timeval msg_start_time;
3146 struct timeval msg_end_time;
3147 static unsigned long total_time = 0;
3149 GetTimeOfDay(&msg_start_time);
3156 last_message = type;
3158 /* make sure this is an SMB packet */
3159 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3161 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3165 for (match=0;match<num_smb_messages;match++)
3166 if (smb_messages[match].code == type)
3169 if (match == num_smb_messages)
3171 DEBUG(0,("Unknown message type %d!\n",type));
3172 outsize = reply_unknown(inbuf,outbuf);
3176 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3177 if (smb_messages[match].fn)
3179 int cnum = SVAL(inbuf,smb_tid);
3180 int flags = smb_messages[match].flags;
3181 int uid = SVAL(inbuf,smb_uid);
3183 /* does this protocol need to be run as root? */
3184 if (!(flags & AS_USER))
3187 /* does this protocol need to be run as the connected user? */
3188 if ((flags & AS_USER) && !become_user(cnum,uid))
3189 return(ERROR(ERRSRV,ERRinvnid));
3191 /* does it need write permission? */
3192 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3193 return(ERROR(ERRSRV,ERRaccess));
3195 /* ipc services are limited */
3196 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3197 return(ERROR(ERRSRV,ERRaccess));
3199 /* load service specific parameters */
3200 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3201 return(ERROR(ERRSRV,ERRaccess));
3203 /* does this protocol need to be run as guest? */
3204 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3205 return(ERROR(ERRSRV,ERRaccess));
3209 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3213 outsize = reply_unknown(inbuf,outbuf);
3218 GetTimeOfDay(&msg_end_time);
3219 if (!(smb_messages[match].flags & TIME_INIT))
3221 smb_messages[match].time = 0;
3222 smb_messages[match].flags |= TIME_INIT;
3225 unsigned long this_time =
3226 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3227 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3228 smb_messages[match].time += this_time;
3229 total_time += this_time;
3231 DEBUG(2,("TIME %s %d usecs %g pct\n",
3232 smb_fn_name(type),smb_messages[match].time,
3233 (100.0*smb_messages[match].time) / total_time));
3240 /****************************************************************************
3241 construct a chained reply and add it to the already made reply
3243 inbuf points to the original message start.
3244 inbuf2 points to the smb_wct part of the secondary message
3245 type is the type of the secondary message
3246 outbuf points to the original outbuffer
3247 outbuf2 points to the smb_wct field of the new outbuffer
3248 size is the total length of the incoming message (from inbuf1)
3249 bufsize is the total buffer size
3251 return how many bytes were added to the response
3252 ****************************************************************************/
3253 int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize)
3257 static BOOL in_chain = False;
3258 static char *last_outbuf=NULL;
3259 BOOL was_inchain = in_chain;
3260 int insize_remaining;
3261 static int insize_deleted;
3264 chain_size += PTR_DIFF(outbuf2,outbuf) - smb_wct;
3266 outbuf = last_outbuf;
3272 inbuf2 -= insize_deleted;
3273 insize_remaining = size - PTR_DIFF(inbuf2,inbuf);
3274 insize_deleted += size - (insize_remaining + smb_wct);
3277 last_outbuf = outbuf;
3280 /* allocate some space for the in and out buffers of the chained message */
3281 ibuf = (char *)malloc(size + SAFETY_MARGIN);
3282 obuf = (char *)malloc(bufsize + SAFETY_MARGIN);
3286 DEBUG(0,("Out of memory in chain reply\n"));
3287 return(ERROR(ERRSRV,ERRnoresource));
3290 ibuf += SMB_ALIGNMENT;
3291 obuf += SMB_ALIGNMENT;
3293 /* create the in buffer */
3294 memcpy(ibuf,inbuf,smb_wct);
3295 memcpy(ibuf+smb_wct,inbuf2,insize_remaining);
3296 CVAL(ibuf,smb_com) = type;
3298 /* create the out buffer */
3299 bzero(obuf,smb_size);
3301 set_message(obuf,0,0,True);
3302 CVAL(obuf,smb_com) = CVAL(ibuf,smb_com);
3304 memcpy(obuf+4,ibuf+4,4);
3305 CVAL(obuf,smb_rcls) = SUCCESS;
3306 CVAL(obuf,smb_reh) = 0;
3307 CVAL(obuf,smb_flg) = 0x80 | (CVAL(ibuf,smb_flg) & 0x8); /* bit 7 set
3309 SSVAL(obuf,smb_flg2,1); /* say we support long filenames */
3310 SSVAL(obuf,smb_err,SUCCESS);
3311 SSVAL(obuf,smb_tid,SVAL(inbuf,smb_tid));
3312 SSVAL(obuf,smb_pid,SVAL(inbuf,smb_pid));
3313 SSVAL(obuf,smb_uid,SVAL(inbuf,smb_uid));
3314 SSVAL(obuf,smb_mid,SVAL(inbuf,smb_mid));
3316 DEBUG(3,("Chained message\n"));
3319 /* process the request */
3320 outsize = switch_message(type,ibuf,obuf,smb_wct+insize_remaining,
3321 bufsize-chain_size);
3323 /* copy the new reply header over the old one, but preserve
3324 the smb_com field */
3325 memcpy(outbuf+smb_com+1,obuf+smb_com+1,smb_wct-(smb_com+1));
3327 /* and copy the data from the reply to the right spot */
3328 memcpy(outbuf2,obuf+smb_wct,outsize - smb_wct);
3330 /* free the allocated buffers */
3331 if (ibuf) free(ibuf-SMB_ALIGNMENT);
3332 if (obuf) free(obuf-SMB_ALIGNMENT);
3334 in_chain = was_inchain;
3336 /* return how much extra has been added to the packet */
3337 return(outsize - smb_wct);
3342 /****************************************************************************
3343 construct a reply to the incoming packet
3344 ****************************************************************************/
3345 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3347 int type = CVAL(inbuf,smb_com);
3349 int msg_type = CVAL(inbuf,0);
3351 smb_last_time = time(NULL);
3355 bzero(outbuf,smb_size);
3358 return(reply_special(inbuf,outbuf));
3360 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3361 set_message(outbuf,0,0,True);
3363 memcpy(outbuf+4,inbuf+4,4);
3364 CVAL(outbuf,smb_rcls) = SUCCESS;
3365 CVAL(outbuf,smb_reh) = 0;
3366 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3368 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3369 SSVAL(outbuf,smb_err,SUCCESS);
3370 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3371 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3372 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3373 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3375 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3378 smb_setlen(outbuf,outsize - 4);
3383 /****************************************************************************
3384 process commands from the client
3385 ****************************************************************************/
3388 static int trans_num = 0;
3390 extern struct from_host Client_info;
3393 fromhost(Client,&Client_info);
3395 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3396 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3397 if ((InBuffer == NULL) || (OutBuffer == NULL))
3400 InBuffer += SMB_ALIGNMENT;
3401 OutBuffer += SMB_ALIGNMENT;
3404 DEBUG(3,("priming nmbd\n"));
3407 ip = *interpret_addr2("localhost");
3408 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3410 send_one_packet(OutBuffer,1,ip,137,SOCK_DGRAM);
3420 int deadtime = lp_deadtime()*60;
3422 int last_keepalive=0;
3425 deadtime = DEFAULT_SMBD_TIMEOUT;
3427 if (lp_readprediction())
3428 do_read_prediction();
3431 extern pstring share_del_pending;
3432 if (*share_del_pending) {
3434 if (!unlink(share_del_pending))
3435 DEBUG(3,("Share file deleted %s\n",share_del_pending));
3437 DEBUG(2,("Share del failed of %s\n",share_del_pending));
3438 share_del_pending[0] = 0;
3442 if (share_mode_pending) {
3444 check_share_modes();
3445 share_mode_pending=False;
3450 for (counter=SMBD_SELECT_LOOP;
3451 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3452 counter += SMBD_SELECT_LOOP)
3456 BOOL allidle = True;
3457 extern int keepalive;
3459 /* check for socket failure */
3461 DEBUG(3,("receive_smb error (%s) exiting\n",strerror(errno)));
3467 /* become root again if waiting */
3470 /* check for smb.conf reload */
3471 if (!(counter%SMBD_RELOAD_CHECK))
3472 reload_services(True);
3474 /* check the share modes every 10 secs */
3475 if (!(counter%SHARE_MODES_CHECK))
3476 check_share_modes();
3478 /* clean the share modes every 5 minutes */
3479 if (!(counter%SHARE_MODES_CLEAN))
3480 clean_share_files();
3482 /* automatic timeout if all connections are closed */
3483 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3484 DEBUG(2,("%s Closing idle connection\n",timestring()));
3488 if (keepalive && (counter-last_keepalive)>keepalive) {
3489 extern int password_client;
3490 if (!send_keepalive(Client)) {
3491 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3494 /* also send a keepalive to the password server if its still
3496 if (password_client != -1)
3497 send_keepalive(password_client);
3498 last_keepalive = counter;
3501 /* check for connection timeouts */
3502 for (i=0;i<MAX_CONNECTIONS;i++)
3503 if (Connections[i].open)
3505 /* close dirptrs on connections that are idle */
3506 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3509 if (Connections[i].num_files_open > 0 ||
3510 (t-Connections[i].lastused)<deadtime)
3514 if (allidle && num_connections_open>0) {
3515 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3520 msg_type = CVAL(InBuffer,0);
3521 msg_flags = CVAL(InBuffer,1);
3522 type = CVAL(InBuffer,smb_com);
3524 len = smb_len(InBuffer);
3526 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3530 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3533 if(trans_num == 1 && VT_Check(InBuffer)) {
3543 nread = construct_reply(InBuffer,OutBuffer,nread,maxxmit);
3546 if (CVAL(OutBuffer,0) == 0)
3547 show_msg(OutBuffer);
3549 if (nread != smb_len(OutBuffer) + 4)
3551 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3553 smb_len(OutBuffer)));
3556 send_smb(Client,OutBuffer);
3563 /****************************************************************************
3564 initialise connect, service and file structs
3565 ****************************************************************************/
3566 static void init_structs(void )
3569 get_myname(myhostname,&myip);
3571 for (i=0;i<MAX_CONNECTIONS;i++)
3573 Connections[i].open = False;
3574 Connections[i].num_files_open=0;
3575 Connections[i].lastused=0;
3576 Connections[i].used=False;
3577 string_init(&Connections[i].user,"");
3578 string_init(&Connections[i].dirpath,"");
3579 string_init(&Connections[i].connectpath,"");
3580 string_init(&Connections[i].origpath,"");
3583 for (i=0;i<MAX_OPEN_FILES;i++)
3585 Files[i].open = False;
3586 string_init(&Files[i].name,"");
3592 /****************************************************************************
3593 usage on the program
3594 ****************************************************************************/
3595 void usage(char *pname)
3597 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3599 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3600 printf("Version %s\n",VERSION);
3601 printf("\t-D become a daemon\n");
3602 printf("\t-p port listen on the specified port\n");
3603 printf("\t-d debuglevel set the debuglevel\n");
3604 printf("\t-l log basename. Basename for log/debug files\n");
3605 printf("\t-s services file. Filename of services file\n");
3606 printf("\t-P passive only\n");
3607 printf("\t-a overwrite log file, don't append\n");
3612 /****************************************************************************
3614 ****************************************************************************/
3615 int main(int argc,char *argv[])
3617 extern BOOL append_log;
3618 /* shall I run as a daemon */
3619 BOOL is_daemon = False;
3622 extern char *optarg;
3624 #ifdef NEED_AUTH_PARAMETERS
3625 set_auth_parameters(argc,argv);
3636 strcpy(debugf,SMBLOGFILE);
3638 setup_logging(argv[0],False);
3640 charset_initialise();
3642 /* make absolutely sure we run as root - to handle cases whre people
3643 are crazy enough to have it setuid */
3653 fault_setup(exit_server);
3655 umask(0777 & ~DEF_CREATE_MASK);
3659 /* this is for people who can't start the program correctly */
3660 while (argc > 1 && (*argv[1] != '-'))
3666 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPa")) != EOF)
3670 strcpy(user_socket_options,optarg);
3673 strcpy(scope,optarg);
3677 extern BOOL passive;
3682 strcpy(servicesf,optarg);
3685 strcpy(debugf,optarg);
3689 extern BOOL append_log;
3690 append_log = !append_log;
3700 DEBUGLEVEL = atoi(optarg);
3703 port = atoi(optarg);
3716 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
3717 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
3719 #ifndef NO_GETRLIMIT
3720 #ifdef RLIMIT_NOFILE
3723 getrlimit(RLIMIT_NOFILE, &rlp);
3724 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
3725 setrlimit(RLIMIT_NOFILE, &rlp);
3726 getrlimit(RLIMIT_NOFILE, &rlp);
3727 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
3733 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
3734 getuid(),getgid(),geteuid(),getegid()));
3736 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
3738 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
3744 if (!reload_services(False))
3747 #ifndef NO_SIGNAL_TEST
3748 signal(SIGHUP,SIGNAL_CAST sig_hup);
3751 DEBUG(3,("%s loaded services\n",timestring()));
3753 if (!is_daemon && !is_a_socket(0))
3755 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
3761 DEBUG(3,("%s becoming a daemon\n",timestring()));
3765 if (!open_sockets(is_daemon,port))
3768 /* possibly reload the services file. */
3769 reload_services(True);
3771 maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
3775 if (sys_chroot(lp_rootdir()) == 0)
3776 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
3782 exit_server("normal exit");