2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
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;
28 extern fstring myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 extern time_t smb_last_time;
53 extern int smb_read_error;
55 extern pstring user_socket_options;
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
70 * Size of data we can send to client. Set
71 * by the client for all protocols above CORE.
72 * Set by us for CORE protocol.
74 int max_send = BUFFER_SIZE;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv = BUFFER_SIZE;
81 /* a fnum to use when chaining */
84 /* number of open connections */
85 static int num_connections_open = 0;
88 /* Oplock ipc UDP socket. */
90 uint16 oplock_port = 0;
91 #endif /* USE_OPLOCKS */
93 extern fstring remote_machine;
97 /* these can be set by some functions to override the error codes */
98 int unix_ERR_class=SUCCESS;
102 extern int extra_time_offset;
104 extern pstring myhostname;
106 static int find_free_connection(int hash);
108 /* for readability... */
109 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
110 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
111 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
112 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
113 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
115 /****************************************************************************
116 when exiting, take the whole family
117 ****************************************************************************/
120 exit_server("caught signal");
121 return 0; /* Keep -Wall happy :-) */
123 /****************************************************************************
124 Send a SIGTERM to our process group.
125 *****************************************************************************/
128 if(am_parent) kill(0,SIGTERM);
131 /****************************************************************************
132 change a dos mode to a unix mode
133 base permission for files:
134 everybody gets read bit set
135 dos readonly is represented in unix by removing everyone's write bit
136 dos archive is represented in unix by the user's execute bit
137 dos system is represented in unix by the group's execute bit
138 dos hidden is represented in unix by the other's execute bit
139 Then apply create mask,
141 base permission for directories:
142 dos directory is represented in unix by unix's dir bit and the exec bit
143 Then apply create mask,
145 ****************************************************************************/
146 mode_t unix_mode(int cnum,int dosmode)
148 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
150 if ( !IS_DOS_READONLY(dosmode) )
151 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
153 if (IS_DOS_DIR(dosmode)) {
154 /* We never make directories read only for the owner as under DOS a user
155 can always create a file in a read-only directory. */
156 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
157 /* Apply directory mask */
158 result &= lp_dir_mode(SNUM(cnum));
159 /* Add in force bits */
160 result |= lp_force_dir_mode(SNUM(cnum));
162 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
165 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
168 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
171 /* Apply mode mask */
172 result &= lp_create_mode(SNUM(cnum));
173 /* Add in force bits */
174 result |= lp_force_create_mode(SNUM(cnum));
180 /****************************************************************************
181 change a unix mode to a dos mode
182 ****************************************************************************/
183 int dos_mode(int cnum,char *path,struct stat *sbuf)
186 extern struct current_user current_user;
188 DEBUG(5,("dos_mode: %d %s\n", cnum, path));
190 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
191 if (!((sbuf->st_mode & S_IWOTH) ||
192 Connections[cnum].admin_user ||
193 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
194 ((sbuf->st_mode & S_IWGRP) &&
195 in_group(sbuf->st_gid,current_user.gid,
196 current_user.ngroups,current_user.igroups))))
199 if ((sbuf->st_mode & S_IWUSR) == 0)
203 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
206 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
209 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
212 if (S_ISDIR(sbuf->st_mode))
213 result = aDIR | (result & aRONLY);
216 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
220 /* hide files with a name starting with a . */
221 if (lp_hide_dot_files(SNUM(cnum)))
223 char *p = strrchr(path,'/');
229 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
233 /* Optimization : Only call is_hidden_path if it's not already
235 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
240 DEBUG(5,("dos_mode returning "));
242 if (result & aHIDDEN) DEBUG(5, ("h"));
243 if (result & aRONLY ) DEBUG(5, ("r"));
244 if (result & aSYSTEM) DEBUG(5, ("s"));
245 if (result & aDIR ) DEBUG(5, ("d"));
246 if (result & aARCH ) DEBUG(5, ("a"));
254 /*******************************************************************
255 chmod a file - but preserve some bits
256 ********************************************************************/
257 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
266 if (sys_stat(fname,st)) return(-1);
269 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
271 if (dos_mode(cnum,fname,st) == dosmode) return(0);
273 unixmode = unix_mode(cnum,dosmode);
275 /* preserve the s bits */
276 mask |= (S_ISUID | S_ISGID);
278 /* preserve the t bit */
283 /* possibly preserve the x bits */
284 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
285 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
286 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
288 unixmode |= (st->st_mode & mask);
290 /* if we previously had any r bits set then leave them alone */
291 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
292 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
296 /* if we previously had any w bits set then leave them alone
297 if the new mode is not rdonly */
298 if (!IS_DOS_READONLY(dosmode) &&
299 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
300 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
304 return(sys_chmod(fname,unixmode));
308 /****************************************************************************
309 check if two filenames are equal
311 this needs to be careful about whether we are case sensitive
312 ****************************************************************************/
313 static BOOL fname_equal(char *name1, char *name2)
315 int l1 = strlen(name1);
316 int l2 = strlen(name2);
318 /* handle filenames ending in a single dot */
319 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
323 ret = fname_equal(name1,name2);
328 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
332 ret = fname_equal(name1,name2);
337 /* now normal filename handling */
339 return(strcmp(name1,name2) == 0);
341 return(strequal(name1,name2));
345 /****************************************************************************
346 mangle the 2nd name and check if it is then equal to the first name
347 ****************************************************************************/
348 static BOOL mangled_equal(char *name1, char *name2)
352 if (is_8_3(name2, True))
355 strcpy(tmpname,name2);
356 mangle_name_83(tmpname);
358 return(strequal(name1,tmpname));
362 /****************************************************************************
363 scan a directory to find a filename, matching without case sensitivity
365 If the name looks like a mangled name then try via the mangling functions
366 ****************************************************************************/
367 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
374 mangled = is_mangled(name);
376 /* handle null paths */
380 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
386 check_mangled_stack(name);
388 /* open the directory */
389 if (!(cur_dir = OpenDir(cnum, path, True)))
391 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
395 /* now scan for matching names */
396 while ((dname = ReadDirName(cur_dir)))
399 (strequal(dname,".") || strequal(dname,"..")))
403 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
405 if ((mangled && mangled_equal(name,name2))
406 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
408 /* we've found the file, change it's name and return */
409 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
420 /****************************************************************************
421 This routine is called to convert names from the dos namespace to unix
422 namespace. It needs to handle any case conversions, mangling, format
425 We assume that we have already done a chdir() to the right "root" directory
428 The function will return False if some part of the name except for the last
429 part cannot be resolved
431 If the saved_last_component != 0, then the unmodified last component
432 of the pathname is returned there. This is used in an exceptional
433 case in reply_mv (so far). If saved_last_component == 0 then nothing
436 The bad_path arg is set to True if the filename walk failed. This is
437 used to pick the correct error code to return between ENOENT and ENOTDIR
438 as Windows applications depend on ERRbadpath being returned if a component
439 of a pathname does not exist.
440 ****************************************************************************/
441 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
451 if(saved_last_component)
452 *saved_last_component = 0;
454 /* convert to basic unix format - removing \ chars and cleaning it up */
456 unix_clean_name(name);
458 /* names must be relative to the root of the service - trim any leading /.
459 also trim trailing /'s */
460 trim_string(name,"/","/");
463 * Ensure saved_last_component is valid even if file exists.
465 if(saved_last_component) {
466 end = strrchr(name, '/');
468 strcpy(saved_last_component, end + 1);
470 strcpy(saved_last_component, name);
473 if (!case_sensitive &&
474 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
477 /* check if it's a printer file */
478 if (Connections[cnum].printer)
480 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
484 sprintf(name2,"%.6s.XXXXXX",remote_machine);
485 /* sanitise the name */
486 for (s=name2 ; *s ; s++)
487 if (!issafe(*s)) *s = '_';
488 strcpy(name,(char *)mktemp(name2));
493 /* stat the name - if it exists then we are all done! */
494 if (sys_stat(name,&st) == 0)
499 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
501 /* a special case - if we don't have any mangling chars and are case
502 sensitive then searching won't help */
503 if (case_sensitive && !is_mangled(name) &&
504 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
507 /* now we need to recursively match the name against the real
508 directory structure */
511 while (strncmp(start,"./",2) == 0)
514 /* now match each part of the path name separately, trying the names
515 as is first, then trying to scan the directory for matching names */
516 for (;start;start = (end?end+1:(char *)NULL))
518 /* pinpoint the end of this section of the filename */
519 end = strchr(start, '/');
521 /* chop the name at this point */
524 if(saved_last_component != 0)
525 strcpy(saved_last_component, end ? end + 1 : start);
527 /* check if the name exists up to this point */
528 if (sys_stat(name, &st) == 0)
530 /* it exists. it must either be a directory or this must be
531 the last part of the path for it to be OK */
532 if (end && !(st.st_mode & S_IFDIR))
534 /* an intermediate part of the name isn't a directory */
535 DEBUG(5,("Not a dir %s\n",start));
546 /* remember the rest of the pathname so it can be restored
548 if (end) strcpy(rest,end+1);
550 /* try to find this part of the path in the directory */
551 if (strchr(start,'?') || strchr(start,'*') ||
552 !scan_directory(dirpath, start, cnum, end?True:False))
556 /* an intermediate part of the name can't be found */
557 DEBUG(5,("Intermediate not found %s\n",start));
559 /* We need to return the fact that the intermediate
560 name resolution failed. This is used to return an
561 error of ERRbadpath rather than ERRbadfile. Some
562 Windows applications depend on the difference between
569 /* just the last part of the name doesn't exist */
570 /* we may need to strupper() or strlower() it in case
571 this conversion is being used for file creation
573 /* if the filename is of mixed case then don't normalise it */
574 if (!case_preserve &&
575 (!strhasupper(start) || !strhaslower(start)))
578 /* check on the mangled stack to see if we can recover the
579 base of the filename */
580 if (is_mangled(start))
581 check_mangled_stack(start);
583 DEBUG(5,("New file %s\n",start));
587 /* restore the rest of the string */
590 strcpy(start+strlen(start)+1,rest);
591 end = start + strlen(start);
595 /* add to the dirpath that we have resolved so far */
596 if (*dirpath) strcat(dirpath,"/");
597 strcat(dirpath,start);
599 /* restore the / that we wiped out earlier */
603 /* the name has been resolved */
604 DEBUG(5,("conversion finished %s\n",name));
609 /****************************************************************************
610 normalise for DOS usage
611 ****************************************************************************/
612 static void disk_norm(int *bsize,int *dfree,int *dsize)
614 /* check if the disk is beyond the max disk size */
615 int maxdisksize = lp_maxdisksize();
617 /* convert to blocks - and don't overflow */
618 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
619 if (*dsize > maxdisksize) *dsize = maxdisksize;
620 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
625 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
630 if (*bsize > WORDMAX )
633 if (*dsize > WORDMAX)
635 if (*dfree > WORDMAX)
642 /****************************************************************************
643 return number of 1K blocks available on a path and total number
644 ****************************************************************************/
645 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
647 char *df_command = lp_dfree_command();
668 /* possibly use system() to get the result */
669 if (df_command && *df_command)
675 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
676 sprintf(syscmd,"%s %s",df_command,path);
677 standard_sub_basic(syscmd);
679 ret = smbrun(syscmd,outfile,False);
680 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
683 FILE *f = fopen(outfile,"r");
689 fscanf(f,"%d %d %d",dsize,dfree,bsize);
693 DEBUG(0,("Can't open %s\n",outfile));
697 disk_norm(bsize,dfree,dsize);
698 dfree_retval = ((*bsize)/1024)*(*dfree);
700 /* Ensure we return the min value between the users quota and
701 what's free on the disk. Thanks to Albrecht Gebhardt
702 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
704 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
706 disk_norm(&bsizeq, &dfreeq, &dsizeq);
707 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
708 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
709 dfree_retval : dfreeq_retval ;
710 /* maybe dfree and dfreeq are calculated using different bsizes
711 so convert dfree from bsize into bsizeq */
712 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
713 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
718 return(dfree_retval);
722 DEBUG(1,("Warning - no statfs function\n"));
726 if (statfs(path,&fs,sizeof(fs),0) != 0)
729 if (statvfs(path, &fs))
732 if (statfs(path,&fs,sizeof(fs)) == -1)
734 if (statfs(path,&fs) == -1)
736 #endif /* USE_STATVFS */
739 DEBUG(3,("dfree call failed code errno=%d\n",errno));
743 return(((*bsize)/1024)*(*dfree));
748 *dfree = fs.fd_req.bfree;
749 *dsize = fs.fd_req.btot;
752 *bsize = fs.f_frsize;
755 /* eg: osf1 has f_fsize = fundamental filesystem block size,
756 f_bsize = optimal transfer block size (MX: 94-04-19) */
761 #endif /* USE_STATVFS */
766 *dfree = fs.f_bavail;
768 *dsize = fs.f_blocks;
771 #if defined(SCO) || defined(ISC) || defined(MIPS)
775 /* handle rediculous bsize values - some OSes are broken */
776 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
778 disk_norm(bsize,dfree,dsize);
784 DEBUG(0,("dfree seems to be broken on your system\n"));
785 *dsize = 20*1024*1024/(*bsize);
786 *dfree = MAX(1,*dfree);
788 dfree_retval = ((*bsize)/1024)*(*dfree);
790 /* Ensure we return the min value between the users quota and
791 what's free on the disk. Thanks to Albrecht Gebhardt
792 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
794 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
796 disk_norm(&bsizeq, &dfreeq, &dsizeq);
797 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
798 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
799 dfree_retval : dfreeq_retval ;
800 /* maybe dfree and dfreeq are calculated using different bsizes
801 so convert dfree from bsize into bsizeq */
802 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
803 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
808 return(dfree_retval);
813 /****************************************************************************
814 wrap it to get filenames right
815 ****************************************************************************/
816 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
818 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
823 /****************************************************************************
824 check a filename - possibly caling reducename
826 This is called by every routine before it allows an operation on a filename.
827 It does any final confirmation necessary to ensure that the filename is
828 a valid one for the user to access.
829 ****************************************************************************/
830 BOOL check_name(char *name,int cnum)
836 if( IS_VETO_PATH(cnum, name))
838 DEBUG(5,("file path name %s vetoed\n",name));
842 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
844 /* Check if we are allowing users to follow symlinks */
845 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
846 University of Geneva */
848 if (!lp_symlinks(SNUM(cnum)))
851 if ( (sys_lstat(name,&statbuf) != -1) &&
852 (S_ISLNK(statbuf.st_mode)) )
854 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
860 DEBUG(5,("check_name on %s failed\n",name));
865 /****************************************************************************
866 check a filename - possibly caling reducename
867 ****************************************************************************/
868 static void check_for_pipe(char *fname)
870 /* special case of pipe opens */
874 if (strstr(s,"pipe/"))
876 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
877 unix_ERR_class = ERRSRV;
878 unix_ERR_code = ERRaccess;
882 /****************************************************************************
883 fd support routines - attempt to do a sys_open
884 ****************************************************************************/
886 int fd_attempt_open(char *fname, int flags, int mode)
888 int fd = sys_open(fname,flags,mode);
890 /* Fix for files ending in '.' */
891 if((fd == -1) && (errno == ENOENT) &&
892 (strchr(fname,'.')==NULL))
895 fd = sys_open(fname,flags,mode);
898 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
899 if ((fd == -1) && (errno == ENAMETOOLONG))
902 char *p = strrchr(fname, '/');
904 if (p == fname) /* name is "/xxx" */
906 max_len = pathconf("/", _PC_NAME_MAX);
909 else if ((p == NULL) || (p == fname))
912 max_len = pathconf(".", _PC_NAME_MAX);
917 max_len = pathconf(fname, _PC_NAME_MAX);
921 if (strlen(p) > max_len)
923 char tmp = p[max_len];
926 if ((fd = sys_open(fname,flags,mode)) == -1)
934 /****************************************************************************
935 fd support routines - attempt to find an already open file by dev
936 and inode - increments the ref_count of the returned file_fd_struct *.
937 ****************************************************************************/
938 file_fd_struct *fd_get_already_open(struct stat *sbuf)
941 file_fd_struct *fd_ptr;
946 for(i = 0; i <= max_file_fd_used; i++) {
948 if((fd_ptr->ref_count > 0) &&
949 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
950 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
953 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
954 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
961 /****************************************************************************
962 fd support routines - attempt to find a empty slot in the FileFd array.
963 Increments the ref_count of the returned entry.
964 ****************************************************************************/
965 file_fd_struct *fd_get_new()
968 file_fd_struct *fd_ptr;
970 for(i = 0; i < MAX_OPEN_FILES; i++) {
972 if(fd_ptr->ref_count == 0) {
973 fd_ptr->dev = (uint32)-1;
974 fd_ptr->inode = (uint32)-1;
976 fd_ptr->fd_readonly = -1;
977 fd_ptr->fd_writeonly = -1;
978 fd_ptr->real_open_flags = -1;
980 /* Increment max used counter if neccessary, cuts down
981 on search time when re-using */
982 if(i > max_file_fd_used)
983 max_file_fd_used = i;
984 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
985 i, fd_ptr->dev, fd_ptr->inode));
989 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
994 /****************************************************************************
995 fd support routines - attempt to re-open an already open fd as O_RDWR.
996 Save the already open fd (we cannot close due to POSIX file locking braindamage.
997 ****************************************************************************/
999 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1001 int fd = sys_open( fname, O_RDWR, mode);
1006 if(fd_ptr->real_open_flags == O_RDONLY)
1007 fd_ptr->fd_readonly = fd_ptr->fd;
1008 if(fd_ptr->real_open_flags == O_WRONLY)
1009 fd_ptr->fd_writeonly = fd_ptr->fd;
1012 fd_ptr->real_open_flags = O_RDWR;
1015 /****************************************************************************
1016 fd support routines - attempt to close the file referenced by this fd.
1017 Decrements the ref_count and returns it.
1018 ****************************************************************************/
1019 int fd_attempt_close(file_fd_struct *fd_ptr)
1021 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1022 fd_ptr - &FileFd[0],
1023 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1024 fd_ptr->real_open_flags,
1025 fd_ptr->ref_count));
1026 if(fd_ptr->ref_count > 0) {
1027 fd_ptr->ref_count--;
1028 if(fd_ptr->ref_count == 0) {
1029 if(fd_ptr->fd != -1)
1031 if(fd_ptr->fd_readonly != -1)
1032 close(fd_ptr->fd_readonly);
1033 if(fd_ptr->fd_writeonly != -1)
1034 close(fd_ptr->fd_writeonly);
1036 fd_ptr->fd_readonly = -1;
1037 fd_ptr->fd_writeonly = -1;
1038 fd_ptr->real_open_flags = -1;
1039 fd_ptr->dev = (uint32)-1;
1040 fd_ptr->inode = (uint32)-1;
1043 return fd_ptr->ref_count;
1046 /****************************************************************************
1048 ****************************************************************************/
1049 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1051 extern struct current_user current_user;
1053 struct stat statbuf;
1054 file_fd_struct *fd_ptr;
1056 Files[fnum].open = False;
1057 Files[fnum].fd_ptr = 0;
1060 strcpy(fname,fname1);
1062 /* check permissions */
1063 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1065 DEBUG(3,("Permission denied opening %s\n",fname));
1066 check_for_pipe(fname);
1070 /* this handles a bug in Win95 - it doesn't say to create the file when it
1072 if (Connections[cnum].printer)
1076 if (flags == O_WRONLY)
1077 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1080 #if UTIME_WORKAROUND
1081 /* XXXX - is this OK?? */
1082 /* this works around a utime bug but can cause other problems */
1083 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1088 * Ensure we have a valid struct stat so we can search the
1092 if(stat(fname, &statbuf) < 0) {
1093 if(errno != ENOENT) {
1094 DEBUG(3,("Error doing stat on file %s (%s)\n",
1095 fname,strerror(errno)));
1097 check_for_pipe(fname);
1107 * Check to see if we have this file already
1108 * open. If we do, just use the already open fd and increment the
1109 * reference count (fd_get_already_open increments the ref_count).
1111 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1113 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1115 /* File was already open. */
1116 if((flags & O_CREAT) && (flags & O_EXCL)) {
1117 fd_ptr->ref_count--;
1123 * If not opened O_RDWR try
1124 * and do that here - a chmod may have been done
1125 * between the last open and now.
1127 if(fd_ptr->real_open_flags != O_RDWR)
1128 fd_attempt_reopen(fname, mode, fd_ptr);
1131 * Ensure that if we wanted write access
1132 * it has been opened for write, and if we wanted read it
1133 * was open for read.
1135 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1136 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1137 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1138 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1139 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1140 check_for_pipe(fname);
1141 fd_ptr->ref_count--;
1147 /* We need to allocate a new file_fd_struct (this increments the
1149 if((fd_ptr = fd_get_new()) == 0)
1152 * Whatever the requested flags, attempt read/write access,
1153 * as we don't know what flags future file opens may require.
1154 * If this fails, try again with the required flags.
1155 * Even if we open read/write when only read access was
1156 * requested the setting of the can_write flag in
1157 * the file_struct will protect us from errant
1158 * write requests. We never need to worry about O_APPEND
1159 * as this is not set anywhere in Samba.
1161 fd_ptr->real_open_flags = O_RDWR;
1162 /* Set the flags as needed without the read/write modes. */
1163 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1164 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1166 * On some systems opening a file for R/W access on a read only
1167 * filesystems sets errno to EROFS.
1170 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1171 #else /* No EROFS */
1172 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1174 if(flags & O_WRONLY) {
1175 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1176 fd_ptr->real_open_flags = O_WRONLY;
1178 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1179 fd_ptr->real_open_flags = O_RDONLY;
1184 if ((fd_ptr->fd >=0) &&
1185 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1189 strcpy(dname,fname);
1190 p = strrchr(dname,'/');
1192 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1193 lp_minprintspace(SNUM(cnum))) {
1194 fd_attempt_close(fd_ptr);
1195 Files[fnum].fd_ptr = 0;
1196 if(fd_ptr->ref_count == 0)
1205 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1206 fname,strerror(errno),flags));
1207 /* Ensure the ref_count is decremented. */
1208 fd_attempt_close(fd_ptr);
1209 check_for_pipe(fname);
1213 if (fd_ptr->fd >= 0)
1217 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1218 /* Error - backout !! */
1219 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1220 fd_ptr->fd, fname,strerror(errno)));
1221 /* Ensure the ref_count is decremented. */
1222 fd_attempt_close(fd_ptr);
1227 /* Set the correct entries in fd_ptr. */
1228 fd_ptr->dev = (uint32)sbuf->st_dev;
1229 fd_ptr->inode = (uint32)sbuf->st_ino;
1231 Files[fnum].fd_ptr = fd_ptr;
1232 Connections[cnum].num_files_open++;
1233 Files[fnum].mode = sbuf->st_mode;
1234 GetTimeOfDay(&Files[fnum].open_time);
1235 Files[fnum].uid = current_user.id;
1236 Files[fnum].size = 0;
1237 Files[fnum].pos = -1;
1238 Files[fnum].open = True;
1239 Files[fnum].mmap_ptr = NULL;
1240 Files[fnum].mmap_size = 0;
1241 Files[fnum].can_lock = True;
1242 Files[fnum].can_read = ((flags & O_WRONLY)==0);
1243 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1244 Files[fnum].share_mode = 0;
1245 Files[fnum].print_file = Connections[cnum].printer;
1246 Files[fnum].modified = False;
1247 Files[fnum].cnum = cnum;
1248 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1249 Files[fnum].wbmpx_ptr = NULL;
1252 * If the printer is marked as postscript output a leading
1253 * file identifier to ensure the file is treated as a raw
1255 * This has a similar effect as CtrlD=0 in WIN.INI file.
1256 * tim@fsg.com 09/06/94
1258 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1259 Files[fnum].can_write)
1261 DEBUG(3,("Writing postscript line\n"));
1262 write_file(fnum,"%!\n",3);
1265 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1266 timestring(),Connections[cnum].user,fname,
1267 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1268 Connections[cnum].num_files_open,fnum));
1273 /* mmap it if read-only */
1274 if (!Files[fnum].can_write)
1276 Files[fnum].mmap_size = file_size(fname);
1277 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1278 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1280 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1282 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1283 Files[fnum].mmap_ptr = NULL;
1289 /*******************************************************************
1291 ********************************************************************/
1292 void sync_file(int fnum)
1295 fsync(Files[fnum].fd_ptr->fd);
1299 /****************************************************************************
1300 run a file if it is a magic script
1301 ****************************************************************************/
1302 static void check_magic(int fnum,int cnum)
1304 if (!*lp_magicscript(SNUM(cnum)))
1307 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1311 if (!(p = strrchr(Files[fnum].name,'/')))
1312 p = Files[fnum].name;
1316 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1322 pstring magic_output;
1324 strcpy(fname,Files[fnum].name);
1326 if (*lp_magicoutput(SNUM(cnum)))
1327 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1329 sprintf(magic_output,"%s.out",fname);
1332 ret = smbrun(fname,magic_output,False);
1333 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1339 /****************************************************************************
1340 close a file - possibly invalidating the read prediction
1341 ****************************************************************************/
1342 void close_file(int fnum)
1344 files_struct *fs_p = &Files[fnum];
1345 int cnum = fs_p->cnum;
1346 uint32 dev = fs_p->fd_ptr->dev;
1347 uint32 inode = fs_p->fd_ptr->inode;
1348 share_lock_token token;
1350 invalidate_read_prediction(fs_p->fd_ptr->fd);
1352 Connections[cnum].num_files_open--;
1355 free((char *)fs_p->wbmpx_ptr);
1356 fs_p->wbmpx_ptr = NULL;
1362 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1363 fs_p->mmap_ptr = NULL;
1367 if (lp_share_modes(SNUM(cnum)))
1369 lock_share_entry( cnum, dev, inode, &token);
1370 del_share_mode(token, fnum);
1373 fd_attempt_close(fs_p->fd_ptr);
1375 if (lp_share_modes(SNUM(cnum)))
1376 unlock_share_entry( cnum, dev, inode, token);
1378 /* NT uses smbclose to start a print - weird */
1379 if (fs_p->print_file)
1382 /* check for magic scripts */
1383 check_magic(fnum,cnum);
1385 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1386 timestring(),Connections[cnum].user,fs_p->name,
1387 Connections[cnum].num_files_open));
1390 enum {AFAIL,AREAD,AWRITE,AALL};
1392 /*******************************************************************
1393 reproduce the share mode access table
1394 ********************************************************************/
1395 static int access_table(int new_deny,int old_deny,int old_mode,
1396 int share_pid,char *fname)
1398 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1400 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1401 if (old_deny == new_deny && share_pid == getpid())
1404 if (old_mode == 0) return(AREAD);
1406 /* the new smbpub.zip spec says that if the file extension is
1407 .com, .dll, .exe or .sym then allow the open. I will force
1408 it to read-only as this seems sensible although the spec is
1409 a little unclear on this. */
1410 if ((fname = strrchr(fname,'.'))) {
1411 if (strequal(fname,".com") ||
1412 strequal(fname,".dll") ||
1413 strequal(fname,".exe") ||
1414 strequal(fname,".sym"))
1424 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1425 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1426 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1429 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1430 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1431 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1434 if (old_deny==DENY_WRITE) return(AREAD);
1435 if (old_deny==DENY_READ) return(AWRITE);
1436 if (old_deny==DENY_NONE) return(AALL);
1442 /*******************************************************************
1443 check if the share mode on a file allows it to be deleted or unlinked
1444 return True if sharing doesn't prevent the operation
1445 ********************************************************************/
1446 BOOL check_file_sharing(int cnum,char *fname)
1450 min_share_mode_entry *old_shares = 0;
1451 int num_share_modes;
1453 share_lock_token token;
1456 if(!lp_share_modes(SNUM(cnum)))
1459 if (stat(fname,&sbuf) == -1) return(True);
1461 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1462 num_share_modes = get_share_modes(cnum, token,
1463 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1465 for( i = 0; i < num_share_modes; i++)
1467 if (old_shares[i].share_mode != DENY_DOS)
1470 if(old_shares[i].pid != pid)
1474 /* XXXX exactly what share mode combinations should be allowed for
1475 deleting/renaming? */
1476 /* If we got here then either there were no share modes or
1477 all share modes were DENY_DOS and the pid == getpid() */
1482 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1483 if(old_shares != NULL)
1484 free((char *)old_shares);
1488 /****************************************************************************
1490 Helper for open_file_shared.
1491 Truncate a file after checking locking; close file if locked.
1492 **************************************************************************/
1493 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1496 if (Files[fnum].can_write){
1497 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1498 /* If share modes are in force for this connection we
1499 have the share entry locked. Unlock it before closing. */
1500 if (*share_locked && lp_share_modes(SNUM(cnum)))
1501 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1502 Files[fnum].fd_ptr->inode, token);
1504 /* Share mode no longer locked. */
1505 *share_locked = False;
1507 unix_ERR_class = ERRDOS;
1508 unix_ERR_code = ERRlock;
1511 ftruncate(Files[fnum].fd_ptr->fd,0);
1516 /****************************************************************************
1517 open a file with a share mode
1518 ****************************************************************************/
1519 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1520 int mode,int *Access,int *action)
1522 files_struct *fs_p = &Files[fnum];
1525 int deny_mode = (share_mode>>4)&7;
1527 BOOL file_existed = file_exist(fname,&sbuf);
1528 BOOL share_locked = False;
1529 BOOL fcbopen = False;
1530 share_lock_token token;
1537 /* this is for OS/2 EAs - try and say we don't support them */
1538 if (strstr(fname,".+,;=[]."))
1540 unix_ERR_class = ERRDOS;
1541 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1543 unix_ERR_code = ERRcannotopen;
1544 #else /* OS2_WPS_FIX */
1545 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1546 #endif /* OS2_WPS_FIX */
1551 if ((ofun & 0x3) == 0 && file_existed)
1559 if ((ofun & 0x3) == 2)
1562 /* note that we ignore the append flag as
1563 append does not mean the same thing under dos and unix */
1565 switch (share_mode&0xF)
1582 if (flags != O_RDONLY && file_existed &&
1583 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1593 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1595 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1600 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1602 if (lp_share_modes(SNUM(cnum)))
1606 min_share_mode_entry *old_shares = 0;
1611 dev = (uint32)sbuf.st_dev;
1612 inode = (uint32)sbuf.st_ino;
1613 lock_share_entry(cnum, dev, inode, &token);
1614 share_locked = True;
1615 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1618 for(i = 0; i < num_shares; i++)
1620 /* someone else has a share lock on it, check to see
1622 int old_open_mode = old_shares[i].share_mode &0xF;
1623 int old_deny_mode = (old_shares[i].share_mode >>4)&7;
1625 if (old_deny_mode > 4 || old_open_mode > 2)
1627 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1628 deny_mode,old_deny_mode,old_open_mode,fname));
1629 free((char *)old_shares);
1631 unlock_share_entry(cnum, dev, inode, token);
1633 unix_ERR_class = ERRDOS;
1634 unix_ERR_code = ERRbadshare;
1639 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1640 old_shares[i].pid,fname);
1642 if ((access_allowed == AFAIL) ||
1643 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1644 (access_allowed == AREAD && flags == O_WRONLY) ||
1645 (access_allowed == AWRITE && flags == O_RDONLY))
1647 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1648 deny_mode,old_deny_mode,old_open_mode,
1649 old_shares[i].pid,fname,
1651 free((char *)old_shares);
1653 unlock_share_entry(cnum, dev, inode, token);
1655 unix_ERR_class = ERRDOS;
1656 unix_ERR_code = ERRbadshare;
1660 if (access_allowed == AREAD)
1663 if (access_allowed == AWRITE)
1668 free((char *)old_shares);
1671 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1672 flags,flags2,mode));
1674 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1675 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1678 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1685 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1687 /* We created the file - thus we must now lock the share entry before creating it. */
1688 dev = fs_p->fd_ptr->dev;
1689 inode = fs_p->fd_ptr->inode;
1690 lock_share_entry(cnum, dev, inode, &token);
1691 share_locked = True;
1707 fs_p->share_mode = (deny_mode<<4) | open_mode;
1710 (*Access) = open_mode;
1714 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1715 if (!file_existed) *action = 2;
1716 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1718 /* We must create the share mode entry before truncate as
1719 truncate can fail due to locking and have to close the
1720 file (which expects the share_mode_entry to be there).
1722 if (lp_share_modes(SNUM(cnum)))
1723 set_share_mode(token, fnum, 0);
1725 if ((flags2&O_TRUNC) && file_existed)
1726 truncate_unless_locked(fnum,cnum,token,&share_locked);
1729 if (share_locked && lp_share_modes(SNUM(cnum)))
1730 unlock_share_entry( cnum, dev, inode, token);
1733 /****************************************************************************
1734 seek a file. Try to avoid the seek if possible
1735 ****************************************************************************/
1736 int seek_file(int fnum,uint32 pos)
1739 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1742 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1744 return(Files[fnum].pos);
1747 /****************************************************************************
1749 ****************************************************************************/
1750 int read_file(int fnum,char *data,uint32 pos,int n)
1754 if (!Files[fnum].can_write)
1756 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1764 if (Files[fnum].mmap_ptr)
1766 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1769 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1781 if (seek_file(fnum,pos) != pos)
1783 DEBUG(3,("Failed to seek to %d\n",pos));
1788 readret = read(Files[fnum].fd_ptr->fd,data,n);
1789 if (readret > 0) ret += readret;
1796 /****************************************************************************
1798 ****************************************************************************/
1799 int write_file(int fnum,char *data,int n)
1801 if (!Files[fnum].can_write) {
1806 if (!Files[fnum].modified) {
1808 Files[fnum].modified = True;
1809 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1810 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1811 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1812 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1817 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1821 /****************************************************************************
1822 load parameters specific to a connection/service
1823 ****************************************************************************/
1824 BOOL become_service(int cnum,BOOL do_chdir)
1826 extern char magic_char;
1827 static int last_cnum = -1;
1830 if (!OPEN_CNUM(cnum))
1836 Connections[cnum].lastused = smb_last_time;
1841 ChDir(Connections[cnum].connectpath) != 0 &&
1842 ChDir(Connections[cnum].origpath) != 0)
1844 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1845 Connections[cnum].connectpath,cnum));
1849 if (cnum == last_cnum)
1854 case_default = lp_defaultcase(snum);
1855 case_preserve = lp_preservecase(snum);
1856 short_case_preserve = lp_shortpreservecase(snum);
1857 case_mangle = lp_casemangle(snum);
1858 case_sensitive = lp_casesensitive(snum);
1859 magic_char = lp_magicchar(snum);
1860 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1865 /****************************************************************************
1866 find a service entry
1867 ****************************************************************************/
1868 int find_service(char *service)
1872 string_sub(service,"\\","/");
1874 iService = lp_servicenumber(service);
1876 /* now handle the special case of a home directory */
1879 char *phome_dir = get_home_dir(service);
1880 DEBUG(3,("checking for home directory %s gave %s\n",service,
1881 phome_dir?phome_dir:"(NULL)"));
1885 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1887 lp_add_home(service,iHomeService,phome_dir);
1888 iService = lp_servicenumber(service);
1893 /* If we still don't have a service, attempt to add it as a printer. */
1896 int iPrinterService;
1898 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1902 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1904 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1906 DEBUG(3,("%s is a valid printer name\n", service));
1907 DEBUG(3,("adding %s as a printer service\n", service));
1908 lp_add_printer(service,iPrinterService);
1909 iService = lp_servicenumber(service);
1911 DEBUG(0,("failed to add %s as a printer service!\n", service));
1914 DEBUG(3,("%s is not a valid printer name\n", service));
1918 /* just possibly it's a default service? */
1921 char *defservice = lp_defaultservice();
1922 if (defservice && *defservice && !strequal(defservice,service)) {
1923 iService = find_service(defservice);
1924 if (iService >= 0) {
1925 string_sub(service,"_","/");
1926 iService = lp_add_service(service,iService);
1932 if (!VALID_SNUM(iService))
1934 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1939 DEBUG(3,("find_service() failed to find service %s\n", service));
1945 /****************************************************************************
1946 create an error packet from a cached error.
1947 ****************************************************************************/
1948 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1950 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1952 int32 eclass = wbmpx->wr_errclass;
1953 int32 err = wbmpx->wr_error;
1955 /* We can now delete the auxiliary struct */
1956 free((char *)wbmpx);
1957 Files[fnum].wbmpx_ptr = NULL;
1958 return error_packet(inbuf,outbuf,eclass,err,line);
1967 } unix_smb_errmap[] =
1969 {EPERM,ERRDOS,ERRnoaccess},
1970 {EACCES,ERRDOS,ERRnoaccess},
1971 {ENOENT,ERRDOS,ERRbadfile},
1972 {ENOTDIR,ERRDOS,ERRbaddirectory},
1973 {EIO,ERRHRD,ERRgeneral},
1974 {EBADF,ERRSRV,ERRsrverror},
1975 {EINVAL,ERRSRV,ERRsrverror},
1976 {EEXIST,ERRDOS,ERRfilexists},
1977 {ENFILE,ERRDOS,ERRnofids},
1978 {EMFILE,ERRDOS,ERRnofids},
1979 {ENOSPC,ERRHRD,ERRdiskfull},
1981 {EDQUOT,ERRHRD,ERRdiskfull},
1984 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1987 {EXDEV,ERRDOS,ERRdiffdevice},
1989 {EROFS,ERRHRD,ERRnowrite},
1993 /* Mapping for old clients. */
2000 enum remote_arch_types valid_ra_type;
2001 } old_client_errmap[] =
2003 {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT},
2007 /****************************************************************************
2008 create an error packet from errno
2009 ****************************************************************************/
2010 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2012 int eclass=def_class;
2016 if (unix_ERR_class != SUCCESS)
2018 eclass = unix_ERR_class;
2019 ecode = unix_ERR_code;
2020 unix_ERR_class = SUCCESS;
2025 while (unix_smb_errmap[i].smbclass != 0)
2027 if (unix_smb_errmap[i].unixerror == errno)
2029 eclass = unix_smb_errmap[i].smbclass;
2030 ecode = unix_smb_errmap[i].smbcode;
2037 /* Make sure we don't return error codes that old
2038 clients don't understand. */
2040 /* JRA - unfortunately, WinNT needs some error codes
2041 for apps to work correctly, Win95 will break if
2042 these error codes are returned. But they both
2043 negotiate the *same* protocol. So we need to use
2044 the revolting 'remote_arch' enum to tie break.
2046 There must be a better way of doing this...
2049 for(i = 0; old_client_errmap[i].new_smb_error != 0; i++)
2051 if(((Protocol < old_client_errmap[i].protocol_level) ||
2052 (old_client_errmap[i].valid_ra_type != get_remote_arch())) &&
2053 (old_client_errmap[i].new_smb_error == ecode))
2055 ecode = old_client_errmap[i].old_smb_error;
2060 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2064 /****************************************************************************
2065 create an error packet. Normally called using the ERROR() macro
2066 ****************************************************************************/
2067 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2069 int outsize = set_message(outbuf,0,0,True);
2071 cmd = CVAL(inbuf,smb_com);
2073 CVAL(outbuf,smb_rcls) = error_class;
2074 SSVAL(outbuf,smb_err,error_code);
2076 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2079 (int)CVAL(inbuf,smb_com),
2080 smb_fn_name(CVAL(inbuf,smb_com)),
2085 DEBUG(3,("error string = %s\n",strerror(errno)));
2091 #ifndef SIGCLD_IGNORE
2092 /****************************************************************************
2093 this prevents zombie child processes
2094 ****************************************************************************/
2095 static int sig_cld()
2097 static int depth = 0;
2100 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2106 BlockSignals(True,SIGCLD);
2107 DEBUG(5,("got SIGCLD\n"));
2110 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2114 /* Stevens, Adv. Unix Prog. says that on system V you must call
2115 wait before reinstalling the signal handler, because the kernel
2116 calls the handler from within the signal-call when there is a
2117 child that has exited. This would lead to an infinite recursion
2118 if done vice versa. */
2120 #ifndef DONT_REINSTALL_SIG
2121 #ifdef SIGCLD_IGNORE
2122 signal(SIGCLD, SIG_IGN);
2124 signal(SIGCLD, SIGNAL_CAST sig_cld);
2129 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2132 BlockSignals(False,SIGCLD);
2137 /****************************************************************************
2138 this is called when the client exits abruptly
2139 **************************************************************************/
2140 static int sig_pipe()
2142 extern int password_client;
2143 BlockSignals(True,SIGPIPE);
2145 if (password_client != -1) {
2146 DEBUG(3,("lost connection to password server\n"));
2147 close(password_client);
2148 password_client = -1;
2149 #ifndef DONT_REINSTALL_SIG
2150 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2152 BlockSignals(False,SIGPIPE);
2156 exit_server("Got sigpipe\n");
2160 /****************************************************************************
2161 open the socket communication
2162 ****************************************************************************/
2163 static BOOL open_sockets(BOOL is_daemon,int port)
2170 struct sockaddr addr;
2171 int in_addrlen = sizeof(addr);
2174 #ifdef SIGCLD_IGNORE
2175 signal(SIGCLD, SIG_IGN);
2177 signal(SIGCLD, SIGNAL_CAST sig_cld);
2180 /* open an incoming socket */
2181 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2185 /* ready to listen */
2186 if (listen(s, 5) == -1)
2188 DEBUG(0,("listen: %s\n",strerror(errno)));
2196 /* now accept incoming connections - forking a new process
2197 for each incoming connection */
2198 DEBUG(2,("waiting for a connection\n"));
2201 Client = accept(s,&addr,&in_addrlen);
2203 if (Client == -1 && errno == EINTR)
2208 DEBUG(0,("accept: %s\n",strerror(errno)));
2212 #ifdef NO_FORK_DEBUG
2213 #ifndef NO_SIGNAL_TEST
2214 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2215 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2219 if (Client != -1 && fork()==0)
2221 /* Child code ... */
2222 #ifndef NO_SIGNAL_TEST
2223 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2224 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2226 /* close the listening socket */
2229 /* close our standard file descriptors */
2233 set_socket_options(Client,"SO_KEEPALIVE");
2234 set_socket_options(Client,user_socket_options);
2236 /* Reset global variables in util.c so that
2237 client substitutions will be done correctly
2240 reset_globals_after_fork();
2243 close(Client); /* The parent doesn't need this socket */
2249 /* We will abort gracefully when the client or remote system
2251 #ifndef NO_SIGNAL_TEST
2252 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2256 /* close our standard file descriptors */
2259 set_socket_options(Client,"SO_KEEPALIVE");
2260 set_socket_options(Client,user_socket_options);
2267 /****************************************************************************
2268 open the oplock IPC socket communication
2269 ****************************************************************************/
2270 static BOOL open_oplock_ipc()
2272 struct sockaddr_in sock_name;
2273 int name_len = sizeof(sock_name);
2275 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2277 /* Open a lookback UDP socket on a random port. */
2278 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2279 if (oplock_sock == -1)
2281 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2282 address %x. Error was %s\n", INADDR_LOOPBACK, strerror(errno)));
2286 /* Find out the transient UDP port we have been allocated. */
2287 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &name_len)<0)
2289 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2295 oplock_port = ntohs(sock_name.sin_port);
2300 /****************************************************************************
2301 process an oplock break message.
2302 ****************************************************************************/
2303 static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size)
2307 struct in_addr from_addr;
2310 msg_len = IVAL(buffer,0);
2311 from_port = SVAL(buffer,4);
2312 memcpy((char *)&from_addr, &buffer[6], sizeof(struct in_addr));
2314 msg_start = &buffer[6 + sizeof(struct in_addr)];
2316 /* Validate message length. */
2317 if(msg_len > (buf_size - (6 + sizeof(struct in_addr))))
2319 DEBUG(0,("process_local_message: invalid msg_len (%d) max can be %d\n",
2320 msg_len, buf_size - (6 + sizeof(struct in_addr))));
2324 /* Validate message from address (must be localhost). */
2325 if(from_addr.s_addr != htonl(INADDR_LOOPBACK))
2327 DEBUG(0,("process_local_message: invalid from address \
2328 (was %x should be 127.0.0.1\n", from_addr.s_addr));
2334 #endif /* USE_OPLOCKS */
2336 /****************************************************************************
2337 check if a snum is in use
2338 ****************************************************************************/
2339 BOOL snum_used(int snum)
2342 for (i=0;i<MAX_CONNECTIONS;i++)
2343 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2348 /****************************************************************************
2349 reload the services file
2350 **************************************************************************/
2351 BOOL reload_services(BOOL test)
2358 strcpy(fname,lp_configfile());
2359 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2361 strcpy(servicesf,fname);
2368 if (test && !lp_file_list_changed())
2371 lp_killunused(snum_used);
2373 ret = lp_load(servicesf,False);
2375 /* perhaps the config filename is now set */
2377 reload_services(True);
2386 set_socket_options(Client,"SO_KEEPALIVE");
2387 set_socket_options(Client,user_socket_options);
2391 create_mangled_stack(lp_mangledstack());
2393 /* this forces service parameters to be flushed */
2394 become_service(-1,True);
2401 /****************************************************************************
2402 this prevents zombie child processes
2403 ****************************************************************************/
2404 static int sig_hup()
2406 BlockSignals(True,SIGHUP);
2407 DEBUG(0,("Got SIGHUP\n"));
2408 reload_services(False);
2409 #ifndef DONT_REINSTALL_SIG
2410 signal(SIGHUP,SIGNAL_CAST sig_hup);
2412 BlockSignals(False,SIGHUP);
2416 /****************************************************************************
2417 Setup the groups a user belongs to.
2418 ****************************************************************************/
2419 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2420 int **p_igroups, gid_t **p_groups)
2422 if (-1 == initgroups(user,gid))
2426 DEBUG(0,("Unable to initgroups!\n"));
2427 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2428 DEBUG(0,("This is probably a problem with the account %s\n",user));
2436 ngroups = getgroups(0,&grp);
2439 igroups = (int *)malloc(sizeof(int)*ngroups);
2440 for (i=0;i<ngroups;i++)
2441 igroups[i] = 0x42424242;
2442 ngroups = getgroups(ngroups,(gid_t *)igroups);
2444 if (igroups[0] == 0x42424242)
2447 *p_ngroups = ngroups;
2449 /* The following bit of code is very strange. It is due to the
2450 fact that some OSes use int* and some use gid_t* for
2451 getgroups, and some (like SunOS) use both, one in prototypes,
2452 and one in man pages and the actual code. Thus we detect it
2453 dynamically using some very ugly code */
2456 /* does getgroups return ints or gid_t ?? */
2457 static BOOL groups_use_ints = True;
2459 if (groups_use_ints &&
2461 SVAL(igroups,2) == 0x4242)
2462 groups_use_ints = False;
2464 for (i=0;groups_use_ints && i<ngroups;i++)
2465 if (igroups[i] == 0x42424242)
2466 groups_use_ints = False;
2468 if (groups_use_ints)
2470 *p_igroups = igroups;
2471 *p_groups = (gid_t *)igroups;
2475 gid_t *groups = (gid_t *)igroups;
2476 igroups = (int *)malloc(sizeof(int)*ngroups);
2477 for (i=0;i<ngroups;i++)
2478 igroups[i] = groups[i];
2479 *p_igroups = igroups;
2480 *p_groups = (gid_t *)groups;
2483 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2484 for (i=0;i<ngroups;i++)
2485 DEBUG(3,("%d ",igroups[i]));
2491 /****************************************************************************
2492 make a connection to a service
2493 ****************************************************************************/
2494 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2498 struct passwd *pass = NULL;
2499 connection_struct *pcon;
2502 static BOOL first_connection = True;
2506 snum = find_service(service);
2509 if (strequal(service,"IPC$"))
2511 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2515 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2519 if (strequal(service,HOMES_NAME))
2521 if (*user && Get_Pwnam(user,True))
2522 return(make_connection(user,user,password,pwlen,dev,vuid));
2524 if (validated_username(vuid))
2526 strcpy(user,validated_username(vuid));
2527 return(make_connection(user,user,password,pwlen,dev,vuid));
2531 if (!lp_snum_ok(snum) || !check_access(snum)) {
2535 /* you can only connect to the IPC$ service as an ipc device */
2536 if (strequal(service,"IPC$"))
2539 if (*dev == '?' || !*dev)
2541 if (lp_print_ok(snum))
2542 strcpy(dev,"LPT1:");
2547 /* if the request is as a printer and you can't print then refuse */
2549 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2550 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2554 /* lowercase the user name */
2557 /* add it as a possible user name */
2558 add_session_user(service);
2560 /* shall we let them in? */
2561 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2563 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2567 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2570 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2574 pcon = &Connections[cnum];
2575 bzero((char *)pcon,sizeof(*pcon));
2577 /* find out some info about the user */
2578 pass = Get_Pwnam(user,True);
2582 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2586 pcon->read_only = lp_readonly(snum);
2590 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2591 string_sub(list,"%S",service);
2593 if (user_in_list(user,list))
2594 pcon->read_only = True;
2596 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2597 string_sub(list,"%S",service);
2599 if (user_in_list(user,list))
2600 pcon->read_only = False;
2603 /* admin user check */
2604 if (user_in_list(user,lp_admin_users(snum)) &&
2607 pcon->admin_user = True;
2608 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2611 pcon->admin_user = False;
2613 pcon->force_user = force;
2615 pcon->uid = pass->pw_uid;
2616 pcon->gid = pass->pw_gid;
2617 pcon->num_files_open = 0;
2618 pcon->lastused = time(NULL);
2619 pcon->service = snum;
2621 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2622 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2623 pcon->dirptr = NULL;
2624 pcon->veto_list = NULL;
2625 pcon->hide_list = NULL;
2626 string_set(&pcon->dirpath,"");
2627 string_set(&pcon->user,user);
2630 if (*lp_force_group(snum))
2635 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2636 /* default service may be a group name */
2637 string_sub(gname,"%S",service);
2638 gptr = (struct group *)getgrnam(gname);
2642 pcon->gid = gptr->gr_gid;
2643 DEBUG(3,("Forced group %s\n",gname));
2646 DEBUG(1,("Couldn't find group %s\n",gname));
2650 if (*lp_force_user(snum))
2652 struct passwd *pass2;
2654 strcpy(fuser,lp_force_user(snum));
2655 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2658 pcon->uid = pass2->pw_uid;
2659 string_set(&pcon->user,fuser);
2661 pcon->force_user = True;
2662 DEBUG(3,("Forced user %s\n",fuser));
2665 DEBUG(1,("Couldn't find user %s\n",fuser));
2670 strcpy(s,lp_pathname(snum));
2671 standard_sub(cnum,s);
2672 string_set(&pcon->connectpath,s);
2673 DEBUG(3,("Connect path is %s\n",s));
2676 /* groups stuff added by ih */
2678 pcon->groups = NULL;
2682 /* Find all the groups this uid is in and store them. Used by become_user() */
2683 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2685 /* check number of connections */
2686 if (!claim_connection(cnum,
2687 lp_servicename(SNUM(cnum)),
2688 lp_max_connections(SNUM(cnum)),False))
2690 DEBUG(1,("too many connections - rejected\n"));
2694 if (lp_status(SNUM(cnum)))
2695 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2697 first_connection = False;
2702 /* execute any "root preexec = " line */
2703 if (*lp_rootpreexec(SNUM(cnum)))
2706 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2707 standard_sub(cnum,cmd);
2708 DEBUG(5,("cmd=%s\n",cmd));
2709 smbrun(cmd,NULL,False);
2712 if (!become_user(cnum,pcon->vuid))
2714 DEBUG(0,("Can't become connected user!\n"));
2716 if (!IS_IPC(cnum)) {
2717 yield_connection(cnum,
2718 lp_servicename(SNUM(cnum)),
2719 lp_max_connections(SNUM(cnum)));
2720 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2725 if (ChDir(pcon->connectpath) != 0)
2727 DEBUG(0,("Can't change directory to %s (%s)\n",
2728 pcon->connectpath,strerror(errno)));
2731 if (!IS_IPC(cnum)) {
2732 yield_connection(cnum,
2733 lp_servicename(SNUM(cnum)),
2734 lp_max_connections(SNUM(cnum)));
2735 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2740 string_set(&pcon->origpath,pcon->connectpath);
2742 #if SOFTLINK_OPTIMISATION
2743 /* resolve any soft links early */
2746 strcpy(s,pcon->connectpath);
2748 string_set(&pcon->connectpath,s);
2749 ChDir(pcon->connectpath);
2753 num_connections_open++;
2754 add_session_user(user);
2756 /* execute any "preexec = " line */
2757 if (*lp_preexec(SNUM(cnum)))
2760 strcpy(cmd,lp_preexec(SNUM(cnum)));
2761 standard_sub(cnum,cmd);
2762 smbrun(cmd,NULL,False);
2765 /* we've finished with the sensitive stuff */
2768 /* Add veto/hide lists */
2769 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
2771 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
2772 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
2776 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2780 lp_servicename(SNUM(cnum)),user,
2790 /****************************************************************************
2791 find first available file slot
2792 ****************************************************************************/
2793 int find_free_file(void )
2796 /* we start at 1 here for an obscure reason I can't now remember,
2797 but I think is important :-) */
2798 for (i=1;i<MAX_OPEN_FILES;i++)
2801 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2805 /****************************************************************************
2806 find first available connection slot, starting from a random position.
2807 The randomisation stops problems with the server dieing and clients
2808 thinking the server is still available.
2809 ****************************************************************************/
2810 static int find_free_connection(int hash )
2814 hash = (hash % (MAX_CONNECTIONS-2))+1;
2818 for (i=hash+1;i!=hash;)
2820 if (!Connections[i].open && Connections[i].used == used)
2822 DEBUG(3,("found free connection number %d\n",i));
2826 if (i == MAX_CONNECTIONS)
2836 DEBUG(1,("ERROR! Out of connection structures\n"));
2841 /****************************************************************************
2842 reply for the core protocol
2843 ****************************************************************************/
2844 int reply_corep(char *outbuf)
2846 int outsize = set_message(outbuf,1,0,True);
2848 Protocol = PROTOCOL_CORE;
2854 /****************************************************************************
2855 reply for the coreplus protocol
2856 ****************************************************************************/
2857 int reply_coreplus(char *outbuf)
2859 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2860 int outsize = set_message(outbuf,13,0,True);
2861 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2862 readbraw and writebraw (possibly) */
2863 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2864 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2866 Protocol = PROTOCOL_COREPLUS;
2872 /****************************************************************************
2873 reply for the lanman 1.0 protocol
2874 ****************************************************************************/
2875 int reply_lanman1(char *outbuf)
2877 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2879 BOOL doencrypt = SMBENCRYPT();
2880 time_t t = time(NULL);
2881 /* We need to save and restore this as it can be destroyed
2882 if we call another server if security=server
2883 Thanks to Paul Nelson @ Thursby for pointing this out.
2885 uint16 mid = SVAL(outbuf, smb_mid);
2887 if (lp_security()>=SEC_USER) secword |= 1;
2888 if (doencrypt) secword |= 2;
2890 set_message(outbuf,13,doencrypt?8:0,True);
2891 SSVAL(outbuf,smb_vwv1,secword);
2892 /* Create a token value and add it to the outgoing packet. */
2894 generate_next_challenge(smb_buf(outbuf));
2896 Protocol = PROTOCOL_LANMAN1;
2898 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2899 DEBUG(3,("using password server validation\n"));
2900 if (doencrypt) set_challenge(smb_buf(outbuf));
2903 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2904 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2905 SSVAL(outbuf,smb_vwv2,max_recv);
2906 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2907 SSVAL(outbuf,smb_vwv4,1);
2908 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2909 readbraw writebraw (possibly) */
2910 SIVAL(outbuf,smb_vwv6,getpid());
2911 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2913 put_dos_date(outbuf,smb_vwv8,t);
2915 return (smb_len(outbuf)+4);
2919 /****************************************************************************
2920 reply for the lanman 2.0 protocol
2921 ****************************************************************************/
2922 int reply_lanman2(char *outbuf)
2924 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2926 BOOL doencrypt = SMBENCRYPT();
2927 time_t t = time(NULL);
2928 /* We need to save and restore this as it can be destroyed
2929 if we call another server if security=server
2930 Thanks to Paul Nelson @ Thursby for pointing this out.
2932 uint16 mid = SVAL(outbuf, smb_mid);
2934 if (lp_security()>=SEC_USER) secword |= 1;
2935 if (doencrypt) secword |= 2;
2937 set_message(outbuf,13,doencrypt?8:0,True);
2938 SSVAL(outbuf,smb_vwv1,secword);
2939 /* Create a token value and add it to the outgoing packet. */
2941 generate_next_challenge(smb_buf(outbuf));
2943 SIVAL(outbuf,smb_vwv6,getpid());
2945 Protocol = PROTOCOL_LANMAN2;
2947 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2948 DEBUG(3,("using password server validation\n"));
2949 if (doencrypt) set_challenge(smb_buf(outbuf));
2952 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2953 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2954 SSVAL(outbuf,smb_vwv2,max_recv);
2955 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2956 SSVAL(outbuf,smb_vwv4,1);
2957 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2958 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2959 put_dos_date(outbuf,smb_vwv8,t);
2961 return (smb_len(outbuf)+4);
2965 /****************************************************************************
2966 reply for the nt protocol
2967 ****************************************************************************/
2968 int reply_nt1(char *outbuf)
2970 /* dual names + lock_and_read + nt SMBs + remote API calls */
2971 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2973 other valid capabilities which we may support at some time...
2974 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2975 CAP_LARGE_FILES|CAP_LARGE_READX|
2976 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2980 BOOL doencrypt = SMBENCRYPT();
2981 time_t t = time(NULL);
2984 char challenge_len = 8;
2985 /* We need to save and restore this as it can be destroyed
2986 if we call another server if security=server
2987 Thanks to Paul Nelson @ Thursby for pointing this out.
2989 uint16 mid = SVAL(outbuf, smb_mid);
2991 if (lp_readraw() && lp_writeraw())
2993 capabilities |= CAP_RAW_MODE;
2996 if (lp_security()>=SEC_USER) secword |= 1;
2997 if (doencrypt) secword |= 2;
2999 /* decide where (if) to put the encryption challenge, and
3000 follow it with the OEM'd domain name
3002 encrypt_len = doencrypt?challenge_len:0;
3004 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3006 data_len = encrypt_len + strlen(myworkgroup) + 1;
3009 set_message(outbuf,17,data_len,True);
3012 /* put the OEM'd domain name */
3013 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3015 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3018 CVAL(outbuf,smb_vwv1) = secword;
3019 /* Create a token value and add it to the outgoing packet. */
3022 generate_next_challenge(smb_buf(outbuf));
3024 /* Tell the nt machine how long the challenge is. */
3025 SSVALS(outbuf,smb_vwv16+1,challenge_len);
3028 Protocol = PROTOCOL_NT1;
3030 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3031 DEBUG(3,("using password server validation\n"));
3032 if (doencrypt) set_challenge(smb_buf(outbuf));
3035 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3036 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3037 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3038 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3039 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3040 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3041 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3042 put_long_date(outbuf+smb_vwv11+1,t);
3043 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3044 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3046 return (smb_len(outbuf)+4);
3049 /* these are the protocol lists used for auto architecture detection:
3052 protocol [PC NETWORK PROGRAM 1.0]
3053 protocol [XENIX CORE]
3054 protocol [MICROSOFT NETWORKS 1.03]
3055 protocol [LANMAN1.0]
3056 protocol [Windows for Workgroups 3.1a]
3057 protocol [LM1.2X002]
3058 protocol [LANMAN2.1]
3059 protocol [NT LM 0.12]
3062 protocol [PC NETWORK PROGRAM 1.0]
3063 protocol [XENIX CORE]
3064 protocol [MICROSOFT NETWORKS 1.03]
3065 protocol [LANMAN1.0]
3066 protocol [Windows for Workgroups 3.1a]
3067 protocol [LM1.2X002]
3068 protocol [LANMAN2.1]
3069 protocol [NT LM 0.12]
3072 protocol [PC NETWORK PROGRAM 1.0]
3073 protocol [XENIX CORE]
3074 protocol [LANMAN1.0]
3075 protocol [LM1.2X002]
3076 protocol [LANMAN2.1]
3080 * Modified to recognize the architecture of the remote machine better.
3082 * This appears to be the matrix of which protocol is used by which
3084 Protocol WfWg Win95 WinNT OS/2
3085 PC NETWORK PROGRAM 1.0 1 1 1 1
3087 MICROSOFT NETWORKS 3.0 2 2
3089 MICROSOFT NETWORKS 1.03 3
3092 Windows for Workgroups 3.1a 5 5 5
3097 * tim@fsg.com 09/29/95
3100 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3101 #define ARCH_WIN95 0x2
3102 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3103 #define ARCH_WINNT 0x8
3104 #define ARCH_SAMBA 0x10
3106 #define ARCH_ALL 0x1F
3108 /* List of supported protocols, most desired first */
3112 int (*proto_reply_fn)(char *);
3114 } supported_protocols[] = {
3115 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3116 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3117 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3118 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3119 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3120 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3121 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3122 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3123 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3128 /****************************************************************************
3130 ****************************************************************************/
3131 static int reply_negprot(char *inbuf,char *outbuf)
3133 int outsize = set_message(outbuf,1,0,True);
3138 int bcc = SVAL(smb_buf(inbuf),-2);
3139 int arch = ARCH_ALL;
3141 p = smb_buf(inbuf)+1;
3142 while (p < (smb_buf(inbuf) + bcc))
3145 DEBUG(3,("Requested protocol [%s]\n",p));
3146 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3147 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3148 else if (strcsequal(p,"DOS LM1.2X002"))
3149 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3150 else if (strcsequal(p,"DOS LANMAN2.1"))
3151 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3152 else if (strcsequal(p,"NT LM 0.12"))
3153 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3154 else if (strcsequal(p,"LANMAN2.1"))
3155 arch &= ( ARCH_WINNT | ARCH_OS2 );
3156 else if (strcsequal(p,"LM1.2X002"))
3157 arch &= ( ARCH_WINNT | ARCH_OS2 );
3158 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3160 else if (strcsequal(p,"XENIX CORE"))
3161 arch &= ( ARCH_WINNT | ARCH_OS2 );
3162 else if (strcsequal(p,"Samba")) {
3172 set_remote_arch(RA_SAMBA);
3175 set_remote_arch(RA_WFWG);
3178 set_remote_arch(RA_WIN95);
3181 set_remote_arch(RA_WINNT);
3184 set_remote_arch(RA_OS2);
3187 set_remote_arch(RA_UNKNOWN);
3191 /* possibly reload - change of architecture */
3192 reload_services(True);
3194 /* a special case to stop password server loops */
3195 if (Index == 1 && strequal(remote_machine,myhostname) &&
3196 lp_security()==SEC_SERVER)
3197 exit_server("Password server loop!");
3199 /* Check for protocols, most desirable first */
3200 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3202 p = smb_buf(inbuf)+1;
3204 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3205 while (p < (smb_buf(inbuf) + bcc))
3207 if (strequal(p,supported_protocols[protocol].proto_name))
3216 SSVAL(outbuf,smb_vwv0,choice);
3218 extern fstring remote_proto;
3219 strcpy(remote_proto,supported_protocols[protocol].short_name);
3220 reload_services(True);
3221 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3222 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3225 DEBUG(0,("No protocol supported !\n"));
3227 SSVAL(outbuf,smb_vwv0,choice);
3229 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3235 /****************************************************************************
3236 close all open files for a connection
3237 ****************************************************************************/
3238 static void close_open_files(int cnum)
3241 for (i=0;i<MAX_OPEN_FILES;i++)
3242 if( Files[i].cnum == cnum && Files[i].open) {
3249 /****************************************************************************
3251 ****************************************************************************/
3252 void close_cnum(int cnum, uint16 vuid)
3254 DirCacheFlush(SNUM(cnum));
3258 if (!OPEN_CNUM(cnum))
3260 DEBUG(0,("Can't close cnum %d\n",cnum));
3264 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3266 remote_machine,client_addr(),
3267 lp_servicename(SNUM(cnum))));
3269 yield_connection(cnum,
3270 lp_servicename(SNUM(cnum)),
3271 lp_max_connections(SNUM(cnum)));
3273 if (lp_status(SNUM(cnum)))
3274 yield_connection(cnum,"STATUS.",MAXSTATUS);
3276 close_open_files(cnum);
3277 dptr_closecnum(cnum);
3279 /* execute any "postexec = " line */
3280 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3283 strcpy(cmd,lp_postexec(SNUM(cnum)));
3284 standard_sub(cnum,cmd);
3285 smbrun(cmd,NULL,False);
3290 /* execute any "root postexec = " line */
3291 if (*lp_rootpostexec(SNUM(cnum)))
3294 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3295 standard_sub(cnum,cmd);
3296 smbrun(cmd,NULL,False);
3299 Connections[cnum].open = False;
3300 num_connections_open--;
3301 if (Connections[cnum].ngroups && Connections[cnum].groups)
3303 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3304 free(Connections[cnum].groups);
3305 free(Connections[cnum].igroups);
3306 Connections[cnum].groups = NULL;
3307 Connections[cnum].igroups = NULL;
3308 Connections[cnum].ngroups = 0;
3311 free_namearray(Connections[cnum].veto_list);
3312 free_namearray(Connections[cnum].hide_list);
3314 string_set(&Connections[cnum].user,"");
3315 string_set(&Connections[cnum].dirpath,"");
3316 string_set(&Connections[cnum].connectpath,"");
3320 /****************************************************************************
3321 simple routines to do connection counting
3322 ****************************************************************************/
3323 BOOL yield_connection(int cnum,char *name,int max_connections)
3325 struct connect_record crec;
3328 int mypid = getpid();
3331 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3333 if (max_connections <= 0)
3336 bzero(&crec,sizeof(crec));
3338 strcpy(fname,lp_lockdir());
3339 standard_sub(cnum,fname);
3340 trim_string(fname,"","/");
3344 strcat(fname,".LCK");
3346 f = fopen(fname,"r+");
3349 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3353 fseek(f,0,SEEK_SET);
3355 /* find a free spot */
3356 for (i=0;i<max_connections;i++)
3358 if (fread(&crec,sizeof(crec),1,f) != 1)
3360 DEBUG(2,("Entry not found in lock file %s\n",fname));
3364 if (crec.pid == mypid && crec.cnum == cnum)
3368 if (crec.pid != mypid || crec.cnum != cnum)
3371 DEBUG(2,("Entry not found in lock file %s\n",fname));
3375 bzero((void *)&crec,sizeof(crec));
3377 /* remove our mark */
3378 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3379 fwrite(&crec,sizeof(crec),1,f) != 1)
3381 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3386 DEBUG(3,("Yield successful\n"));
3393 /****************************************************************************
3394 simple routines to do connection counting
3395 ****************************************************************************/
3396 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3398 struct connect_record crec;
3401 int snum = SNUM(cnum);
3405 if (max_connections <= 0)
3408 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3410 strcpy(fname,lp_lockdir());
3411 standard_sub(cnum,fname);
3412 trim_string(fname,"","/");
3414 if (!directory_exist(fname,NULL))
3419 strcat(fname,".LCK");
3421 if (!file_exist(fname,NULL))
3423 int oldmask = umask(022);
3424 f = fopen(fname,"w");
3429 total_recs = file_size(fname) / sizeof(crec);
3431 f = fopen(fname,"r+");
3435 DEBUG(1,("couldn't open lock file %s\n",fname));
3439 /* find a free spot */
3440 for (i=0;i<max_connections;i++)
3443 if (i>=total_recs ||
3444 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3445 fread(&crec,sizeof(crec),1,f) != 1)
3447 if (foundi < 0) foundi = i;
3451 if (Clear && crec.pid && !process_exists(crec.pid))
3453 fseek(f,i*sizeof(crec),SEEK_SET);
3454 bzero((void *)&crec,sizeof(crec));
3455 fwrite(&crec,sizeof(crec),1,f);
3456 if (foundi < 0) foundi = i;
3459 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3468 DEBUG(3,("no free locks in %s\n",fname));
3473 /* fill in the crec */
3474 bzero((void *)&crec,sizeof(crec));
3475 crec.magic = 0x280267;
3476 crec.pid = getpid();
3478 crec.uid = Connections[cnum].uid;
3479 crec.gid = Connections[cnum].gid;
3480 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3481 crec.start = time(NULL);
3483 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3484 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3487 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3488 fwrite(&crec,sizeof(crec),1,f) != 1)
3499 /*******************************************************************
3500 prepare to dump a core file - carefully!
3501 ********************************************************************/
3502 static BOOL dump_core(void)
3506 strcpy(dname,debugf);
3507 if ((p=strrchr(dname,'/'))) *p=0;
3508 strcat(dname,"/corefiles");
3510 sys_chown(dname,getuid(),getgid());
3512 if (chdir(dname)) return(False);
3515 #ifndef NO_GETRLIMIT
3519 getrlimit(RLIMIT_CORE, &rlp);
3520 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3521 setrlimit(RLIMIT_CORE, &rlp);
3522 getrlimit(RLIMIT_CORE, &rlp);
3523 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3529 DEBUG(0,("Dumping core in %s\n",dname));
3534 /****************************************************************************
3536 ****************************************************************************/
3537 void exit_server(char *reason)
3539 static int firsttime=1;
3542 if (!firsttime) exit(0);
3546 DEBUG(2,("Closing connections\n"));
3547 for (i=0;i<MAX_CONNECTIONS;i++)
3548 if (Connections[i].open)
3549 close_cnum(i,(uint16)-1);
3551 if (dcelogin_atmost_once)
3555 int oldlevel = DEBUGLEVEL;
3557 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3559 show_msg(last_inbuf);
3560 DEBUGLEVEL = oldlevel;
3561 DEBUG(0,("===============================================================\n"));
3563 if (dump_core()) return;
3567 #ifdef FAST_SHARE_MODES
3568 stop_share_mode_mgmt();
3569 #endif /* FAST_SHARE_MODES */
3571 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3575 /****************************************************************************
3576 do some standard substitutions in a string
3577 ****************************************************************************/
3578 void standard_sub(int cnum,char *str)
3580 if (VALID_CNUM(cnum)) {
3583 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
3585 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
3586 string_sub(p,"%H",home);
3590 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
3591 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
3592 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
3593 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
3594 case '\0' : p++; break; /* don't run off the end of the string */
3595 default : p+=2; break;
3599 standard_sub_basic(str);
3603 These flags determine some of the permissions required to do an operation
3605 Note that I don't set NEED_WRITE on some write operations because they
3606 are used by some brain-dead clients when printing, and I don't want to
3607 force write permissions on print services.
3609 #define AS_USER (1<<0)
3610 #define NEED_WRITE (1<<1)
3611 #define TIME_INIT (1<<2)
3612 #define CAN_IPC (1<<3)
3613 #define AS_GUEST (1<<5)
3617 define a list of possible SMB messages and their corresponding
3618 functions. Any message that has a NULL function is unimplemented -
3619 please feel free to contribute implementations!
3621 struct smb_message_struct
3635 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3636 {SMBtcon,"SMBtcon",reply_tcon,0},
3637 {SMBtdis,"SMBtdis",reply_tdis,0},
3638 {SMBexit,"SMBexit",reply_exit,0},
3639 {SMBioctl,"SMBioctl",reply_ioctl,0},
3640 {SMBecho,"SMBecho",reply_echo,0},
3641 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3642 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3643 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3644 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3645 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3646 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3647 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3648 {SMBopen,"SMBopen",reply_open,AS_USER},
3650 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3651 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3652 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3654 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3655 {SMBread,"SMBread",reply_read,AS_USER},
3656 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3657 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3658 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3659 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3660 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3661 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3663 /* this is a Pathworks specific call, allowing the
3664 changing of the root path */
3665 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3667 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3668 {SMBflush,"SMBflush",reply_flush,AS_USER},
3669 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3670 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3671 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3672 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3673 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3674 {SMBlock,"SMBlock",reply_lock,AS_USER},
3675 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3677 /* CORE+ PROTOCOL FOLLOWS */
3679 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3680 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3681 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3682 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3683 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3685 /* LANMAN1.0 PROTOCOL FOLLOWS */
3687 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3688 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3689 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3690 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3691 {SMBwritec,"SMBwritec",NULL,AS_USER},
3692 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3693 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3694 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3695 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3696 {SMBioctls,"SMBioctls",NULL,AS_USER},
3697 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3698 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3700 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3701 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3702 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3703 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3705 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3706 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3707 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3709 /* LANMAN2.0 PROTOCOL FOLLOWS */
3710 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3711 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3712 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3713 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3715 /* messaging routines */
3716 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3717 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3718 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3719 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3721 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3723 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3724 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3725 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3726 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3729 /****************************************************************************
3730 return a string containing the function name of a SMB command
3731 ****************************************************************************/
3732 char *smb_fn_name(int type)
3734 static char *unknown_name = "SMBunknown";
3735 static int num_smb_messages =
3736 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3739 for (match=0;match<num_smb_messages;match++)
3740 if (smb_messages[match].code == type)
3743 if (match == num_smb_messages)
3744 return(unknown_name);
3746 return(smb_messages[match].name);
3750 /****************************************************************************
3751 do a switch on the message type, and return the response size
3752 ****************************************************************************/
3753 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3757 static int num_smb_messages =
3758 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3762 struct timeval msg_start_time;
3763 struct timeval msg_end_time;
3764 static unsigned long total_time = 0;
3766 GetTimeOfDay(&msg_start_time);
3773 last_message = type;
3775 /* make sure this is an SMB packet */
3776 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3778 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3782 for (match=0;match<num_smb_messages;match++)
3783 if (smb_messages[match].code == type)
3786 if (match == num_smb_messages)
3788 DEBUG(0,("Unknown message type %d!\n",type));
3789 outsize = reply_unknown(inbuf,outbuf);
3793 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3794 if (smb_messages[match].fn)
3796 int cnum = SVAL(inbuf,smb_tid);
3797 int flags = smb_messages[match].flags;
3798 uint16 session_tag = SVAL(inbuf,smb_uid);
3800 /* does this protocol need to be run as root? */
3801 if (!(flags & AS_USER))
3804 /* does this protocol need to be run as the connected user? */
3805 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3806 if (flags & AS_GUEST)
3809 return(ERROR(ERRSRV,ERRinvnid));
3811 /* this code is to work around a bug is MS client 3 without
3812 introducing a security hole - it needs to be able to do
3813 print queue checks as guest if it isn't logged in properly */
3814 if (flags & AS_USER)
3817 /* does it need write permission? */
3818 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3819 return(ERROR(ERRSRV,ERRaccess));
3821 /* ipc services are limited */
3822 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3823 return(ERROR(ERRSRV,ERRaccess));
3825 /* load service specific parameters */
3826 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3827 return(ERROR(ERRSRV,ERRaccess));
3829 /* does this protocol need to be run as guest? */
3830 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3831 return(ERROR(ERRSRV,ERRaccess));
3835 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3839 outsize = reply_unknown(inbuf,outbuf);
3844 GetTimeOfDay(&msg_end_time);
3845 if (!(smb_messages[match].flags & TIME_INIT))
3847 smb_messages[match].time = 0;
3848 smb_messages[match].flags |= TIME_INIT;
3851 unsigned long this_time =
3852 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3853 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3854 smb_messages[match].time += this_time;
3855 total_time += this_time;
3857 DEBUG(2,("TIME %s %d usecs %g pct\n",
3858 smb_fn_name(type),smb_messages[match].time,
3859 (100.0*smb_messages[match].time) / total_time));
3866 /****************************************************************************
3867 construct a chained reply and add it to the already made reply
3868 **************************************************************************/
3869 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3871 static char *orig_inbuf;
3872 static char *orig_outbuf;
3873 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3874 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3875 char *inbuf2, *outbuf2;
3877 char inbuf_saved[smb_wct];
3878 char outbuf_saved[smb_wct];
3879 extern int chain_size;
3880 int wct = CVAL(outbuf,smb_wct);
3881 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3883 /* maybe its not chained */
3884 if (smb_com2 == 0xFF) {
3885 CVAL(outbuf,smb_vwv0) = 0xFF;
3889 if (chain_size == 0) {
3890 /* this is the first part of the chain */
3892 orig_outbuf = outbuf;
3895 /* we need to tell the client where the next part of the reply will be */
3896 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3897 CVAL(outbuf,smb_vwv0) = smb_com2;
3899 /* remember how much the caller added to the chain, only counting stuff
3900 after the parameter words */
3901 chain_size += outsize - smb_wct;
3903 /* work out pointers into the original packets. The
3904 headers on these need to be filled in */
3905 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3906 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3908 /* remember the original command type */
3909 smb_com1 = CVAL(orig_inbuf,smb_com);
3911 /* save the data which will be overwritten by the new headers */
3912 memcpy(inbuf_saved,inbuf2,smb_wct);
3913 memcpy(outbuf_saved,outbuf2,smb_wct);
3915 /* give the new packet the same header as the last part of the SMB */
3916 memmove(inbuf2,inbuf,smb_wct);
3918 /* create the in buffer */
3919 CVAL(inbuf2,smb_com) = smb_com2;
3921 /* create the out buffer */
3922 bzero(outbuf2,smb_size);
3923 set_message(outbuf2,0,0,True);
3924 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3926 memcpy(outbuf2+4,inbuf2+4,4);
3927 CVAL(outbuf2,smb_rcls) = SUCCESS;
3928 CVAL(outbuf2,smb_reh) = 0;
3929 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3931 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3932 SSVAL(outbuf2,smb_err,SUCCESS);
3933 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3934 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3935 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3936 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3938 DEBUG(3,("Chained message\n"));
3941 /* process the request */
3942 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3943 bufsize-chain_size);
3945 /* copy the new reply and request headers over the old ones, but
3946 preserve the smb_com field */
3947 memmove(orig_outbuf,outbuf2,smb_wct);
3948 CVAL(orig_outbuf,smb_com) = smb_com1;
3950 /* restore the saved data, being careful not to overwrite any
3951 data from the reply header */
3952 memcpy(inbuf2,inbuf_saved,smb_wct);
3954 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3955 if (ofs < 0) ofs = 0;
3956 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3964 /****************************************************************************
3965 construct a reply to the incoming packet
3966 ****************************************************************************/
3967 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3969 int type = CVAL(inbuf,smb_com);
3971 int msg_type = CVAL(inbuf,0);
3972 extern int chain_size;
3974 smb_last_time = time(NULL);
3979 bzero(outbuf,smb_size);
3982 return(reply_special(inbuf,outbuf));
3984 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3985 set_message(outbuf,0,0,True);
3987 memcpy(outbuf+4,inbuf+4,4);
3988 CVAL(outbuf,smb_rcls) = SUCCESS;
3989 CVAL(outbuf,smb_reh) = 0;
3990 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3992 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3993 SSVAL(outbuf,smb_err,SUCCESS);
3994 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3995 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3996 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3997 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3999 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4001 outsize += chain_size;
4004 smb_setlen(outbuf,outsize - 4);
4008 /****************************************************************************
4009 process an smb from the client - split out from the process() code so
4010 it can be used by the oplock break code.
4011 ****************************************************************************/
4013 static void process_smb(char *InBuffer, char *OutBuffer)
4016 static int trans_num = 0;
4018 int msg_type = CVAL(InBuffer,0);
4019 int32 len = smb_len(InBuffer);
4020 int nread = len + 4;
4022 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
4023 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
4026 if(trans_num == 1 && VT_Check(InBuffer))
4036 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
4040 if (CVAL(OutBuffer,0) == 0)
4041 show_msg(OutBuffer);
4043 if (nread != smb_len(OutBuffer) + 4)
4045 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
4046 nread, smb_len(OutBuffer)));
4049 send_smb(Client,OutBuffer);
4054 /****************************************************************************
4055 process commands from the client
4056 ****************************************************************************/
4057 static void process(void)
4061 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4062 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4063 if ((InBuffer == NULL) || (OutBuffer == NULL))
4066 InBuffer += SMB_ALIGNMENT;
4067 OutBuffer += SMB_ALIGNMENT;
4070 DEBUG(3,("priming nmbd\n"));
4073 ip = *interpret_addr2("localhost");
4074 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4076 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4082 int deadtime = lp_deadtime()*60;
4084 int last_keepalive=0;
4085 int service_load_counter = 0;
4087 BOOL got_smb = False;
4088 #endif /* USE_OPLOCKS */
4091 deadtime = DEFAULT_SMBD_TIMEOUT;
4093 if (lp_readprediction())
4094 do_read_prediction();
4098 for (counter=SMBD_SELECT_LOOP;
4100 !receive_message_or_smb(Client,oplock_sock,
4101 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4102 #else /* USE_OPLOCKS */
4103 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
4104 #endif /* USE_OPLOCKS */
4105 counter += SMBD_SELECT_LOOP)
4109 BOOL allidle = True;
4110 extern int keepalive;
4112 if (counter > 365 * 3600) /* big number of seconds. */
4115 service_load_counter = 0;
4118 if (smb_read_error == READ_EOF)
4120 DEBUG(3,("end of file from client\n"));
4124 if (smb_read_error == READ_ERROR)
4126 DEBUG(3,("receive_smb error (%s) exiting\n",
4133 /* become root again if waiting */
4136 /* check for smb.conf reload */
4137 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4139 service_load_counter = counter;
4141 /* reload services, if files have changed. */
4142 reload_services(True);
4145 /* automatic timeout if all connections are closed */
4146 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4148 DEBUG(2,("%s Closing idle connection\n",timestring()));
4152 if (keepalive && (counter-last_keepalive)>keepalive)
4154 extern int password_client;
4155 if (!send_keepalive(Client))
4157 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4160 /* also send a keepalive to the password server if its still
4162 if (password_client != -1)
4163 send_keepalive(password_client);
4164 last_keepalive = counter;
4167 /* check for connection timeouts */
4168 for (i=0;i<MAX_CONNECTIONS;i++)
4169 if (Connections[i].open)
4171 /* close dirptrs on connections that are idle */
4172 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4175 if (Connections[i].num_files_open > 0 ||
4176 (t-Connections[i].lastused)<deadtime)
4180 if (allidle && num_connections_open>0)
4182 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4189 #endif /* USE_OPLOCKS */
4190 process_smb(InBuffer, OutBuffer);
4193 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4194 #endif /* USE_OPLOCKS */
4199 /****************************************************************************
4200 initialise connect, service and file structs
4201 ****************************************************************************/
4202 static void init_structs(void )
4205 get_myname(myhostname,NULL);
4207 for (i=0;i<MAX_CONNECTIONS;i++)
4209 Connections[i].open = False;
4210 Connections[i].num_files_open=0;
4211 Connections[i].lastused=0;
4212 Connections[i].used=False;
4213 string_init(&Connections[i].user,"");
4214 string_init(&Connections[i].dirpath,"");
4215 string_init(&Connections[i].connectpath,"");
4216 string_init(&Connections[i].origpath,"");
4219 for (i=0;i<MAX_OPEN_FILES;i++)
4221 Files[i].open = False;
4222 string_init(&Files[i].name,"");
4226 for (i=0;i<MAX_OPEN_FILES;i++)
4228 file_fd_struct *fd_ptr = &FileFd[i];
4229 fd_ptr->ref_count = 0;
4230 fd_ptr->dev = (int32)-1;
4231 fd_ptr->inode = (int32)-1;
4233 fd_ptr->fd_readonly = -1;
4234 fd_ptr->fd_writeonly = -1;
4235 fd_ptr->real_open_flags = -1;
4241 /****************************************************************************
4242 usage on the program
4243 ****************************************************************************/
4244 static void usage(char *pname)
4246 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4248 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4249 printf("Version %s\n",VERSION);
4250 printf("\t-D become a daemon\n");
4251 printf("\t-p port listen on the specified port\n");
4252 printf("\t-d debuglevel set the debuglevel\n");
4253 printf("\t-l log basename. Basename for log/debug files\n");
4254 printf("\t-s services file. Filename of services file\n");
4255 printf("\t-P passive only\n");
4256 printf("\t-a overwrite log file, don't append\n");
4261 /****************************************************************************
4263 ****************************************************************************/
4264 int main(int argc,char *argv[])
4266 extern BOOL append_log;
4267 /* shall I run as a daemon */
4268 BOOL is_daemon = False;
4269 int port = SMB_PORT;
4271 extern char *optarg;
4272 char pidFile[100] = { 0 };
4274 #ifdef NEED_AUTH_PARAMETERS
4275 set_auth_parameters(argc,argv);
4286 strcpy(debugf,SMBLOGFILE);
4288 setup_logging(argv[0],False);
4290 charset_initialise();
4292 /* make absolutely sure we run as root - to handle cases whre people
4293 are crazy enough to have it setuid */
4303 fault_setup(exit_server);
4304 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4306 /* we want total control over the permissions on created files,
4307 so set our umask to 0 */
4314 /* this is for people who can't start the program correctly */
4315 while (argc > 1 && (*argv[1] != '-'))
4321 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4325 strncpy(pidFile, optarg, sizeof(pidFile));
4328 strcpy(user_socket_options,optarg);
4331 strcpy(scope,optarg);
4335 extern BOOL passive;
4340 strcpy(servicesf,optarg);
4343 strcpy(debugf,optarg);
4347 extern BOOL append_log;
4348 append_log = !append_log;
4358 DEBUGLEVEL = atoi(optarg);
4361 port = atoi(optarg);
4374 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4375 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4377 #ifndef NO_GETRLIMIT
4378 #ifdef RLIMIT_NOFILE
4381 getrlimit(RLIMIT_NOFILE, &rlp);
4382 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4383 setrlimit(RLIMIT_NOFILE, &rlp);
4384 getrlimit(RLIMIT_NOFILE, &rlp);
4385 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4391 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4392 getuid(),getgid(),geteuid(),getegid()));
4394 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4396 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4402 if (!reload_services(False))
4405 codepage_initialise(lp_client_code_page());
4407 strcpy(myworkgroup, lp_workgroup());
4409 #ifndef NO_SIGNAL_TEST
4410 signal(SIGHUP,SIGNAL_CAST sig_hup);
4413 DEBUG(3,("%s loaded services\n",timestring()));
4415 if (!is_daemon && !is_a_socket(0))
4417 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4423 DEBUG(3,("%s becoming a daemon\n",timestring()));
4432 if ((fd = open(pidFile,
4436 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4438 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4441 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4443 DEBUG(0,("ERROR: smbd is already running\n"));
4446 sprintf(buf, "%u\n", (unsigned int) getpid());
4447 if (write(fd, buf, strlen(buf)) < 0)
4449 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4452 /* Leave pid file open & locked for the duration... */
4455 if (!open_sockets(is_daemon,port))
4458 #ifdef FAST_SHARE_MODES
4459 if (!start_share_mode_mgmt())
4461 #endif /* FAST_SHARE_MODES */
4463 /* possibly reload the services file. */
4464 reload_services(True);
4466 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4470 if (sys_chroot(lp_rootdir()) == 0)
4471 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4475 /* Setup the oplock IPC socket. */
4476 if(!open_oplock_ipc())
4478 #endif /* USE_OPLOCKS */
4483 exit_server("normal exit");