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;
72 /* these can be set by some functions to override the error codes */
73 int unix_ERR_class=SUCCESS;
77 extern int extra_time_offset;
79 extern pstring myhostname;
81 static int find_free_connection(int hash);
83 /* for readability... */
84 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
85 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
86 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
87 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
88 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
92 /****************************************************************************
93 change a dos mode to a unix mode
94 base permission for files:
95 everybody gets read bit set
96 dos readonly is represented in unix by removing everyone's write bit
97 dos archive is represented in unix by the user's execute bit
98 dos system is represented in unix by the group's execute bit
99 dos hidden is represented in unix by the other's execute bit
100 base permission for directories:
101 dos directory is represented in unix by unix's dir bit and the exec bit
102 ****************************************************************************/
103 mode_t unix_mode(int cnum,int dosmode)
105 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
107 if ( !IS_DOS_READONLY(dosmode) )
108 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
110 if (IS_DOS_DIR(dosmode))
111 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
113 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
116 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
119 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
122 result &= CREATE_MODE(cnum);
127 /****************************************************************************
128 change a unix mode to a dos mode
129 ****************************************************************************/
130 int dos_mode(int cnum,char *path,struct stat *sbuf)
133 extern struct current_user current_user;
135 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
136 if (!((sbuf->st_mode & S_IWOTH) ||
137 Connections[cnum].admin_user ||
138 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
139 ((sbuf->st_mode & S_IWGRP) &&
140 in_group(sbuf->st_gid,current_user.gid,
141 current_user.ngroups,current_user.igroups))))
144 if ((sbuf->st_mode & S_IWUSR) == 0)
148 if ((sbuf->st_mode & S_IXUSR) != 0)
151 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
154 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
157 if (S_ISDIR(sbuf->st_mode))
158 result = aDIR | (result & aRONLY);
161 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
165 /* hide files with a name starting with a . */
166 if (lp_hide_dot_files(SNUM(cnum)))
168 char *p = strrchr(path,'/');
174 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
182 /*******************************************************************
183 chmod a file - but preserve some bits
184 ********************************************************************/
185 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
194 if (sys_stat(fname,st)) return(-1);
197 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
199 if (dos_mode(cnum,fname,st) == dosmode) return(0);
201 unixmode = unix_mode(cnum,dosmode);
203 /* preserve the s bits */
204 mask |= (S_ISUID | S_ISGID);
206 /* preserve the t bit */
211 /* possibly preserve the x bits */
212 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
213 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
214 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
216 unixmode |= (st->st_mode & mask);
218 /* if we previously had any r bits set then leave them alone */
219 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
220 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
224 /* if we previously had any w bits set then leave them alone
225 if the new mode is not rdonly */
226 if (!IS_DOS_READONLY(dosmode) &&
227 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
228 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
232 return(sys_chmod(fname,unixmode));
236 /****************************************************************************
237 check if two filenames are equal
239 this needs to be careful about whether we are case sensitive
240 ****************************************************************************/
241 static BOOL fname_equal(char *name1, char *name2)
243 int l1 = strlen(name1);
244 int l2 = strlen(name2);
246 /* handle filenames ending in a single dot */
247 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
251 ret = fname_equal(name1,name2);
256 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
260 ret = fname_equal(name1,name2);
265 /* now normal filename handling */
267 return(strcmp(name1,name2) == 0);
269 return(strequal(name1,name2));
273 /****************************************************************************
274 mangle the 2nd name and check if it is then equal to the first name
275 ****************************************************************************/
276 static BOOL mangled_equal(char *name1, char *name2)
283 strcpy(tmpname,name2);
284 mangle_name_83(tmpname);
286 return(strequal(name1,tmpname));
290 /****************************************************************************
291 scan a directory to find a filename, matching without case sensitivity
293 If the name looks like a mangled name then try via the mangling functions
294 ****************************************************************************/
295 static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
302 mangled = is_mangled(name);
304 /* handle null paths */
308 if (docache && (dname = DirCacheCheck(path,name,snum))) {
314 check_mangled_stack(name);
316 /* open the directory */
317 if (!(cur_dir = OpenDir(path)))
319 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
323 /* now scan for matching names */
324 while ((dname = ReadDirName(cur_dir)))
327 (strequal(dname,".") || strequal(dname,"..")))
331 if (!name_map_mangle(name2,False,snum)) continue;
333 if ((mangled && mangled_equal(name,name2))
334 || fname_equal(name, name2))
336 /* we've found the file, change it's name and return */
337 if (docache) DirCacheAdd(path,name,dname,snum);
348 /****************************************************************************
349 This routine is called to convert names from the dos namespace to unix
350 namespace. It needs to handle any case conversions, mangling, format
353 We assume that we have already done a chdir() to the right "root" directory
356 The function will return False if some part of the name except for the last
357 part cannot be resolved
358 ****************************************************************************/
359 BOOL unix_convert(char *name,int cnum)
367 /* convert to basic unix format - removing \ chars and cleaning it up */
369 unix_clean_name(name);
371 if (!case_sensitive &&
372 (!case_preserve || (is_8_3(name) && !short_case_preserve)))
375 /* names must be relative to the root of the service - trim any leading /.
376 also trim trailing /'s */
377 trim_string(name,"/","/");
379 /* check if it's a printer file */
380 if (Connections[cnum].printer)
382 if ((! *name) || strchr(name,'/') || !is_8_3(name))
386 sprintf(name2,"%.6s.XXXXXX",remote_machine);
387 /* sanitise the name */
388 for (s=name2 ; *s ; s++)
389 if (!issafe(*s)) *s = '_';
390 strcpy(name,(char *)mktemp(name2));
395 /* stat the name - if it exists then we are all done! */
396 if (sys_stat(name,&st) == 0)
399 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
401 /* a special case - if we don't have any mangling chars and are case
402 sensitive then searching won't help */
403 if (case_sensitive && !is_mangled(name) &&
404 !lp_strip_dot() && !use_mangled_map)
407 /* now we need to recursively match the name against the real
408 directory structure */
411 while (strncmp(start,"./",2) == 0)
414 /* now match each part of the path name separately, trying the names
415 as is first, then trying to scan the directory for matching names */
416 for (;start;start = (end?end+1:(char *)NULL))
418 /* pinpoint the end of this section of the filename */
419 end = strchr(start, '/');
421 /* chop the name at this point */
424 /* check if the name exists up to this point */
425 if (sys_stat(name, &st) == 0)
427 /* it exists. it must either be a directory or this must be
428 the last part of the path for it to be OK */
429 if (end && !(st.st_mode & S_IFDIR))
431 /* an intermediate part of the name isn't a directory */
432 DEBUG(5,("Not a dir %s\n",start));
443 /* remember the rest of the pathname so it can be restored
445 if (end) strcpy(rest,end+1);
448 /* try to find this part of the path in the directory */
449 if (strchr(start,'?') || strchr(start,'*') ||
450 !scan_directory(dirpath, start, SNUM(cnum), end?True:False))
454 /* an intermediate part of the name can't be found */
455 DEBUG(5,("Intermediate not found %s\n",start));
460 /* just the last part of the name doesn't exist */
461 /* we may need to strupper() or strlower() it in case
462 this conversion is being used for file creation
464 /* if the filename is of mixed case then don't normalise it */
465 if (!case_preserve &&
466 (!strhasupper(start) || !strhaslower(start)))
469 /* check on the mangled stack to see if we can recover the
470 base of the filename */
471 if (is_mangled(start))
472 check_mangled_stack(start);
474 DEBUG(5,("New file %s\n",start));
478 /* restore the rest of the string */
481 strcpy(start+strlen(start)+1,rest);
482 end = start + strlen(start);
486 /* add to the dirpath that we have resolved so far */
487 if (*dirpath) strcat(dirpath,"/");
488 strcat(dirpath,start);
490 /* restore the / that we wiped out earlier */
494 /* the name has been resolved */
495 DEBUG(5,("conversion finished %s\n",name));
500 /****************************************************************************
501 normalise for DOS usage
502 ****************************************************************************/
503 static void disk_norm(int *bsize,int *dfree,int *dsize)
505 /* check if the disk is beyond the max disk size */
506 int maxdisksize = lp_maxdisksize();
508 /* convert to blocks - and don't overflow */
509 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
510 if (*dsize > maxdisksize) *dsize = maxdisksize;
511 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
516 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
521 if (*bsize > WORDMAX )
524 if (*dsize > WORDMAX)
526 if (*dfree > WORDMAX)
533 /****************************************************************************
534 return number of 1K blocks available on a path and total number
535 ****************************************************************************/
536 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
538 char *df_command = lp_dfree_command();
552 if (disk_quotas(path, bsize, dfree, dsize))
554 disk_norm(bsize,dfree,dsize);
555 return(((*bsize)/1024)*(*dfree));
560 /* possibly use system() to get the result */
561 if (df_command && *df_command)
567 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
568 sprintf(syscmd,"%s %s",df_command,path);
569 standard_sub_basic(syscmd);
571 ret = smbrun(syscmd,outfile,False);
572 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
575 FILE *f = fopen(outfile,"r");
581 fscanf(f,"%d %d %d",dsize,dfree,bsize);
585 DEBUG(0,("Can't open %s\n",outfile));
589 disk_norm(bsize,dfree,dsize);
590 return(((*bsize)/1024)*(*dfree));
594 DEBUG(1,("Warning - no statfs function\n"));
598 if (statfs(path,&fs,sizeof(fs),0) != 0)
601 if (statvfs(path, &fs))
604 if (statfs(path,&fs,sizeof(fs)) == -1)
606 if (statfs(path,&fs) == -1)
608 #endif /* USE_STATVFS */
611 DEBUG(3,("dfree call failed code errno=%d\n",errno));
615 return(((*bsize)/1024)*(*dfree));
620 *dfree = fs.fd_req.bfree;
621 *dsize = fs.fd_req.btot;
624 *bsize = fs.f_frsize;
627 /* eg: osf1 has f_fsize = fundamental filesystem block size,
628 f_bsize = optimal transfer block size (MX: 94-04-19) */
633 #endif /* USE_STATVFS */
638 *dfree = fs.f_bavail;
640 *dsize = fs.f_blocks;
643 #if defined(SCO) || defined(ISC) || defined(MIPS)
647 /* handle rediculous bsize values - some OSes are broken */
648 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
650 disk_norm(bsize,dfree,dsize);
656 DEBUG(0,("dfree seems to be broken on your system\n"));
657 *dsize = 20*1024*1024/(*bsize);
658 *dfree = MAX(1,*dfree);
660 return(((*bsize)/1024)*(*dfree));
665 /****************************************************************************
666 wrap it to get filenames right
667 ****************************************************************************/
668 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
670 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
675 /****************************************************************************
676 check a filename - possibly caling reducename
678 This is called by every routine before it allows an operation on a filename.
679 It does any final confirmation necessary to ensure that the filename is
680 a valid one for the user to access.
681 ****************************************************************************/
682 BOOL check_name(char *name,int cnum)
688 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
690 DEBUG(5,("check_name on %s failed\n",name));
695 /****************************************************************************
696 check a filename - possibly caling reducename
697 ****************************************************************************/
698 static void check_for_pipe(char *fname)
700 /* special case of pipe opens */
704 if (strstr(s,"pipe/"))
706 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
707 unix_ERR_class = ERRSRV;
708 unix_ERR_code = ERRaccess;
713 /****************************************************************************
715 ****************************************************************************/
716 void open_file(int fnum,int cnum,char *fname1,int flags,int mode)
718 extern struct current_user current_user;
721 Files[fnum].open = False;
725 strcpy(fname,fname1);
727 /* check permissions */
728 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
730 DEBUG(3,("Permission denied opening %s\n",fname));
731 check_for_pipe(fname);
735 /* this handles a bug in Win95 - it doesn't say to create the file when it
737 if (Connections[cnum].printer)
741 if (flags == O_WRONLY)
742 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
746 /* XXXX - is this OK?? */
747 /* this works around a utime bug but can cause other problems */
748 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
753 Files[fnum].fd = sys_open(fname,flags,mode);
755 if ((Files[fnum].fd>=0) &&
756 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
761 p = strrchr(dname,'/');
763 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
764 lp_minprintspace(SNUM(cnum))) {
765 close(Files[fnum].fd);
774 /* Fix for files ending in '.' */
775 if((Files[fnum].fd == -1) && (errno == ENOENT) &&
776 (strchr(fname,'.')==NULL))
779 Files[fnum].fd = sys_open(fname,flags,mode);
782 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
783 if ((Files[fnum].fd == -1) && (errno == ENAMETOOLONG))
786 char *p = strrchr(fname, '/');
788 if (p == fname) /* name is "/xxx" */
790 max_len = pathconf("/", _PC_NAME_MAX);
793 else if ((p == NULL) || (p == fname))
796 max_len = pathconf(".", _PC_NAME_MAX);
801 max_len = pathconf(fname, _PC_NAME_MAX);
805 if (strlen(p) > max_len)
807 char tmp = p[max_len];
810 if ((Files[fnum].fd = sys_open(fname,flags,mode)) == -1)
816 if (Files[fnum].fd < 0)
818 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
819 fname,strerror(errno),flags));
820 check_for_pipe(fname);
824 if (Files[fnum].fd >= 0)
827 Connections[cnum].num_files_open++;
828 fstat(Files[fnum].fd,&st);
829 Files[fnum].mode = st.st_mode;
830 Files[fnum].open_time = time(NULL);
831 Files[fnum].uid = current_user.id;
832 Files[fnum].size = 0;
833 Files[fnum].pos = -1;
834 Files[fnum].open = True;
835 Files[fnum].mmap_ptr = NULL;
836 Files[fnum].mmap_size = 0;
837 Files[fnum].can_lock = True;
838 Files[fnum].can_read = ((flags & O_WRONLY)==0);
839 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
840 Files[fnum].share_mode = 0;
841 Files[fnum].share_pending = False;
842 Files[fnum].print_file = Connections[cnum].printer;
843 Files[fnum].modified = False;
844 Files[fnum].cnum = cnum;
845 string_set(&Files[fnum].name,dos_to_unix(fname,False));
846 Files[fnum].wbmpx_ptr = NULL;
849 * If the printer is marked as postscript output a leading
850 * file identifier to ensure the file is treated as a raw
852 * This has a similar effect as CtrlD=0 in WIN.INI file.
853 * tim@fsg.com 09/06/94
855 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
856 Files[fnum].can_write)
858 DEBUG(3,("Writing postscript line\n"));
859 write_file(fnum,"%!\n",3);
862 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
863 timestring(),Connections[cnum].user,fname,
864 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
865 Connections[cnum].num_files_open,fnum));
870 /* mmap it if read-only */
871 if (!Files[fnum].can_write)
873 Files[fnum].mmap_size = file_size(fname);
874 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
875 PROT_READ,MAP_SHARED,Files[fnum].fd,0);
877 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
879 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
880 Files[fnum].mmap_ptr = NULL;
886 /*******************************************************************
888 ********************************************************************/
889 void sync_file(int fnum)
892 fsync(Files[fnum].fd);
896 /****************************************************************************
897 run a file if it is a magic script
898 ****************************************************************************/
899 static void check_magic(int fnum,int cnum)
901 if (!*lp_magicscript(SNUM(cnum)))
904 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
908 if (!(p = strrchr(Files[fnum].name,'/')))
909 p = Files[fnum].name;
913 if (!strequal(lp_magicscript(SNUM(cnum)),p))
919 pstring magic_output;
921 strcpy(fname,Files[fnum].name);
923 if (*lp_magicoutput(SNUM(cnum)))
924 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
926 sprintf(magic_output,"%s.out",fname);
929 ret = smbrun(fname,magic_output,False);
930 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
936 /****************************************************************************
937 close a file - possibly invalidating the read prediction
938 ****************************************************************************/
939 void close_file(int fnum)
941 int cnum = Files[fnum].cnum;
942 invalidate_read_prediction(Files[fnum].fd);
943 Files[fnum].open = False;
944 Connections[cnum].num_files_open--;
945 if(Files[fnum].wbmpx_ptr)
947 free((char *)Files[fnum].wbmpx_ptr);
948 Files[fnum].wbmpx_ptr = NULL;
952 if(Files[fnum].mmap_ptr)
954 munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size);
955 Files[fnum].mmap_ptr = NULL;
959 if (lp_share_modes(SNUM(cnum)))
960 del_share_mode(fnum);
962 close(Files[fnum].fd);
964 /* NT uses smbclose to start a print - weird */
965 if (Files[fnum].print_file)
968 /* check for magic scripts */
969 check_magic(fnum,cnum);
971 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
972 timestring(),Connections[cnum].user,Files[fnum].name,
973 Connections[cnum].num_files_open));
976 enum {AFAIL,AREAD,AWRITE,AALL};
978 /*******************************************************************
979 reproduce the share mode access table
980 ********************************************************************/
981 static int access_table(int new_deny,int old_deny,int old_mode,
982 int share_pid,char *fname)
984 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
986 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
987 if (old_deny == new_deny && share_pid == getpid())
990 if (old_mode == 0) return(AREAD);
992 /* the new smbpub.zip spec says that if the file extension is
993 .com, .dll, .exe or .sym then allow the open. I will force
994 it to read-only as this seems sensible although the spec is
995 a little unclear on this. */
996 if ((fname = strrchr(fname,'.'))) {
997 if (strequal(fname,".com") ||
998 strequal(fname,".dll") ||
999 strequal(fname,".exe") ||
1000 strequal(fname,".sym"))
1010 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1011 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1012 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1015 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1016 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1017 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1020 if (old_deny==DENY_WRITE) return(AREAD);
1021 if (old_deny==DENY_READ) return(AWRITE);
1022 if (old_deny==DENY_NONE) return(AALL);
1028 /*******************************************************************
1029 check if the share mode on a file allows it to be deleted or unlinked
1030 return True if sharing doesn't prevent the operation
1031 ********************************************************************/
1032 BOOL check_file_sharing(int cnum,char *fname)
1035 int share_mode = get_share_mode_byname(cnum,fname,&pid);
1037 if (!pid || !share_mode) return(True);
1039 if (share_mode == DENY_DOS)
1040 return(pid == getpid());
1042 /* XXXX exactly what share mode combinations should be allowed for
1043 deleting/renaming? */
1047 /****************************************************************************
1049 Helper for open_file_shared.
1050 Truncate a file after checking locking; close file if locked.
1051 **************************************************************************/
1052 static void truncate_unless_locked(int fnum, int cnum)
1054 if (Files[fnum].can_write){
1055 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1058 unix_ERR_class = ERRDOS;
1059 unix_ERR_code = ERRlock;
1062 ftruncate(Files[fnum].fd,0);
1067 /****************************************************************************
1068 open a file with a share mode
1069 ****************************************************************************/
1070 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1071 int mode,int *Access,int *action)
1075 int deny_mode = (share_mode>>4)&7;
1077 BOOL file_existed = file_exist(fname,&sbuf);
1078 BOOL fcbopen = False;
1081 Files[fnum].open = False;
1082 Files[fnum].fd = -1;
1084 /* this is for OS/2 EAs - try and say we don't support them */
1085 if (strstr(fname,".+,;=[].")) {
1086 unix_ERR_class = ERRDOS;
1087 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1091 if ((ofun & 0x3) == 0 && file_existed) {
1098 if ((ofun & 0x3) == 2)
1101 /* note that we ignore the append flag as
1102 append does not mean the same thing under dos and unix */
1104 switch (share_mode&0xF)
1121 if (flags != O_RDONLY && file_existed &&
1122 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) {
1130 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
1131 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1136 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1138 if (lp_share_modes(SNUM(cnum))) {
1142 old_share = get_share_mode(cnum,&sbuf,&share_pid);
1145 /* someone else has a share lock on it, check to see
1147 int old_open_mode = old_share&0xF;
1148 int old_deny_mode = (old_share>>4)&7;
1150 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) {
1151 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1152 deny_mode,old_deny_mode,old_open_mode,fname));
1154 unix_ERR_class = ERRDOS;
1155 unix_ERR_code = ERRbadshare;
1160 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1163 if ((access_allowed == AFAIL) ||
1164 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1165 (access_allowed == AREAD && flags == O_WRONLY) ||
1166 (access_allowed == AWRITE && flags == O_RDONLY)) {
1167 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1168 deny_mode,old_deny_mode,old_open_mode,
1172 unix_ERR_class = ERRDOS;
1173 unix_ERR_code = ERRbadshare;
1177 if (access_allowed == AREAD)
1180 if (access_allowed == AWRITE)
1186 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1187 flags,flags2,mode));
1189 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode);
1190 if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) {
1192 open_file(fnum,cnum,fname,flags,mode);
1195 if (Files[fnum].open) {
1209 Files[fnum].share_mode = (deny_mode<<4) | open_mode;
1210 Files[fnum].share_pending = True;
1213 (*Access) = open_mode;
1217 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1218 if (!file_existed) *action = 2;
1219 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1223 share_mode_pending = True;
1225 if ((flags2&O_TRUNC) && file_existed)
1226 truncate_unless_locked(fnum,cnum);
1232 /*******************************************************************
1233 check for files that we should now set our share modes on
1234 ********************************************************************/
1235 static void check_share_modes(void)
1238 for (i=0;i<MAX_OPEN_FILES;i++)
1239 if(Files[i].open && Files[i].share_pending) {
1240 if (lp_share_modes(SNUM(Files[i].cnum))) {
1242 get_share_mode_by_fnum(Files[i].cnum,i,&pid);
1244 set_share_mode(i,Files[i].share_mode);
1245 Files[i].share_pending = False;
1248 Files[i].share_pending = False;
1254 /****************************************************************************
1255 seek a file. Try to avoid the seek if possible
1256 ****************************************************************************/
1257 int seek_file(int fnum,int pos)
1260 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1263 Files[fnum].pos = lseek(Files[fnum].fd,pos+offset,SEEK_SET) - offset;
1264 return(Files[fnum].pos);
1267 /****************************************************************************
1269 ****************************************************************************/
1270 int read_file(int fnum,char *data,int pos,int n)
1274 if (!Files[fnum].can_write)
1276 ret = read_predict(Files[fnum].fd,pos,data,NULL,n);
1284 if (Files[fnum].mmap_ptr)
1286 int num = MIN(n,Files[fnum].mmap_size-pos);
1289 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1301 if (seek_file(fnum,pos) != pos)
1303 DEBUG(3,("Failed to seek to %d\n",pos));
1308 readret = read(Files[fnum].fd,data,n);
1309 if (readret > 0) ret += readret;
1316 /****************************************************************************
1318 ****************************************************************************/
1319 int write_file(int fnum,char *data,int n)
1321 if (!Files[fnum].can_write) {
1326 if (!Files[fnum].modified) {
1328 Files[fnum].modified = True;
1329 if (fstat(Files[fnum].fd,&st) == 0) {
1330 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1331 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1332 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1337 return(write_data(Files[fnum].fd,data,n));
1341 /****************************************************************************
1342 load parameters specific to a connection/service
1343 ****************************************************************************/
1344 BOOL become_service(int cnum,BOOL do_chdir)
1346 extern char magic_char;
1347 static int last_cnum = -1;
1350 if (!OPEN_CNUM(cnum))
1356 Connections[cnum].lastused = smb_last_time;
1361 ChDir(Connections[cnum].connectpath) != 0 &&
1362 ChDir(Connections[cnum].origpath) != 0)
1364 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1365 Connections[cnum].connectpath,cnum));
1369 if (cnum == last_cnum)
1374 case_default = lp_defaultcase(snum);
1375 case_preserve = lp_preservecase(snum);
1376 short_case_preserve = lp_shortpreservecase(snum);
1377 case_mangle = lp_casemangle(snum);
1378 case_sensitive = lp_casesensitive(snum);
1379 magic_char = lp_magicchar(snum);
1380 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1385 /****************************************************************************
1386 find a service entry
1387 ****************************************************************************/
1388 int find_service(char *service)
1392 string_sub(service,"\\","/");
1394 iService = lp_servicenumber(service);
1396 /* now handle the special case of a home directory */
1399 char *phome_dir = get_home_dir(service);
1400 DEBUG(3,("checking for home directory %s gave %s\n",service,
1401 phome_dir?phome_dir:"(NULL)"));
1405 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1407 lp_add_home(service,iHomeService,phome_dir);
1408 iService = lp_servicenumber(service);
1413 /* If we still don't have a service, attempt to add it as a printer. */
1416 int iPrinterService;
1418 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1422 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1424 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1426 DEBUG(3,("%s is a valid printer name\n", service));
1427 DEBUG(3,("adding %s as a printer service\n", service));
1428 lp_add_printer(service,iPrinterService);
1429 iService = lp_servicenumber(service);
1431 DEBUG(0,("failed to add %s as a printer service!\n", service));
1434 DEBUG(3,("%s is not a valid printer name\n", service));
1438 /* just possibly it's a default service? */
1441 char *defservice = lp_defaultservice();
1442 if (defservice && *defservice && !strequal(defservice,service)) {
1443 iService = find_service(defservice);
1444 if (iService >= 0) {
1445 string_sub(service,"_","/");
1446 iService = lp_add_service(service,iService);
1452 if (!VALID_SNUM(iService))
1454 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1459 DEBUG(3,("find_service() failed to find service %s\n", service));
1465 /****************************************************************************
1466 create an error packet from a cached error.
1467 ****************************************************************************/
1468 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1470 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1472 int32 eclass = wbmpx->wr_errclass;
1473 int32 err = wbmpx->wr_error;
1475 /* We can now delete the auxiliary struct */
1476 free((char *)wbmpx);
1477 Files[fnum].wbmpx_ptr = NULL;
1478 return error_packet(inbuf,outbuf,eclass,err,line);
1487 } unix_smb_errmap[] =
1489 {EPERM,ERRDOS,ERRnoaccess},
1490 {EACCES,ERRDOS,ERRnoaccess},
1491 {ENOENT,ERRDOS,ERRbadfile},
1492 {EIO,ERRHRD,ERRgeneral},
1493 {EBADF,ERRSRV,ERRsrverror},
1494 {EINVAL,ERRSRV,ERRsrverror},
1495 {EEXIST,ERRDOS,ERRfilexists},
1496 {ENFILE,ERRDOS,ERRnofids},
1497 {EMFILE,ERRDOS,ERRnofids},
1498 {ENOSPC,ERRHRD,ERRdiskfull},
1500 {EDQUOT,ERRHRD,ERRdiskfull},
1503 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1506 {EXDEV,ERRDOS,ERRdiffdevice},
1508 {EROFS,ERRHRD,ERRnowrite},
1513 /****************************************************************************
1514 create an error packet from errno
1515 ****************************************************************************/
1516 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1518 int eclass=def_class;
1522 if (unix_ERR_class != SUCCESS)
1524 eclass = unix_ERR_class;
1525 ecode = unix_ERR_code;
1526 unix_ERR_class = SUCCESS;
1531 while (unix_smb_errmap[i].smbclass != 0)
1533 if (unix_smb_errmap[i].unixerror == errno)
1535 eclass = unix_smb_errmap[i].smbclass;
1536 ecode = unix_smb_errmap[i].smbcode;
1543 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1547 /****************************************************************************
1548 create an error packet. Normally called using the ERROR() macro
1549 ****************************************************************************/
1550 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1552 int outsize = set_message(outbuf,0,0,True);
1554 cmd = CVAL(inbuf,smb_com);
1556 CVAL(outbuf,smb_rcls) = error_class;
1557 SSVAL(outbuf,smb_err,error_code);
1559 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1562 (int)CVAL(inbuf,smb_com),
1563 smb_fn_name(CVAL(inbuf,smb_com)),
1568 DEBUG(3,("error string = %s\n",strerror(errno)));
1574 #ifndef SIGCLD_IGNORE
1575 /****************************************************************************
1576 this prevents zombie child processes
1577 ****************************************************************************/
1578 static int sig_cld()
1580 static int depth = 0;
1583 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1589 BlockSignals(True,SIGCLD);
1590 DEBUG(5,("got SIGCLD\n"));
1593 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1597 /* Stevens, Adv. Unix Prog. says that on system V you must call
1598 wait before reinstalling the signal handler, because the kernel
1599 calls the handler from within the signal-call when there is a
1600 child that has exited. This would lead to an infinite recursion
1601 if done vice versa. */
1603 #ifndef DONT_REINSTALL_SIG
1604 #ifdef SIGCLD_IGNORE
1605 signal(SIGCLD, SIG_IGN);
1607 signal(SIGCLD, SIGNAL_CAST sig_cld);
1612 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1615 BlockSignals(False,SIGCLD);
1620 /****************************************************************************
1621 this is called when the client exits abruptly
1622 **************************************************************************/
1623 static int sig_pipe()
1625 extern int password_client;
1626 BlockSignals(True,SIGPIPE);
1628 if (password_client != -1) {
1629 DEBUG(3,("lost connection to password server\n"));
1630 close(password_client);
1631 password_client = -1;
1632 #ifndef DONT_REINSTALL_SIG
1633 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1635 BlockSignals(False,SIGPIPE);
1639 exit_server("Got sigpipe\n");
1643 /****************************************************************************
1644 open the socket communication
1645 ****************************************************************************/
1646 static BOOL open_sockets(BOOL is_daemon,int port)
1653 struct sockaddr addr;
1654 int in_addrlen = sizeof(addr);
1657 #ifdef SIGCLD_IGNORE
1658 signal(SIGCLD, SIG_IGN);
1660 signal(SIGCLD, SIGNAL_CAST sig_cld);
1663 /* open an incoming socket */
1664 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
1668 /* ready to listen */
1669 if (listen(s, 5) == -1)
1671 DEBUG(0,("listen: %s",strerror(errno)));
1676 /* now accept incoming connections - forking a new process
1677 for each incoming connection */
1678 DEBUG(2,("waiting for a connection\n"));
1681 Client = accept(s,&addr,&in_addrlen);
1683 if (Client == -1 && errno == EINTR)
1688 DEBUG(0,("accept: %s",strerror(errno)));
1692 #ifdef NO_FORK_DEBUG
1693 #ifndef NO_SIGNAL_TEST
1694 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1695 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1699 if (Client != -1 && fork()==0)
1701 #ifndef NO_SIGNAL_TEST
1702 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1703 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
1705 /* close the listening socket */
1708 /* close our standard file descriptors */
1711 set_socket_options(Client,"SO_KEEPALIVE");
1712 set_socket_options(Client,user_socket_options);
1716 close(Client); /* The parent doesn't need this socket */
1722 /* We will abort gracefully when the client or remote system
1724 #ifndef NO_SIGNAL_TEST
1725 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1729 /* close our standard file descriptors */
1732 set_socket_options(Client,"SO_KEEPALIVE");
1733 set_socket_options(Client,user_socket_options);
1740 /****************************************************************************
1741 check if a snum is in use
1742 ****************************************************************************/
1743 BOOL snum_used(int snum)
1746 for (i=0;i<MAX_CONNECTIONS;i++)
1747 if (OPEN_CNUM(i) && (SNUM(i) == snum))
1752 /****************************************************************************
1753 reload the services file
1754 **************************************************************************/
1755 BOOL reload_services(BOOL test)
1762 strcpy(fname,lp_configfile());
1763 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
1765 strcpy(servicesf,fname);
1772 if (test && !lp_file_list_changed())
1775 lp_killunused(snum_used);
1777 ret = lp_load(servicesf,False);
1779 /* perhaps the config filename is now set */
1781 reload_services(True);
1790 set_socket_options(Client,"SO_KEEPALIVE");
1791 set_socket_options(Client,user_socket_options);
1795 create_mangled_stack(lp_mangledstack());
1797 /* this forces service parameters to be flushed */
1798 become_service(-1,True);
1805 /****************************************************************************
1806 this prevents zombie child processes
1807 ****************************************************************************/
1808 static int sig_hup()
1810 BlockSignals(True,SIGHUP);
1811 DEBUG(0,("Got SIGHUP\n"));
1812 reload_services(False);
1813 #ifndef DONT_REINSTALL_SIG
1814 signal(SIGHUP,SIGNAL_CAST sig_hup);
1816 BlockSignals(False,SIGHUP);
1820 /****************************************************************************
1821 Setup the groups a user belongs to.
1822 ****************************************************************************/
1823 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
1824 int **p_igroups, gid_t **p_groups)
1826 if (-1 == initgroups(user,gid))
1830 DEBUG(0,("Unable to initgroups!\n"));
1831 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
1832 DEBUG(0,("This is probably a problem with the account %s\n",user));
1840 ngroups = getgroups(0,&grp);
1843 igroups = (int *)malloc(sizeof(int)*ngroups);
1844 for (i=0;i<ngroups;i++)
1845 igroups[i] = 0x42424242;
1846 ngroups = getgroups(ngroups,(gid_t *)igroups);
1848 if (igroups[0] == 0x42424242)
1851 *p_ngroups = ngroups;
1853 /* The following bit of code is very strange. It is due to the
1854 fact that some OSes use int* and some use gid_t* for
1855 getgroups, and some (like SunOS) use both, one in prototypes,
1856 and one in man pages and the actual code. Thus we detect it
1857 dynamically using some very ugly code */
1860 /* does getgroups return ints or gid_t ?? */
1861 static BOOL groups_use_ints = True;
1863 if (groups_use_ints &&
1865 SVAL(igroups,2) == 0x4242)
1866 groups_use_ints = False;
1868 for (i=0;groups_use_ints && i<ngroups;i++)
1869 if (igroups[i] == 0x42424242)
1870 groups_use_ints = False;
1872 if (groups_use_ints)
1874 *p_igroups = igroups;
1875 *p_groups = (gid_t *)igroups;
1879 gid_t *groups = (gid_t *)igroups;
1880 igroups = (int *)malloc(sizeof(int)*ngroups);
1881 for (i=0;i<ngroups;i++)
1882 igroups[i] = groups[i];
1883 *p_igroups = igroups;
1884 *p_groups = (gid_t *)groups;
1887 DEBUG(3,("%s is in %d groups\n",user,ngroups));
1888 for (i=0;i<ngroups;i++)
1889 DEBUG(3,("%d ",igroups[i]));
1895 /****************************************************************************
1896 make a connection to a service
1897 ****************************************************************************/
1898 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid)
1902 struct passwd *pass = NULL;
1903 connection_struct *pcon;
1906 static BOOL first_connection = True;
1910 snum = find_service(service);
1913 if (strequal(service,"IPC$"))
1915 DEBUG(3,("%s refusing IPC connection\n",timestring()));
1919 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
1923 if (strequal(service,HOMES_NAME))
1925 if (*user && Get_Pwnam(user,True))
1926 return(make_connection(user,user,password,pwlen,dev,vuid));
1928 if (validated_username(vuid))
1930 strcpy(user,validated_username(vuid));
1931 return(make_connection(user,user,password,pwlen,dev,vuid));
1935 if (!lp_snum_ok(snum) || !check_access(snum)) {
1939 /* you can only connect to the IPC$ service as an ipc device */
1940 if (strequal(service,"IPC$"))
1943 if (*dev == '?' || !*dev)
1945 if (lp_print_ok(snum))
1946 strcpy(dev,"LPT1:");
1951 /* if the request is as a printer and you can't print then refuse */
1953 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
1954 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
1958 /* lowercase the user name */
1961 /* add it as a possible user name */
1962 add_session_user(service);
1964 /* shall we let them in? */
1965 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
1967 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
1971 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
1974 DEBUG(0,("%s couldn't find free connection\n",timestring()));
1978 pcon = &Connections[cnum];
1979 bzero((char *)pcon,sizeof(*pcon));
1981 /* find out some info about the user */
1982 pass = Get_Pwnam(user,True);
1986 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
1990 pcon->read_only = lp_readonly(snum);
1994 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
1995 string_sub(list,"%S",service);
1997 if (user_in_list(user,list))
1998 pcon->read_only = True;
2000 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2001 string_sub(list,"%S",service);
2003 if (user_in_list(user,list))
2004 pcon->read_only = False;
2007 /* admin user check */
2008 if (user_in_list(user,lp_admin_users(snum)) &&
2011 pcon->admin_user = True;
2012 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2015 pcon->admin_user = False;
2017 pcon->force_user = force;
2018 pcon->uid = pass->pw_uid;
2019 pcon->gid = pass->pw_gid;
2020 pcon->num_files_open = 0;
2021 pcon->lastused = time(NULL);
2022 pcon->service = snum;
2024 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2025 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2026 pcon->dirptr = NULL;
2027 string_set(&pcon->dirpath,"");
2028 string_set(&pcon->user,user);
2031 if (*lp_force_group(snum))
2033 struct group *gptr = (struct group *)getgrnam(lp_force_group(snum));
2036 pcon->gid = gptr->gr_gid;
2037 DEBUG(3,("Forced group %s\n",lp_force_group(snum)));
2040 DEBUG(1,("Couldn't find group %s\n",lp_force_group(snum)));
2044 if (*lp_force_user(snum))
2046 struct passwd *pass2;
2048 strcpy(fuser,lp_force_user(snum));
2049 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2052 pcon->uid = pass2->pw_uid;
2053 string_set(&pcon->user,fuser);
2055 pcon->force_user = True;
2056 DEBUG(3,("Forced user %s\n",fuser));
2059 DEBUG(1,("Couldn't find user %s\n",fuser));
2064 strcpy(s,lp_pathname(snum));
2065 standard_sub(cnum,s);
2066 string_set(&pcon->connectpath,s);
2067 DEBUG(3,("Connect path is %s\n",s));
2070 /* groups stuff added by ih */
2072 pcon->groups = NULL;
2076 /* Find all the groups this uid is in and store them. Used by become_user() */
2077 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2079 /* check number of connections */
2080 if (!claim_connection(cnum,
2081 lp_servicename(SNUM(cnum)),
2082 lp_max_connections(SNUM(cnum)),False))
2084 DEBUG(1,("too many connections - rejected\n"));
2088 if (lp_status(SNUM(cnum)))
2089 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2091 first_connection = False;
2096 /* execute any "root preexec = " line */
2097 if (*lp_rootpreexec(SNUM(cnum)))
2100 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2101 standard_sub(cnum,cmd);
2102 DEBUG(5,("cmd=%s\n",cmd));
2103 smbrun(cmd,NULL,False);
2106 if (!become_user(cnum,pcon->uid))
2108 DEBUG(0,("Can't become connected user!\n"));
2110 if (!IS_IPC(cnum)) {
2111 yield_connection(cnum,
2112 lp_servicename(SNUM(cnum)),
2113 lp_max_connections(SNUM(cnum)));
2114 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2119 if (ChDir(pcon->connectpath) != 0)
2121 DEBUG(0,("Can't change directory to %s (%s)\n",
2122 pcon->connectpath,strerror(errno)));
2125 if (!IS_IPC(cnum)) {
2126 yield_connection(cnum,
2127 lp_servicename(SNUM(cnum)),
2128 lp_max_connections(SNUM(cnum)));
2129 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2134 string_set(&pcon->origpath,pcon->connectpath);
2136 #if SOFTLINK_OPTIMISATION
2137 /* resolve any soft links early */
2140 strcpy(s,pcon->connectpath);
2142 string_set(&pcon->connectpath,s);
2143 ChDir(pcon->connectpath);
2147 num_connections_open++;
2148 add_session_user(user);
2150 /* execute any "preexec = " line */
2151 if (*lp_preexec(SNUM(cnum)))
2154 strcpy(cmd,lp_preexec(SNUM(cnum)));
2155 standard_sub(cnum,cmd);
2156 smbrun(cmd,NULL,False);
2159 /* we've finished with the sensitive stuff */
2163 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2167 lp_servicename(SNUM(cnum)),user,
2177 /****************************************************************************
2178 find first available file slot
2179 ****************************************************************************/
2180 int find_free_file(void )
2183 /* we start at 1 here for an obscure reason I can't now remember,
2184 but I think is important :-) */
2185 for (i=1;i<MAX_OPEN_FILES;i++)
2188 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2192 /****************************************************************************
2193 find first available connection slot, starting from a random position.
2194 The randomisation stops problems with the server dieing and clients
2195 thinking the server is still available.
2196 ****************************************************************************/
2197 static int find_free_connection(int hash )
2201 hash = (hash % (MAX_CONNECTIONS-2))+1;
2205 for (i=hash+1;i!=hash;)
2207 if (!Connections[i].open && Connections[i].used == used)
2209 DEBUG(3,("found free connection number %d\n",i));
2213 if (i == MAX_CONNECTIONS)
2223 DEBUG(1,("ERROR! Out of connection structures\n"));
2228 /****************************************************************************
2229 reply for the core protocol
2230 ****************************************************************************/
2231 int reply_corep(char *outbuf)
2233 int outsize = set_message(outbuf,1,0,True);
2235 Protocol = PROTOCOL_CORE;
2241 /****************************************************************************
2242 reply for the coreplus protocol
2243 ****************************************************************************/
2244 int reply_coreplus(char *outbuf)
2246 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2247 int outsize = set_message(outbuf,13,0,True);
2248 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2249 readbraw and writebraw (possibly) */
2250 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2251 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2253 Protocol = PROTOCOL_COREPLUS;
2259 /****************************************************************************
2260 reply for the lanman 1.0 protocol
2261 ****************************************************************************/
2262 int reply_lanman1(char *outbuf)
2264 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2266 BOOL doencrypt = SMBENCRYPT();
2267 time_t t = time(NULL);
2269 if (lp_security()>=SEC_USER) secword |= 1;
2270 if (doencrypt) secword |= 2;
2272 set_message(outbuf,13,doencrypt?8:0,True);
2273 SSVAL(outbuf,smb_vwv1,secword);
2275 /* Create a token value and add it to the outgoing packet. */
2277 generate_next_challenge(smb_buf(outbuf));
2280 Protocol = PROTOCOL_LANMAN1;
2282 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2283 DEBUG(3,("using password server validation\n"));
2285 if (doencrypt) set_challenge(smb_buf(outbuf));
2289 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2290 SSVAL(outbuf,smb_vwv2,maxxmit);
2291 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2292 SSVAL(outbuf,smb_vwv4,1);
2293 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2294 readbraw writebraw (possibly) */
2295 SIVAL(outbuf,smb_vwv6,getpid());
2296 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2298 put_dos_date(outbuf,smb_vwv8,t);
2300 return (smb_len(outbuf)+4);
2304 /****************************************************************************
2305 reply for the lanman 2.0 protocol
2306 ****************************************************************************/
2307 int reply_lanman2(char *outbuf)
2309 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2311 BOOL doencrypt = SMBENCRYPT();
2312 time_t t = time(NULL);
2314 if (lp_security()>=SEC_USER) secword |= 1;
2315 if (doencrypt) secword |= 2;
2317 set_message(outbuf,13,doencrypt?8:0,True);
2318 SSVAL(outbuf,smb_vwv1,secword);
2320 /* Create a token value and add it to the outgoing packet. */
2322 generate_next_challenge(smb_buf(outbuf));
2325 SIVAL(outbuf,smb_vwv6,getpid());
2327 Protocol = PROTOCOL_LANMAN2;
2329 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2330 DEBUG(3,("using password server validation\n"));
2332 if (doencrypt) set_challenge(smb_buf(outbuf));
2336 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2337 SSVAL(outbuf,smb_vwv2,maxxmit);
2338 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2339 SSVAL(outbuf,smb_vwv4,1);
2340 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2341 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2342 put_dos_date(outbuf,smb_vwv8,t);
2344 return (smb_len(outbuf)+4);
2347 /****************************************************************************
2348 reply for the nt protocol
2349 ****************************************************************************/
2350 int reply_nt1(char *outbuf)
2352 int capabilities=0x300; /* has dual names + lock_and_read */
2354 BOOL doencrypt = SMBENCRYPT();
2355 time_t t = time(NULL);
2357 if (lp_security()>=SEC_USER) secword |= 1;
2358 if (doencrypt) secword |= 2;
2360 set_message(outbuf,17,doencrypt?8:0,True);
2361 CVAL(outbuf,smb_vwv1) = secword;
2363 /* Create a token value and add it to the outgoing packet. */
2365 generate_next_challenge(smb_buf(outbuf));
2366 /* Tell the nt machine how long the challenge is. */
2367 SSVALS(outbuf,smb_vwv16+1,8);
2371 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2373 Protocol = PROTOCOL_NT1;
2375 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2376 DEBUG(3,("using password server validation\n"));
2378 if (doencrypt) set_challenge(smb_buf(outbuf));
2382 if (lp_readraw() && lp_writeraw())
2385 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2386 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2387 SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
2388 SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
2389 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2390 put_long_date(outbuf+smb_vwv11+1,t);
2391 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2393 return (smb_len(outbuf)+4);
2397 /* these are the protocol lists used for auto architecture detection:
2400 protocol [PC NETWORK PROGRAM 1.0]
2401 protocol [XENIX CORE]
2402 protocol [MICROSOFT NETWORKS 1.03]
2403 protocol [LANMAN1.0]
2404 protocol [Windows for Workgroups 3.1a]
2405 protocol [LM1.2X002]
2406 protocol [LANMAN2.1]
2407 protocol [NT LM 0.12]
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 [LANMAN1.0]
2423 protocol [LM1.2X002]
2424 protocol [LANMAN2.1]
2428 * Modified to recognize the architecture of the remote machine better.
2430 * This appears to be the matrix of which protocol is used by which
2432 Protocol WfWg Win95 WinNT OS/2
2433 PC NETWORK PROGRAM 1.0 1 1 1 1
2435 MICROSOFT NETWORKS 3.0 2 2
2437 MICROSOFT NETWORKS 1.03 3
2440 Windows for Workgroups 3.1a 5 5 5
2445 * tim@fsg.com 09/29/95
2448 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2449 #define ARCH_WIN95 0x2
2450 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2451 #define ARCH_WINNT 0x8
2452 #define ARCH_SAMBA 0x10
2454 #define ARCH_ALL 0x1F
2456 /* List of supported protocols, most desired first */
2460 int (*proto_reply_fn)(char *);
2462 } supported_protocols[] = {
2463 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2464 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2465 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2466 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2467 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2468 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2469 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2470 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2471 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2476 /****************************************************************************
2478 ****************************************************************************/
2479 static int reply_negprot(char *inbuf,char *outbuf)
2481 extern fstring remote_arch;
2482 int outsize = set_message(outbuf,1,0,True);
2487 int bcc = SVAL(smb_buf(inbuf),-2);
2488 int arch = ARCH_ALL;
2490 p = smb_buf(inbuf)+1;
2491 while (p < (smb_buf(inbuf) + bcc))
2494 DEBUG(3,("Requested protocol [%s]\n",p));
2495 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2496 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2497 else if (strcsequal(p,"DOS LM1.2X002"))
2498 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2499 else if (strcsequal(p,"DOS LANMAN2.1"))
2500 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2501 else if (strcsequal(p,"NT LM 0.12"))
2502 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2503 else if (strcsequal(p,"LANMAN2.1"))
2504 arch &= ( ARCH_WINNT | ARCH_OS2 );
2505 else if (strcsequal(p,"LM1.2X002"))
2506 arch &= ( ARCH_WINNT | ARCH_OS2 );
2507 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2509 else if (strcsequal(p,"XENIX CORE"))
2510 arch &= ( ARCH_WINNT | ARCH_OS2 );
2511 else if (strcsequal(p,"Samba")) {
2521 strcpy(remote_arch,"Samba");
2524 strcpy(remote_arch,"WfWg");
2527 strcpy(remote_arch,"Win95");
2530 strcpy(remote_arch,"WinNT");
2533 strcpy(remote_arch,"OS2");
2536 strcpy(remote_arch,"UNKNOWN");
2540 /* possibly reload - change of architecture */
2541 reload_services(True);
2543 /* a special case to stop password server loops */
2544 if (Index == 1 && strequal(remote_machine,myhostname) &&
2545 lp_security()==SEC_SERVER)
2546 exit_server("Password server loop!");
2548 /* Check for protocols, most desirable first */
2549 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2551 p = smb_buf(inbuf)+1;
2553 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2554 while (p < (smb_buf(inbuf) + bcc))
2556 if (strequal(p,supported_protocols[protocol].proto_name))
2565 SSVAL(outbuf,smb_vwv0,choice);
2567 extern fstring remote_proto;
2568 strcpy(remote_proto,supported_protocols[protocol].short_name);
2569 reload_services(True);
2570 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
2571 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
2574 DEBUG(0,("No protocol supported !\n"));
2576 SSVAL(outbuf,smb_vwv0,choice);
2578 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
2584 /****************************************************************************
2585 close all open files for a connection
2586 ****************************************************************************/
2587 static void close_open_files(int cnum)
2590 for (i=0;i<MAX_OPEN_FILES;i++)
2591 if( Files[i].cnum == cnum && Files[i].open) {
2598 /****************************************************************************
2600 ****************************************************************************/
2601 void close_cnum(int cnum, int uid)
2603 DirCacheFlush(SNUM(cnum));
2607 if (!OPEN_CNUM(cnum))
2609 DEBUG(0,("Can't close cnum %d\n",cnum));
2613 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
2615 remote_machine,client_addr(),
2616 lp_servicename(SNUM(cnum))));
2618 yield_connection(cnum,
2619 lp_servicename(SNUM(cnum)),
2620 lp_max_connections(SNUM(cnum)));
2622 if (lp_status(SNUM(cnum)))
2623 yield_connection(cnum,"STATUS.",MAXSTATUS);
2625 close_open_files(cnum);
2626 dptr_closecnum(cnum);
2628 /* execute any "postexec = " line */
2629 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,uid))
2632 strcpy(cmd,lp_postexec(SNUM(cnum)));
2633 standard_sub(cnum,cmd);
2634 smbrun(cmd,NULL,False);
2639 /* execute any "root postexec = " line */
2640 if (*lp_rootpostexec(SNUM(cnum)))
2643 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
2644 standard_sub(cnum,cmd);
2645 smbrun(cmd,NULL,False);
2648 Connections[cnum].open = False;
2649 num_connections_open--;
2650 if (Connections[cnum].ngroups && Connections[cnum].groups)
2652 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
2653 free(Connections[cnum].groups);
2654 free(Connections[cnum].igroups);
2655 Connections[cnum].groups = NULL;
2656 Connections[cnum].igroups = NULL;
2657 Connections[cnum].ngroups = 0;
2660 string_set(&Connections[cnum].user,"");
2661 string_set(&Connections[cnum].dirpath,"");
2662 string_set(&Connections[cnum].connectpath,"");
2666 /****************************************************************************
2667 simple routines to do connection counting
2668 ****************************************************************************/
2669 BOOL yield_connection(int cnum,char *name,int max_connections)
2671 struct connect_record crec;
2674 int mypid = getpid();
2677 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
2679 if (max_connections <= 0)
2682 bzero(&crec,sizeof(crec));
2684 strcpy(fname,lp_lockdir());
2685 standard_sub(cnum,fname);
2686 trim_string(fname,"","/");
2690 strcat(fname,".LCK");
2692 f = fopen(fname,"r+");
2695 DEBUG(2,("Coudn't open lock file %s (%s)\n",fname,strerror(errno)));
2699 fseek(f,0,SEEK_SET);
2701 /* find a free spot */
2702 for (i=0;i<max_connections;i++)
2704 if (fread(&crec,sizeof(crec),1,f) != 1)
2706 DEBUG(2,("Entry not found in lock file %s\n",fname));
2710 if (crec.pid == mypid && crec.cnum == cnum)
2714 if (crec.pid != mypid || crec.cnum != cnum)
2717 DEBUG(2,("Entry not found in lock file %s\n",fname));
2721 bzero((void *)&crec,sizeof(crec));
2723 /* remove our mark */
2724 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2725 fwrite(&crec,sizeof(crec),1,f) != 1)
2727 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
2732 DEBUG(3,("Yield successful\n"));
2739 /****************************************************************************
2740 simple routines to do connection counting
2741 ****************************************************************************/
2742 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
2744 struct connect_record crec;
2747 int snum = SNUM(cnum);
2751 if (max_connections <= 0)
2754 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
2756 strcpy(fname,lp_lockdir());
2757 standard_sub(cnum,fname);
2758 trim_string(fname,"","/");
2760 if (!directory_exist(fname,NULL))
2765 strcat(fname,".LCK");
2767 if (!file_exist(fname,NULL))
2769 int oldmask = umask(022);
2770 f = fopen(fname,"w");
2775 total_recs = file_size(fname) / sizeof(crec);
2777 f = fopen(fname,"r+");
2781 DEBUG(1,("couldn't open lock file %s\n",fname));
2785 /* find a free spot */
2786 for (i=0;i<max_connections;i++)
2789 if (i>=total_recs ||
2790 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
2791 fread(&crec,sizeof(crec),1,f) != 1)
2793 if (foundi < 0) foundi = i;
2797 if (Clear && crec.pid && !process_exists(crec.pid))
2799 fseek(f,i*sizeof(crec),SEEK_SET);
2800 bzero((void *)&crec,sizeof(crec));
2801 fwrite(&crec,sizeof(crec),1,f);
2802 if (foundi < 0) foundi = i;
2805 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
2814 DEBUG(3,("no free locks in %s\n",fname));
2819 /* fill in the crec */
2820 bzero((void *)&crec,sizeof(crec));
2821 crec.magic = 0x280267;
2822 crec.pid = getpid();
2824 crec.uid = Connections[cnum].uid;
2825 crec.gid = Connections[cnum].gid;
2826 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
2827 crec.start = time(NULL);
2829 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
2830 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
2833 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
2834 fwrite(&crec,sizeof(crec),1,f) != 1)
2845 /*******************************************************************
2846 prepare to dump a core file - carefully!
2847 ********************************************************************/
2848 static BOOL dump_core(void)
2852 strcpy(dname,debugf);
2853 if ((p=strrchr(dname,'/'))) *p=0;
2854 strcat(dname,"/corefiles");
2856 sys_chown(dname,getuid(),getgid());
2858 if (chdir(dname)) return(False);
2861 #ifndef NO_GETRLIMIT
2865 getrlimit(RLIMIT_CORE, &rlp);
2866 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
2867 setrlimit(RLIMIT_CORE, &rlp);
2868 getrlimit(RLIMIT_CORE, &rlp);
2869 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
2875 DEBUG(0,("Dumping core in %s\n",dname));
2880 /****************************************************************************
2882 ****************************************************************************/
2883 void exit_server(char *reason)
2885 static int firsttime=1;
2888 if (!firsttime) exit(0);
2892 DEBUG(2,("Closing connections\n"));
2893 for (i=0;i<MAX_CONNECTIONS;i++)
2894 if (Connections[i].open)
2897 if (dcelogin_atmost_once)
2901 int oldlevel = DEBUGLEVEL;
2903 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
2905 show_msg(last_inbuf);
2906 DEBUGLEVEL = oldlevel;
2907 DEBUG(0,("===============================================================\n"));
2909 if (dump_core()) return;
2912 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
2916 /****************************************************************************
2917 do some standard substitutions in a string
2918 ****************************************************************************/
2919 void standard_sub(int cnum,char *s)
2921 if (!strchr(s,'%')) return;
2923 if (VALID_CNUM(cnum))
2925 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
2926 string_sub(s,"%P",Connections[cnum].connectpath);
2927 string_sub(s,"%u",Connections[cnum].user);
2928 if (strstr(s,"%H")) {
2929 char *home = get_home_dir(Connections[cnum].user);
2930 if (home) string_sub(s,"%H",home);
2932 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
2934 standard_sub_basic(s);
2938 These flags determine some of the permissions required to do an operation
2940 Note that I don't set NEED_WRITE on some write operations because they
2941 are used by some brain-dead clients when printing, and I don't want to
2942 force write permissions on print services.
2944 #define AS_USER (1<<0)
2945 #define NEED_WRITE (1<<1)
2946 #define TIME_INIT (1<<2)
2947 #define CAN_IPC (1<<3)
2948 #define AS_GUEST (1<<5)
2952 define a list of possible SMB messages and their corresponding
2953 functions. Any message that has a NULL function is unimplemented -
2954 please feel free to contribute implementations!
2956 struct smb_message_struct
2970 {SMBnegprot,"SMBnegprot",reply_negprot,0},
2971 {SMBtcon,"SMBtcon",reply_tcon,0},
2972 {SMBtdis,"SMBtdis",reply_tdis,0},
2973 {SMBexit,"SMBexit",reply_exit,0},
2974 {SMBioctl,"SMBioctl",reply_ioctl,0},
2975 {SMBecho,"SMBecho",reply_echo,0},
2976 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
2977 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
2978 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
2979 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
2980 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
2981 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
2982 {SMBsearch,"SMBsearch",reply_search,AS_USER},
2983 {SMBopen,"SMBopen",reply_open,AS_USER},
2985 /* note that SMBmknew and SMBcreate are deliberately overloaded */
2986 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
2987 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
2989 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
2990 {SMBread,"SMBread",reply_read,AS_USER},
2991 {SMBwrite,"SMBwrite",reply_write,AS_USER},
2992 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
2993 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
2994 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
2995 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
2996 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
2998 /* this is a Pathworks specific call, allowing the
2999 changing of the root path */
3000 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3002 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3003 {SMBflush,"SMBflush",reply_flush,AS_USER},
3004 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3005 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3006 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3007 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3008 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3009 {SMBlock,"SMBlock",reply_lock,AS_USER},
3010 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3012 /* CORE+ PROTOCOL FOLLOWS */
3014 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3015 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3016 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3017 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3018 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3020 /* LANMAN1.0 PROTOCOL FOLLOWS */
3022 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3023 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3024 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3025 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3026 {SMBwritec,"SMBwritec",NULL,AS_USER},
3027 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3028 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3029 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3030 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3031 {SMBioctls,"SMBioctls",NULL,AS_USER},
3032 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3033 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3035 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3036 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3037 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3038 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3040 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3041 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3042 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3044 /* LANMAN2.0 PROTOCOL FOLLOWS */
3045 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3046 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3047 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3048 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3050 /* messaging routines */
3051 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3052 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3053 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3054 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3056 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3058 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3059 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3060 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3061 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3064 /****************************************************************************
3065 return a string containing the function name of a SMB command
3066 ****************************************************************************/
3067 char *smb_fn_name(int type)
3069 static char *unknown_name = "SMBunknown";
3070 static int num_smb_messages =
3071 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3074 for (match=0;match<num_smb_messages;match++)
3075 if (smb_messages[match].code == type)
3078 if (match == num_smb_messages)
3079 return(unknown_name);
3081 return(smb_messages[match].name);
3085 /****************************************************************************
3086 do a switch on the message type, and return the response size
3087 ****************************************************************************/
3088 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3092 static int num_smb_messages =
3093 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3097 struct timeval msg_start_time;
3098 struct timeval msg_end_time;
3099 static unsigned long total_time = 0;
3101 GetTimeOfDay(&msg_start_time);
3108 last_message = type;
3110 /* make sure this is an SMB packet */
3111 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3113 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3117 for (match=0;match<num_smb_messages;match++)
3118 if (smb_messages[match].code == type)
3121 if (match == num_smb_messages)
3123 DEBUG(0,("Unknown message type %d!\n",type));
3124 outsize = reply_unknown(inbuf,outbuf);
3128 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3129 if (smb_messages[match].fn)
3131 int cnum = SVAL(inbuf,smb_tid);
3132 int flags = smb_messages[match].flags;
3133 int uid = SVAL(inbuf,smb_uid);
3135 /* does this protocol need to be run as root? */
3136 if (!(flags & AS_USER))
3139 /* does this protocol need to be run as the connected user? */
3140 if ((flags & AS_USER) && !become_user(cnum,uid)) {
3141 if (flags & AS_GUEST)
3144 return(ERROR(ERRSRV,ERRinvnid));
3146 /* this code is to work around a bug is MS client 3 without
3147 introducing a security hole - it needs to be able to do
3148 print queue checks as guest if it isn't logged in properly */
3149 if (flags & AS_USER)
3152 /* does it need write permission? */
3153 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3154 return(ERROR(ERRSRV,ERRaccess));
3156 /* ipc services are limited */
3157 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3158 return(ERROR(ERRSRV,ERRaccess));
3160 /* load service specific parameters */
3161 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3162 return(ERROR(ERRSRV,ERRaccess));
3164 /* does this protocol need to be run as guest? */
3165 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3166 return(ERROR(ERRSRV,ERRaccess));
3170 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3174 outsize = reply_unknown(inbuf,outbuf);
3179 GetTimeOfDay(&msg_end_time);
3180 if (!(smb_messages[match].flags & TIME_INIT))
3182 smb_messages[match].time = 0;
3183 smb_messages[match].flags |= TIME_INIT;
3186 unsigned long this_time =
3187 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3188 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3189 smb_messages[match].time += this_time;
3190 total_time += this_time;
3192 DEBUG(2,("TIME %s %d usecs %g pct\n",
3193 smb_fn_name(type),smb_messages[match].time,
3194 (100.0*smb_messages[match].time) / total_time));
3201 /****************************************************************************
3202 construct a chained reply and add it to the already made reply
3203 **************************************************************************/
3204 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3206 static char *orig_inbuf;
3207 static char *orig_outbuf;
3208 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3209 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3210 char *inbuf2, *outbuf2;
3212 char inbuf_saved[smb_wct];
3213 char outbuf_saved[smb_wct];
3214 extern int chain_size;
3215 int wct = CVAL(outbuf,smb_wct);
3216 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3218 /* maybe its not chained */
3219 if (smb_com2 == 0xFF) {
3220 CVAL(outbuf,smb_vwv0) = 0xFF;
3224 if (chain_size == 0) {
3225 /* this is the first part of the chain */
3227 orig_outbuf = outbuf;
3230 /* we need to tell the client where the next part of the reply will be */
3231 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3232 CVAL(outbuf,smb_vwv0) = smb_com2;
3234 /* remember how much the caller added to the chain, only counting stuff
3235 after the parameter words */
3236 chain_size += outsize - smb_wct;
3238 /* work out pointers into the original packets. The
3239 headers on these need to be filled in */
3240 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3241 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3243 /* remember the original command type */
3244 smb_com1 = CVAL(orig_inbuf,smb_com);
3246 /* save the data which will be overwritten by the new headers */
3247 memcpy(inbuf_saved,inbuf2,smb_wct);
3248 memcpy(outbuf_saved,outbuf2,smb_wct);
3250 /* give the new packet the same header as the last part of the SMB */
3251 memmove(inbuf2,inbuf,smb_wct);
3253 /* create the in buffer */
3254 CVAL(inbuf2,smb_com) = smb_com2;
3256 /* create the out buffer */
3257 bzero(outbuf2,smb_size);
3258 set_message(outbuf2,0,0,True);
3259 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3261 memcpy(outbuf2+4,inbuf2+4,4);
3262 CVAL(outbuf2,smb_rcls) = SUCCESS;
3263 CVAL(outbuf2,smb_reh) = 0;
3264 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3266 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3267 SSVAL(outbuf2,smb_err,SUCCESS);
3268 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3269 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3270 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3271 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3273 DEBUG(3,("Chained message\n"));
3276 /* process the request */
3277 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3278 bufsize-chain_size);
3280 /* copy the new reply and request headers over the old ones, but
3281 preserve the smb_com field */
3282 memmove(orig_outbuf,outbuf2,smb_wct);
3283 CVAL(orig_outbuf,smb_com) = smb_com1;
3285 /* restore the saved data, being careful not to overwrite any
3286 data from the reply header */
3287 memcpy(inbuf2,inbuf_saved,smb_wct);
3289 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3290 if (ofs < 0) ofs = 0;
3291 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3299 /****************************************************************************
3300 construct a reply to the incoming packet
3301 ****************************************************************************/
3302 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3304 int type = CVAL(inbuf,smb_com);
3306 int msg_type = CVAL(inbuf,0);
3307 extern int chain_size;
3309 smb_last_time = time(NULL);
3314 bzero(outbuf,smb_size);
3317 return(reply_special(inbuf,outbuf));
3319 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3320 set_message(outbuf,0,0,True);
3322 memcpy(outbuf+4,inbuf+4,4);
3323 CVAL(outbuf,smb_rcls) = SUCCESS;
3324 CVAL(outbuf,smb_reh) = 0;
3325 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3327 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3328 SSVAL(outbuf,smb_err,SUCCESS);
3329 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3330 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3331 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3332 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3334 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3336 outsize += chain_size;
3339 smb_setlen(outbuf,outsize - 4);
3344 /****************************************************************************
3345 process commands from the client
3346 ****************************************************************************/
3347 static void process(void)
3349 static int trans_num = 0;
3353 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3354 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3355 if ((InBuffer == NULL) || (OutBuffer == NULL))
3358 InBuffer += SMB_ALIGNMENT;
3359 OutBuffer += SMB_ALIGNMENT;
3362 DEBUG(3,("priming nmbd\n"));
3365 ip = *interpret_addr2("localhost");
3366 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3368 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3378 int deadtime = lp_deadtime()*60;
3380 int last_keepalive=0;
3383 deadtime = DEFAULT_SMBD_TIMEOUT;
3385 if (lp_readprediction())
3386 do_read_prediction();
3389 extern pstring share_del_pending;
3390 if (*share_del_pending) {
3392 if (!unlink(share_del_pending))
3393 DEBUG(3,("Share file deleted %s\n",share_del_pending));
3395 DEBUG(2,("Share del failed of %s\n",share_del_pending));
3396 share_del_pending[0] = 0;
3400 if (share_mode_pending) {
3402 check_share_modes();
3403 share_mode_pending=False;
3408 for (counter=SMBD_SELECT_LOOP;
3409 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3410 counter += SMBD_SELECT_LOOP)
3414 BOOL allidle = True;
3415 extern int keepalive;
3417 if (smb_read_error == READ_EOF) {
3418 DEBUG(3,("end of file from client\n"));
3422 if (smb_read_error == READ_ERROR) {
3423 DEBUG(3,("receive_smb error (%s) exiting\n",
3430 /* become root again if waiting */
3433 /* check for smb.conf reload */
3434 if (!(counter%SMBD_RELOAD_CHECK))
3435 reload_services(True);
3437 /* check the share modes every 10 secs */
3438 if (!(counter%SHARE_MODES_CHECK))
3439 check_share_modes();
3441 /* clean the share modes every 5 minutes */
3442 if (!(counter%SHARE_MODES_CLEAN))
3443 clean_share_modes();
3445 /* automatic timeout if all connections are closed */
3446 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3447 DEBUG(2,("%s Closing idle connection\n",timestring()));
3451 if (keepalive && (counter-last_keepalive)>keepalive) {
3452 extern int password_client;
3453 if (!send_keepalive(Client)) {
3454 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3457 /* also send a keepalive to the password server if its still
3459 if (password_client != -1)
3460 send_keepalive(password_client);
3461 last_keepalive = counter;
3464 /* check for connection timeouts */
3465 for (i=0;i<MAX_CONNECTIONS;i++)
3466 if (Connections[i].open)
3468 /* close dirptrs on connections that are idle */
3469 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3472 if (Connections[i].num_files_open > 0 ||
3473 (t-Connections[i].lastused)<deadtime)
3477 if (allidle && num_connections_open>0) {
3478 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3483 msg_type = CVAL(InBuffer,0);
3484 msg_flags = CVAL(InBuffer,1);
3485 type = CVAL(InBuffer,smb_com);
3487 len = smb_len(InBuffer);
3489 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3493 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3496 if(trans_num == 1 && VT_Check(InBuffer)) {
3506 nread = construct_reply(InBuffer,OutBuffer,nread,maxxmit);
3509 if (CVAL(OutBuffer,0) == 0)
3510 show_msg(OutBuffer);
3512 if (nread != smb_len(OutBuffer) + 4)
3514 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3516 smb_len(OutBuffer)));
3519 send_smb(Client,OutBuffer);
3526 /****************************************************************************
3527 initialise connect, service and file structs
3528 ****************************************************************************/
3529 static void init_structs(void )
3532 get_myname(myhostname,NULL);
3534 for (i=0;i<MAX_CONNECTIONS;i++)
3536 Connections[i].open = False;
3537 Connections[i].num_files_open=0;
3538 Connections[i].lastused=0;
3539 Connections[i].used=False;
3540 string_init(&Connections[i].user,"");
3541 string_init(&Connections[i].dirpath,"");
3542 string_init(&Connections[i].connectpath,"");
3543 string_init(&Connections[i].origpath,"");
3546 for (i=0;i<MAX_OPEN_FILES;i++)
3548 Files[i].open = False;
3549 string_init(&Files[i].name,"");
3555 /****************************************************************************
3556 usage on the program
3557 ****************************************************************************/
3558 static void usage(char *pname)
3560 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3562 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3563 printf("Version %s\n",VERSION);
3564 printf("\t-D become a daemon\n");
3565 printf("\t-p port listen on the specified port\n");
3566 printf("\t-d debuglevel set the debuglevel\n");
3567 printf("\t-l log basename. Basename for log/debug files\n");
3568 printf("\t-s services file. Filename of services file\n");
3569 printf("\t-P passive only\n");
3570 printf("\t-a overwrite log file, don't append\n");
3575 /****************************************************************************
3577 ****************************************************************************/
3578 int main(int argc,char *argv[])
3580 extern BOOL append_log;
3581 /* shall I run as a daemon */
3582 BOOL is_daemon = False;
3583 int port = SMB_PORT;
3585 extern char *optarg;
3587 #ifdef NEED_AUTH_PARAMETERS
3588 set_auth_parameters(argc,argv);
3599 strcpy(debugf,SMBLOGFILE);
3601 setup_logging(argv[0],False);
3603 charset_initialise();
3605 /* make absolutely sure we run as root - to handle cases whre people
3606 are crazy enough to have it setuid */
3616 fault_setup(exit_server);
3618 /* we want total control over the permissions on created files,
3619 so set our umask to 0 */
3626 /* this is for people who can't start the program correctly */
3627 while (argc > 1 && (*argv[1] != '-'))
3633 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPa")) != EOF)
3637 strcpy(user_socket_options,optarg);
3640 strcpy(scope,optarg);
3644 extern BOOL passive;
3649 strcpy(servicesf,optarg);
3652 strcpy(debugf,optarg);
3656 extern BOOL append_log;
3657 append_log = !append_log;
3667 DEBUGLEVEL = atoi(optarg);
3670 port = atoi(optarg);
3683 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
3684 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
3686 #ifndef NO_GETRLIMIT
3687 #ifdef RLIMIT_NOFILE
3690 getrlimit(RLIMIT_NOFILE, &rlp);
3691 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
3692 setrlimit(RLIMIT_NOFILE, &rlp);
3693 getrlimit(RLIMIT_NOFILE, &rlp);
3694 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
3700 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
3701 getuid(),getgid(),geteuid(),getegid()));
3703 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
3705 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
3711 if (!reload_services(False))
3714 #ifndef NO_SIGNAL_TEST
3715 signal(SIGHUP,SIGNAL_CAST sig_hup);
3718 DEBUG(3,("%s loaded services\n",timestring()));
3720 if (!is_daemon && !is_a_socket(0))
3722 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
3728 DEBUG(3,("%s becoming a daemon\n",timestring()));
3732 if (!open_sockets(is_daemon,port))
3735 #if FAST_SHARE_MODES
3736 if (!start_share_mode_mgmt())
3740 /* possibly reload the services file. */
3741 reload_services(True);
3743 maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
3747 if (sys_chroot(lp_rootdir()) == 0)
3748 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
3754 #if FAST_SHARE_MODES
3755 stop_share_mode_mgmt();
3758 exit_server("normal exit");