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 /* Current number of oplocks we have outstanding. */
92 uint32 oplocks_open = 0;
93 #endif /* USE_OPLOCKS */
95 extern fstring remote_machine;
99 /* these can be set by some functions to override the error codes */
100 int unix_ERR_class=SUCCESS;
104 extern int extra_time_offset;
106 extern pstring myhostname;
108 static int find_free_connection(int hash);
110 /* for readability... */
111 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
112 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
113 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
114 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
115 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
117 /****************************************************************************
118 when exiting, take the whole family
119 ****************************************************************************/
122 exit_server("caught signal");
123 return 0; /* Keep -Wall happy :-) */
125 /****************************************************************************
126 Send a SIGTERM to our process group.
127 *****************************************************************************/
130 if(am_parent) kill(0,SIGTERM);
133 /****************************************************************************
134 change a dos mode to a unix mode
135 base permission for files:
136 everybody gets read bit set
137 dos readonly is represented in unix by removing everyone's write bit
138 dos archive is represented in unix by the user's execute bit
139 dos system is represented in unix by the group's execute bit
140 dos hidden is represented in unix by the other's execute bit
141 Then apply create mask,
143 base permission for directories:
144 dos directory is represented in unix by unix's dir bit and the exec bit
145 Then apply create mask,
147 ****************************************************************************/
148 mode_t unix_mode(int cnum,int dosmode)
150 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
152 if ( !IS_DOS_READONLY(dosmode) )
153 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
155 if (IS_DOS_DIR(dosmode)) {
156 /* We never make directories read only for the owner as under DOS a user
157 can always create a file in a read-only directory. */
158 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
159 /* Apply directory mask */
160 result &= lp_dir_mode(SNUM(cnum));
161 /* Add in force bits */
162 result |= lp_force_dir_mode(SNUM(cnum));
164 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
167 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
170 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
173 /* Apply mode mask */
174 result &= lp_create_mode(SNUM(cnum));
175 /* Add in force bits */
176 result |= lp_force_create_mode(SNUM(cnum));
182 /****************************************************************************
183 change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
188 extern struct current_user current_user;
190 DEBUG(5,("dos_mode: %d %s\n", cnum, path));
192 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
193 if (!((sbuf->st_mode & S_IWOTH) ||
194 Connections[cnum].admin_user ||
195 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
196 ((sbuf->st_mode & S_IWGRP) &&
197 in_group(sbuf->st_gid,current_user.gid,
198 current_user.ngroups,current_user.igroups))))
201 if ((sbuf->st_mode & S_IWUSR) == 0)
205 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
208 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
211 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
214 if (S_ISDIR(sbuf->st_mode))
215 result = aDIR | (result & aRONLY);
218 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
222 /* hide files with a name starting with a . */
223 if (lp_hide_dot_files(SNUM(cnum)))
225 char *p = strrchr(path,'/');
231 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
235 /* Optimization : Only call is_hidden_path if it's not already
237 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
242 DEBUG(5,("dos_mode returning "));
244 if (result & aHIDDEN) DEBUG(5, ("h"));
245 if (result & aRONLY ) DEBUG(5, ("r"));
246 if (result & aSYSTEM) DEBUG(5, ("s"));
247 if (result & aDIR ) DEBUG(5, ("d"));
248 if (result & aARCH ) DEBUG(5, ("a"));
256 /*******************************************************************
257 chmod a file - but preserve some bits
258 ********************************************************************/
259 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
268 if (sys_stat(fname,st)) return(-1);
271 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
273 if (dos_mode(cnum,fname,st) == dosmode) return(0);
275 unixmode = unix_mode(cnum,dosmode);
277 /* preserve the s bits */
278 mask |= (S_ISUID | S_ISGID);
280 /* preserve the t bit */
285 /* possibly preserve the x bits */
286 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
287 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
288 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
290 unixmode |= (st->st_mode & mask);
292 /* if we previously had any r bits set then leave them alone */
293 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
294 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
298 /* if we previously had any w bits set then leave them alone
299 if the new mode is not rdonly */
300 if (!IS_DOS_READONLY(dosmode) &&
301 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
302 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
306 return(sys_chmod(fname,unixmode));
310 /****************************************************************************
311 check if two filenames are equal
313 this needs to be careful about whether we are case sensitive
314 ****************************************************************************/
315 static BOOL fname_equal(char *name1, char *name2)
317 int l1 = strlen(name1);
318 int l2 = strlen(name2);
320 /* handle filenames ending in a single dot */
321 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
325 ret = fname_equal(name1,name2);
330 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
334 ret = fname_equal(name1,name2);
339 /* now normal filename handling */
341 return(strcmp(name1,name2) == 0);
343 return(strequal(name1,name2));
347 /****************************************************************************
348 mangle the 2nd name and check if it is then equal to the first name
349 ****************************************************************************/
350 static BOOL mangled_equal(char *name1, char *name2)
354 if (is_8_3(name2, True))
357 strcpy(tmpname,name2);
358 mangle_name_83(tmpname);
360 return(strequal(name1,tmpname));
364 /****************************************************************************
365 scan a directory to find a filename, matching without case sensitivity
367 If the name looks like a mangled name then try via the mangling functions
368 ****************************************************************************/
369 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
376 mangled = is_mangled(name);
378 /* handle null paths */
382 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
388 check_mangled_stack(name);
390 /* open the directory */
391 if (!(cur_dir = OpenDir(cnum, path, True)))
393 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
397 /* now scan for matching names */
398 while ((dname = ReadDirName(cur_dir)))
401 (strequal(dname,".") || strequal(dname,"..")))
404 pstrcpy(name2,dname);
405 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
407 if ((mangled && mangled_equal(name,name2))
408 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
410 /* we've found the file, change it's name and return */
411 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
422 /****************************************************************************
423 This routine is called to convert names from the dos namespace to unix
424 namespace. It needs to handle any case conversions, mangling, format
427 We assume that we have already done a chdir() to the right "root" directory
430 The function will return False if some part of the name except for the last
431 part cannot be resolved
433 If the saved_last_component != 0, then the unmodified last component
434 of the pathname is returned there. This is used in an exceptional
435 case in reply_mv (so far). If saved_last_component == 0 then nothing
438 The bad_path arg is set to True if the filename walk failed. This is
439 used to pick the correct error code to return between ENOENT and ENOTDIR
440 as Windows applications depend on ERRbadpath being returned if a component
441 of a pathname does not exist.
442 ****************************************************************************/
443 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
453 if(saved_last_component)
454 *saved_last_component = 0;
456 /* convert to basic unix format - removing \ chars and cleaning it up */
458 unix_clean_name(name);
460 /* names must be relative to the root of the service - trim any leading /.
461 also trim trailing /'s */
462 trim_string(name,"/","/");
465 * Ensure saved_last_component is valid even if file exists.
467 if(saved_last_component) {
468 end = strrchr(name, '/');
470 strcpy(saved_last_component, end + 1);
472 strcpy(saved_last_component, name);
475 if (!case_sensitive &&
476 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
479 /* check if it's a printer file */
480 if (Connections[cnum].printer)
482 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
486 sprintf(name2,"%.6s.XXXXXX",remote_machine);
487 /* sanitise the name */
488 for (s=name2 ; *s ; s++)
489 if (!issafe(*s)) *s = '_';
490 strcpy(name,(char *)mktemp(name2));
495 /* stat the name - if it exists then we are all done! */
496 if (sys_stat(name,&st) == 0)
501 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
503 /* a special case - if we don't have any mangling chars and are case
504 sensitive then searching won't help */
505 if (case_sensitive && !is_mangled(name) &&
506 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
509 /* now we need to recursively match the name against the real
510 directory structure */
513 while (strncmp(start,"./",2) == 0)
516 /* now match each part of the path name separately, trying the names
517 as is first, then trying to scan the directory for matching names */
518 for (;start;start = (end?end+1:(char *)NULL))
520 /* pinpoint the end of this section of the filename */
521 end = strchr(start, '/');
523 /* chop the name at this point */
526 if(saved_last_component != 0)
527 strcpy(saved_last_component, end ? end + 1 : start);
529 /* check if the name exists up to this point */
530 if (sys_stat(name, &st) == 0)
532 /* it exists. it must either be a directory or this must be
533 the last part of the path for it to be OK */
534 if (end && !(st.st_mode & S_IFDIR))
536 /* an intermediate part of the name isn't a directory */
537 DEBUG(5,("Not a dir %s\n",start));
548 /* remember the rest of the pathname so it can be restored
550 if (end) pstrcpy(rest,end+1);
552 /* try to find this part of the path in the directory */
553 if (strchr(start,'?') || strchr(start,'*') ||
554 !scan_directory(dirpath, start, cnum, end?True:False))
558 /* an intermediate part of the name can't be found */
559 DEBUG(5,("Intermediate not found %s\n",start));
561 /* We need to return the fact that the intermediate
562 name resolution failed. This is used to return an
563 error of ERRbadpath rather than ERRbadfile. Some
564 Windows applications depend on the difference between
571 /* just the last part of the name doesn't exist */
572 /* we may need to strupper() or strlower() it in case
573 this conversion is being used for file creation
575 /* if the filename is of mixed case then don't normalise it */
576 if (!case_preserve &&
577 (!strhasupper(start) || !strhaslower(start)))
580 /* check on the mangled stack to see if we can recover the
581 base of the filename */
582 if (is_mangled(start))
583 check_mangled_stack(start);
585 DEBUG(5,("New file %s\n",start));
589 /* restore the rest of the string */
592 strcpy(start+strlen(start)+1,rest);
593 end = start + strlen(start);
597 /* add to the dirpath that we have resolved so far */
598 if (*dirpath) strcat(dirpath,"/");
599 strcat(dirpath,start);
601 /* restore the / that we wiped out earlier */
605 /* the name has been resolved */
606 DEBUG(5,("conversion finished %s\n",name));
611 /****************************************************************************
612 normalise for DOS usage
613 ****************************************************************************/
614 static void disk_norm(int *bsize,int *dfree,int *dsize)
616 /* check if the disk is beyond the max disk size */
617 int maxdisksize = lp_maxdisksize();
619 /* convert to blocks - and don't overflow */
620 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
621 if (*dsize > maxdisksize) *dsize = maxdisksize;
622 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
627 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
632 if (*bsize > WORDMAX )
635 if (*dsize > WORDMAX)
637 if (*dfree > WORDMAX)
644 /****************************************************************************
645 return number of 1K blocks available on a path and total number
646 ****************************************************************************/
647 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
649 char *df_command = lp_dfree_command();
670 /* possibly use system() to get the result */
671 if (df_command && *df_command)
677 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
678 sprintf(syscmd,"%s %s",df_command,path);
679 standard_sub_basic(syscmd);
681 ret = smbrun(syscmd,outfile,False);
682 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
685 FILE *f = fopen(outfile,"r");
691 fscanf(f,"%d %d %d",dsize,dfree,bsize);
695 DEBUG(0,("Can't open %s\n",outfile));
699 disk_norm(bsize,dfree,dsize);
700 dfree_retval = ((*bsize)/1024)*(*dfree);
702 /* Ensure we return the min value between the users quota and
703 what's free on the disk. Thanks to Albrecht Gebhardt
704 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
706 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
708 disk_norm(&bsizeq, &dfreeq, &dsizeq);
709 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
710 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
711 dfree_retval : dfreeq_retval ;
712 /* maybe dfree and dfreeq are calculated using different bsizes
713 so convert dfree from bsize into bsizeq */
714 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
715 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
720 return(dfree_retval);
724 DEBUG(1,("Warning - no statfs function\n"));
728 if (statfs(path,&fs,sizeof(fs),0) != 0)
731 if (statvfs(path, &fs))
734 if (statfs(path,&fs,sizeof(fs)) == -1)
736 if (statfs(path,&fs) == -1)
738 #endif /* USE_STATVFS */
741 DEBUG(3,("dfree call failed code errno=%d\n",errno));
745 return(((*bsize)/1024)*(*dfree));
750 *dfree = fs.fd_req.bfree;
751 *dsize = fs.fd_req.btot;
754 *bsize = fs.f_frsize;
757 /* eg: osf1 has f_fsize = fundamental filesystem block size,
758 f_bsize = optimal transfer block size (MX: 94-04-19) */
763 #endif /* USE_STATVFS */
768 *dfree = fs.f_bavail;
770 *dsize = fs.f_blocks;
773 #if defined(SCO) || defined(ISC) || defined(MIPS)
777 /* handle rediculous bsize values - some OSes are broken */
778 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
780 disk_norm(bsize,dfree,dsize);
786 DEBUG(0,("dfree seems to be broken on your system\n"));
787 *dsize = 20*1024*1024/(*bsize);
788 *dfree = MAX(1,*dfree);
790 dfree_retval = ((*bsize)/1024)*(*dfree);
792 /* Ensure we return the min value between the users quota and
793 what's free on the disk. Thanks to Albrecht Gebhardt
794 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
796 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
798 disk_norm(&bsizeq, &dfreeq, &dsizeq);
799 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
800 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
801 dfree_retval : dfreeq_retval ;
802 /* maybe dfree and dfreeq are calculated using different bsizes
803 so convert dfree from bsize into bsizeq */
804 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
805 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
810 return(dfree_retval);
815 /****************************************************************************
816 wrap it to get filenames right
817 ****************************************************************************/
818 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
820 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
825 /****************************************************************************
826 check a filename - possibly caling reducename
828 This is called by every routine before it allows an operation on a filename.
829 It does any final confirmation necessary to ensure that the filename is
830 a valid one for the user to access.
831 ****************************************************************************/
832 BOOL check_name(char *name,int cnum)
838 if( IS_VETO_PATH(cnum, name))
840 DEBUG(5,("file path name %s vetoed\n",name));
844 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
846 /* Check if we are allowing users to follow symlinks */
847 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
848 University of Geneva */
850 if (!lp_symlinks(SNUM(cnum)))
853 if ( (sys_lstat(name,&statbuf) != -1) &&
854 (S_ISLNK(statbuf.st_mode)) )
856 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
862 DEBUG(5,("check_name on %s failed\n",name));
867 /****************************************************************************
868 check a filename - possibly caling reducename
869 ****************************************************************************/
870 static void check_for_pipe(char *fname)
872 /* special case of pipe opens */
876 if (strstr(s,"pipe/"))
878 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
879 unix_ERR_class = ERRSRV;
880 unix_ERR_code = ERRaccess;
884 /****************************************************************************
885 fd support routines - attempt to do a sys_open
886 ****************************************************************************/
888 int fd_attempt_open(char *fname, int flags, int mode)
890 int fd = sys_open(fname,flags,mode);
892 /* Fix for files ending in '.' */
893 if((fd == -1) && (errno == ENOENT) &&
894 (strchr(fname,'.')==NULL))
897 fd = sys_open(fname,flags,mode);
900 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
901 if ((fd == -1) && (errno == ENAMETOOLONG))
904 char *p = strrchr(fname, '/');
906 if (p == fname) /* name is "/xxx" */
908 max_len = pathconf("/", _PC_NAME_MAX);
911 else if ((p == NULL) || (p == fname))
914 max_len = pathconf(".", _PC_NAME_MAX);
919 max_len = pathconf(fname, _PC_NAME_MAX);
923 if (strlen(p) > max_len)
925 char tmp = p[max_len];
928 if ((fd = sys_open(fname,flags,mode)) == -1)
936 /****************************************************************************
937 fd support routines - attempt to find an already open file by dev
938 and inode - increments the ref_count of the returned file_fd_struct *.
939 ****************************************************************************/
940 file_fd_struct *fd_get_already_open(struct stat *sbuf)
943 file_fd_struct *fd_ptr;
948 for(i = 0; i <= max_file_fd_used; i++) {
950 if((fd_ptr->ref_count > 0) &&
951 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
952 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
955 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
956 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
963 /****************************************************************************
964 fd support routines - attempt to find a empty slot in the FileFd array.
965 Increments the ref_count of the returned entry.
966 ****************************************************************************/
967 file_fd_struct *fd_get_new()
970 file_fd_struct *fd_ptr;
972 for(i = 0; i < MAX_OPEN_FILES; i++) {
974 if(fd_ptr->ref_count == 0) {
975 fd_ptr->dev = (uint32)-1;
976 fd_ptr->inode = (uint32)-1;
978 fd_ptr->fd_readonly = -1;
979 fd_ptr->fd_writeonly = -1;
980 fd_ptr->real_open_flags = -1;
982 /* Increment max used counter if neccessary, cuts down
983 on search time when re-using */
984 if(i > max_file_fd_used)
985 max_file_fd_used = i;
986 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
987 i, fd_ptr->dev, fd_ptr->inode));
991 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
996 /****************************************************************************
997 fd support routines - attempt to re-open an already open fd as O_RDWR.
998 Save the already open fd (we cannot close due to POSIX file locking braindamage.
999 ****************************************************************************/
1001 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1003 int fd = sys_open( fname, O_RDWR, mode);
1008 if(fd_ptr->real_open_flags == O_RDONLY)
1009 fd_ptr->fd_readonly = fd_ptr->fd;
1010 if(fd_ptr->real_open_flags == O_WRONLY)
1011 fd_ptr->fd_writeonly = fd_ptr->fd;
1014 fd_ptr->real_open_flags = O_RDWR;
1017 /****************************************************************************
1018 fd support routines - attempt to close the file referenced by this fd.
1019 Decrements the ref_count and returns it.
1020 ****************************************************************************/
1021 int fd_attempt_close(file_fd_struct *fd_ptr)
1023 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1024 fd_ptr - &FileFd[0],
1025 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1026 fd_ptr->real_open_flags,
1027 fd_ptr->ref_count));
1028 if(fd_ptr->ref_count > 0) {
1029 fd_ptr->ref_count--;
1030 if(fd_ptr->ref_count == 0) {
1031 if(fd_ptr->fd != -1)
1033 if(fd_ptr->fd_readonly != -1)
1034 close(fd_ptr->fd_readonly);
1035 if(fd_ptr->fd_writeonly != -1)
1036 close(fd_ptr->fd_writeonly);
1038 fd_ptr->fd_readonly = -1;
1039 fd_ptr->fd_writeonly = -1;
1040 fd_ptr->real_open_flags = -1;
1041 fd_ptr->dev = (uint32)-1;
1042 fd_ptr->inode = (uint32)-1;
1045 return fd_ptr->ref_count;
1048 /****************************************************************************
1050 ****************************************************************************/
1051 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1053 extern struct current_user current_user;
1055 struct stat statbuf;
1056 file_fd_struct *fd_ptr;
1057 files_struct *fsp = &Files[fnum];
1063 pstrcpy(fname,fname1);
1065 /* check permissions */
1066 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1068 DEBUG(3,("Permission denied opening %s\n",fname));
1069 check_for_pipe(fname);
1073 /* this handles a bug in Win95 - it doesn't say to create the file when it
1075 if (Connections[cnum].printer)
1079 if (flags == O_WRONLY)
1080 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1083 #if UTIME_WORKAROUND
1084 /* XXXX - is this OK?? */
1085 /* this works around a utime bug but can cause other problems */
1086 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1091 * Ensure we have a valid struct stat so we can search the
1095 if(stat(fname, &statbuf) < 0) {
1096 if(errno != ENOENT) {
1097 DEBUG(3,("Error doing stat on file %s (%s)\n",
1098 fname,strerror(errno)));
1100 check_for_pipe(fname);
1110 * Check to see if we have this file already
1111 * open. If we do, just use the already open fd and increment the
1112 * reference count (fd_get_already_open increments the ref_count).
1114 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1116 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1118 /* File was already open. */
1119 if((flags & O_CREAT) && (flags & O_EXCL)) {
1120 fd_ptr->ref_count--;
1126 * If not opened O_RDWR try
1127 * and do that here - a chmod may have been done
1128 * between the last open and now.
1130 if(fd_ptr->real_open_flags != O_RDWR)
1131 fd_attempt_reopen(fname, mode, fd_ptr);
1134 * Ensure that if we wanted write access
1135 * it has been opened for write, and if we wanted read it
1136 * was open for read.
1138 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1139 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1140 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1141 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1142 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1143 check_for_pipe(fname);
1144 fd_ptr->ref_count--;
1150 /* We need to allocate a new file_fd_struct (this increments the
1152 if((fd_ptr = fd_get_new()) == 0)
1155 * Whatever the requested flags, attempt read/write access,
1156 * as we don't know what flags future file opens may require.
1157 * If this fails, try again with the required flags.
1158 * Even if we open read/write when only read access was
1159 * requested the setting of the can_write flag in
1160 * the file_struct will protect us from errant
1161 * write requests. We never need to worry about O_APPEND
1162 * as this is not set anywhere in Samba.
1164 fd_ptr->real_open_flags = O_RDWR;
1165 /* Set the flags as needed without the read/write modes. */
1166 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1167 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1169 * On some systems opening a file for R/W access on a read only
1170 * filesystems sets errno to EROFS.
1173 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1174 #else /* No EROFS */
1175 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1177 if(flags & O_WRONLY) {
1178 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1179 fd_ptr->real_open_flags = O_WRONLY;
1181 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1182 fd_ptr->real_open_flags = O_RDONLY;
1187 if ((fd_ptr->fd >=0) &&
1188 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1192 pstrcpy(dname,fname);
1193 p = strrchr(dname,'/');
1195 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1196 lp_minprintspace(SNUM(cnum))) {
1197 fd_attempt_close(fd_ptr);
1199 if(fd_ptr->ref_count == 0)
1208 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1209 fname,strerror(errno),flags));
1210 /* Ensure the ref_count is decremented. */
1211 fd_attempt_close(fd_ptr);
1212 check_for_pipe(fname);
1216 if (fd_ptr->fd >= 0)
1220 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1221 /* Error - backout !! */
1222 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1223 fd_ptr->fd, fname,strerror(errno)));
1224 /* Ensure the ref_count is decremented. */
1225 fd_attempt_close(fd_ptr);
1230 /* Set the correct entries in fd_ptr. */
1231 fd_ptr->dev = (uint32)sbuf->st_dev;
1232 fd_ptr->inode = (uint32)sbuf->st_ino;
1234 fsp->fd_ptr = fd_ptr;
1235 Connections[cnum].num_files_open++;
1236 fsp->mode = sbuf->st_mode;
1237 GetTimeOfDay(&fsp->open_time);
1238 fsp->uid = current_user.id;
1242 fsp->mmap_ptr = NULL;
1244 fsp->can_lock = True;
1245 fsp->can_read = ((flags & O_WRONLY)==0);
1246 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1247 fsp->share_mode = 0;
1248 fsp->print_file = Connections[cnum].printer;
1249 fsp->modified = False;
1250 fsp->granted_oplock = False;
1252 string_set(&fsp->name,dos_to_unix(fname,False));
1253 fsp->wbmpx_ptr = NULL;
1256 * If the printer is marked as postscript output a leading
1257 * file identifier to ensure the file is treated as a raw
1259 * This has a similar effect as CtrlD=0 in WIN.INI file.
1260 * tim@fsg.com 09/06/94
1262 if (fsp->print_file && POSTSCRIPT(cnum) &&
1265 DEBUG(3,("Writing postscript line\n"));
1266 write_file(fnum,"%!\n",3);
1269 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1270 timestring(),Connections[cnum].user,fname,
1271 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1272 Connections[cnum].num_files_open,fnum));
1277 /* mmap it if read-only */
1278 if (!fsp->can_write)
1280 fsp->mmap_size = file_size(fname);
1281 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1282 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1284 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1286 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1287 fsp->mmap_ptr = NULL;
1293 /*******************************************************************
1295 ********************************************************************/
1296 void sync_file(int fnum)
1299 fsync(Files[fnum].fd_ptr->fd);
1303 /****************************************************************************
1304 run a file if it is a magic script
1305 ****************************************************************************/
1306 static void check_magic(int fnum,int cnum)
1308 if (!*lp_magicscript(SNUM(cnum)))
1311 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1315 if (!(p = strrchr(Files[fnum].name,'/')))
1316 p = Files[fnum].name;
1320 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1326 pstring magic_output;
1328 pstrcpy(fname,Files[fnum].name);
1330 if (*lp_magicoutput(SNUM(cnum)))
1331 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1333 sprintf(magic_output,"%s.out",fname);
1336 ret = smbrun(fname,magic_output,False);
1337 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1343 /****************************************************************************
1344 close a file - possibly invalidating the read prediction
1345 ****************************************************************************/
1346 void close_file(int fnum)
1348 files_struct *fs_p = &Files[fnum];
1349 int cnum = fs_p->cnum;
1350 uint32 dev = fs_p->fd_ptr->dev;
1351 uint32 inode = fs_p->fd_ptr->inode;
1352 share_lock_token token;
1354 invalidate_read_prediction(fs_p->fd_ptr->fd);
1356 Connections[cnum].num_files_open--;
1359 free((char *)fs_p->wbmpx_ptr);
1360 fs_p->wbmpx_ptr = NULL;
1366 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1367 fs_p->mmap_ptr = NULL;
1371 if (lp_share_modes(SNUM(cnum)))
1373 lock_share_entry( cnum, dev, inode, &token);
1374 del_share_mode(token, fnum);
1377 fd_attempt_close(fs_p->fd_ptr);
1379 if (lp_share_modes(SNUM(cnum)))
1380 unlock_share_entry( cnum, dev, inode, token);
1382 /* NT uses smbclose to start a print - weird */
1383 if (fs_p->print_file)
1386 /* check for magic scripts */
1387 check_magic(fnum,cnum);
1389 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1390 timestring(),Connections[cnum].user,fs_p->name,
1391 Connections[cnum].num_files_open));
1394 enum {AFAIL,AREAD,AWRITE,AALL};
1396 /*******************************************************************
1397 reproduce the share mode access table
1398 ********************************************************************/
1399 static int access_table(int new_deny,int old_deny,int old_mode,
1400 int share_pid,char *fname)
1402 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1404 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1405 if (old_deny == new_deny && share_pid == getpid())
1408 if (old_mode == 0) return(AREAD);
1410 /* the new smbpub.zip spec says that if the file extension is
1411 .com, .dll, .exe or .sym then allow the open. I will force
1412 it to read-only as this seems sensible although the spec is
1413 a little unclear on this. */
1414 if ((fname = strrchr(fname,'.'))) {
1415 if (strequal(fname,".com") ||
1416 strequal(fname,".dll") ||
1417 strequal(fname,".exe") ||
1418 strequal(fname,".sym"))
1428 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1429 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1430 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1433 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1434 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1435 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1438 if (old_deny==DENY_WRITE) return(AREAD);
1439 if (old_deny==DENY_READ) return(AWRITE);
1440 if (old_deny==DENY_NONE) return(AALL);
1446 /*******************************************************************
1447 check if the share mode on a file allows it to be deleted or unlinked
1448 return True if sharing doesn't prevent the operation
1449 ********************************************************************/
1450 BOOL check_file_sharing(int cnum,char *fname)
1454 min_share_mode_entry *old_shares = 0;
1455 int num_share_modes;
1457 share_lock_token token;
1460 if(!lp_share_modes(SNUM(cnum)))
1463 if (stat(fname,&sbuf) == -1) return(True);
1465 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1466 num_share_modes = get_share_modes(cnum, token,
1467 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1469 for( i = 0; i < num_share_modes; i++)
1471 if (old_shares[i].share_mode != DENY_DOS)
1474 if(old_shares[i].pid != pid)
1478 /* XXXX exactly what share mode combinations should be allowed for
1479 deleting/renaming? */
1480 /* If we got here then either there were no share modes or
1481 all share modes were DENY_DOS and the pid == getpid() */
1486 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1487 if(old_shares != NULL)
1488 free((char *)old_shares);
1492 /****************************************************************************
1494 Helper for open_file_shared.
1495 Truncate a file after checking locking; close file if locked.
1496 **************************************************************************/
1497 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1500 if (Files[fnum].can_write){
1501 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1502 /* If share modes are in force for this connection we
1503 have the share entry locked. Unlock it before closing. */
1504 if (*share_locked && lp_share_modes(SNUM(cnum)))
1505 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1506 Files[fnum].fd_ptr->inode, token);
1508 /* Share mode no longer locked. */
1509 *share_locked = False;
1511 unix_ERR_class = ERRDOS;
1512 unix_ERR_code = ERRlock;
1515 ftruncate(Files[fnum].fd_ptr->fd,0);
1519 /****************************************************************************
1520 check if we can open a file with a share mode
1521 ****************************************************************************/
1522 int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
1523 BOOL fcbopen, int *flags)
1525 int old_open_mode = share->share_mode &0xF;
1526 int old_deny_mode = (share->share_mode >>4)&7;
1528 if (old_deny_mode > 4 || old_open_mode > 2)
1530 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1531 deny_mode,old_deny_mode,old_open_mode,fname));
1536 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1539 if ((access_allowed == AFAIL) ||
1540 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1541 (access_allowed == AREAD && *flags == O_WRONLY) ||
1542 (access_allowed == AWRITE && *flags == O_RDONLY))
1544 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1545 deny_mode,old_deny_mode,old_open_mode,
1546 share->pid,fname, access_allowed));
1550 if (access_allowed == AREAD)
1553 if (access_allowed == AWRITE)
1560 /****************************************************************************
1561 open a file with a share mode
1562 ****************************************************************************/
1563 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1564 int mode,int oplock_request, int *Access,int *action)
1566 files_struct *fs_p = &Files[fnum];
1569 int deny_mode = (share_mode>>4)&7;
1571 BOOL file_existed = file_exist(fname,&sbuf);
1572 BOOL share_locked = False;
1573 BOOL fcbopen = False;
1574 share_lock_token token;
1581 /* this is for OS/2 EAs - try and say we don't support them */
1582 if (strstr(fname,".+,;=[]."))
1584 unix_ERR_class = ERRDOS;
1585 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1587 unix_ERR_code = ERRcannotopen;
1588 #else /* OS2_WPS_FIX */
1589 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1590 #endif /* OS2_WPS_FIX */
1595 if ((ofun & 0x3) == 0 && file_existed)
1603 if ((ofun & 0x3) == 2)
1606 /* note that we ignore the append flag as
1607 append does not mean the same thing under dos and unix */
1609 switch (share_mode&0xF)
1626 if (flags != O_RDONLY && file_existed &&
1627 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1637 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1639 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1644 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1646 if (lp_share_modes(SNUM(cnum)))
1650 min_share_mode_entry *old_shares = 0;
1654 dev = (uint32)sbuf.st_dev;
1655 inode = (uint32)sbuf.st_ino;
1656 lock_share_entry(cnum, dev, inode, &token);
1657 share_locked = True;
1658 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1662 * Check if the share modes will give us access.
1665 if(share_locked && (num_shares != 0))
1671 broke_oplock = False;
1672 for(i = 0; i < num_shares; i++)
1674 /* someone else has a share lock on it, check to see
1676 if(check_share_mode(&old_shares[i], deny_mode, fname, fcbopen, &flags) == False)
1678 free((char *)old_shares);
1679 unlock_share_entry(cnum, dev, inode, token);
1681 unix_ERR_class = ERRDOS;
1682 unix_ERR_code = ERRbadshare;
1687 * The share modes would give us access. Check if someone
1688 * has an oplock on this file. If so we must break it before
1691 if(old_shares[i].op_type != 0)
1693 /* Oplock break.... */
1694 unlock_share_entry(cnum, dev, inode, token);
1695 #if 0 /* Work in progress..... */
1698 free((char *)old_shares);
1699 /* Error condition here... */
1701 lock_share_entry(cnum, dev, inode, &token);
1702 broke_oplock = True;
1706 #endif /* USE_OPLOCKS */
1710 free((char *)old_shares);
1711 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1713 } while(broke_oplock);
1717 free((char *)old_shares);
1720 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1721 flags,flags2,mode));
1723 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1724 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1727 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1734 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1736 /* We created the file - thus we must now lock the share entry before creating it. */
1737 dev = fs_p->fd_ptr->dev;
1738 inode = fs_p->fd_ptr->inode;
1739 lock_share_entry(cnum, dev, inode, &token);
1740 share_locked = True;
1756 fs_p->share_mode = (deny_mode<<4) | open_mode;
1759 (*Access) = open_mode;
1763 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1764 if (!file_existed) *action = 2;
1765 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1767 /* We must create the share mode entry before truncate as
1768 truncate can fail due to locking and have to close the
1769 file (which expects the share_mode_entry to be there).
1771 if (lp_share_modes(SNUM(cnum)))
1772 set_share_mode(token, fnum, 0, 0);
1774 if ((flags2&O_TRUNC) && file_existed)
1775 truncate_unless_locked(fnum,cnum,token,&share_locked);
1778 if (share_locked && lp_share_modes(SNUM(cnum)))
1779 unlock_share_entry( cnum, dev, inode, token);
1782 /****************************************************************************
1783 seek a file. Try to avoid the seek if possible
1784 ****************************************************************************/
1785 int seek_file(int fnum,uint32 pos)
1788 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1791 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1793 return(Files[fnum].pos);
1796 /****************************************************************************
1798 ****************************************************************************/
1799 int read_file(int fnum,char *data,uint32 pos,int n)
1803 if (!Files[fnum].can_write)
1805 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1813 if (Files[fnum].mmap_ptr)
1815 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1818 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1830 if (seek_file(fnum,pos) != pos)
1832 DEBUG(3,("Failed to seek to %d\n",pos));
1837 readret = read(Files[fnum].fd_ptr->fd,data,n);
1838 if (readret > 0) ret += readret;
1845 /****************************************************************************
1847 ****************************************************************************/
1848 int write_file(int fnum,char *data,int n)
1850 if (!Files[fnum].can_write) {
1855 if (!Files[fnum].modified) {
1857 Files[fnum].modified = True;
1858 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1859 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1860 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1861 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1866 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1870 /****************************************************************************
1871 load parameters specific to a connection/service
1872 ****************************************************************************/
1873 BOOL become_service(int cnum,BOOL do_chdir)
1875 extern char magic_char;
1876 static int last_cnum = -1;
1879 if (!OPEN_CNUM(cnum))
1885 Connections[cnum].lastused = smb_last_time;
1890 ChDir(Connections[cnum].connectpath) != 0 &&
1891 ChDir(Connections[cnum].origpath) != 0)
1893 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1894 Connections[cnum].connectpath,cnum));
1898 if (cnum == last_cnum)
1903 case_default = lp_defaultcase(snum);
1904 case_preserve = lp_preservecase(snum);
1905 short_case_preserve = lp_shortpreservecase(snum);
1906 case_mangle = lp_casemangle(snum);
1907 case_sensitive = lp_casesensitive(snum);
1908 magic_char = lp_magicchar(snum);
1909 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1914 /****************************************************************************
1915 find a service entry
1916 ****************************************************************************/
1917 int find_service(char *service)
1921 string_sub(service,"\\","/");
1923 iService = lp_servicenumber(service);
1925 /* now handle the special case of a home directory */
1928 char *phome_dir = get_home_dir(service);
1929 DEBUG(3,("checking for home directory %s gave %s\n",service,
1930 phome_dir?phome_dir:"(NULL)"));
1934 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1936 lp_add_home(service,iHomeService,phome_dir);
1937 iService = lp_servicenumber(service);
1942 /* If we still don't have a service, attempt to add it as a printer. */
1945 int iPrinterService;
1947 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1951 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1953 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1955 DEBUG(3,("%s is a valid printer name\n", service));
1956 DEBUG(3,("adding %s as a printer service\n", service));
1957 lp_add_printer(service,iPrinterService);
1958 iService = lp_servicenumber(service);
1960 DEBUG(0,("failed to add %s as a printer service!\n", service));
1963 DEBUG(3,("%s is not a valid printer name\n", service));
1967 /* just possibly it's a default service? */
1970 char *defservice = lp_defaultservice();
1971 if (defservice && *defservice && !strequal(defservice,service)) {
1972 iService = find_service(defservice);
1973 if (iService >= 0) {
1974 string_sub(service,"_","/");
1975 iService = lp_add_service(service,iService);
1981 if (!VALID_SNUM(iService))
1983 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1988 DEBUG(3,("find_service() failed to find service %s\n", service));
1994 /****************************************************************************
1995 create an error packet from a cached error.
1996 ****************************************************************************/
1997 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1999 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2001 int32 eclass = wbmpx->wr_errclass;
2002 int32 err = wbmpx->wr_error;
2004 /* We can now delete the auxiliary struct */
2005 free((char *)wbmpx);
2006 Files[fnum].wbmpx_ptr = NULL;
2007 return error_packet(inbuf,outbuf,eclass,err,line);
2016 } unix_smb_errmap[] =
2018 {EPERM,ERRDOS,ERRnoaccess},
2019 {EACCES,ERRDOS,ERRnoaccess},
2020 {ENOENT,ERRDOS,ERRbadfile},
2021 {ENOTDIR,ERRDOS,ERRbaddirectory},
2022 {EIO,ERRHRD,ERRgeneral},
2023 {EBADF,ERRSRV,ERRsrverror},
2024 {EINVAL,ERRSRV,ERRsrverror},
2025 {EEXIST,ERRDOS,ERRfilexists},
2026 {ENFILE,ERRDOS,ERRnofids},
2027 {EMFILE,ERRDOS,ERRnofids},
2028 {ENOSPC,ERRHRD,ERRdiskfull},
2030 {EDQUOT,ERRHRD,ERRdiskfull},
2033 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2036 {EXDEV,ERRDOS,ERRdiffdevice},
2038 {EROFS,ERRHRD,ERRnowrite},
2042 /* Mapping for old clients. */
2049 enum remote_arch_types valid_ra_type;
2050 } old_client_errmap[] =
2052 {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT},
2056 /****************************************************************************
2057 create an error packet from errno
2058 ****************************************************************************/
2059 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2061 int eclass=def_class;
2065 if (unix_ERR_class != SUCCESS)
2067 eclass = unix_ERR_class;
2068 ecode = unix_ERR_code;
2069 unix_ERR_class = SUCCESS;
2074 while (unix_smb_errmap[i].smbclass != 0)
2076 if (unix_smb_errmap[i].unixerror == errno)
2078 eclass = unix_smb_errmap[i].smbclass;
2079 ecode = unix_smb_errmap[i].smbcode;
2086 /* Make sure we don't return error codes that old
2087 clients don't understand. */
2089 /* JRA - unfortunately, WinNT needs some error codes
2090 for apps to work correctly, Win95 will break if
2091 these error codes are returned. But they both
2092 negotiate the *same* protocol. So we need to use
2093 the revolting 'remote_arch' enum to tie break.
2095 There must be a better way of doing this...
2098 for(i = 0; old_client_errmap[i].new_smb_error != 0; i++)
2100 if(((Protocol < old_client_errmap[i].protocol_level) ||
2101 (old_client_errmap[i].valid_ra_type != get_remote_arch())) &&
2102 (old_client_errmap[i].new_smb_error == ecode))
2104 ecode = old_client_errmap[i].old_smb_error;
2109 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2113 /****************************************************************************
2114 create an error packet. Normally called using the ERROR() macro
2115 ****************************************************************************/
2116 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2118 int outsize = set_message(outbuf,0,0,True);
2120 cmd = CVAL(inbuf,smb_com);
2122 CVAL(outbuf,smb_rcls) = error_class;
2123 SSVAL(outbuf,smb_err,error_code);
2125 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2128 (int)CVAL(inbuf,smb_com),
2129 smb_fn_name(CVAL(inbuf,smb_com)),
2134 DEBUG(3,("error string = %s\n",strerror(errno)));
2140 #ifndef SIGCLD_IGNORE
2141 /****************************************************************************
2142 this prevents zombie child processes
2143 ****************************************************************************/
2144 static int sig_cld()
2146 static int depth = 0;
2149 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2155 BlockSignals(True,SIGCLD);
2156 DEBUG(5,("got SIGCLD\n"));
2159 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2163 /* Stevens, Adv. Unix Prog. says that on system V you must call
2164 wait before reinstalling the signal handler, because the kernel
2165 calls the handler from within the signal-call when there is a
2166 child that has exited. This would lead to an infinite recursion
2167 if done vice versa. */
2169 #ifndef DONT_REINSTALL_SIG
2170 #ifdef SIGCLD_IGNORE
2171 signal(SIGCLD, SIG_IGN);
2173 signal(SIGCLD, SIGNAL_CAST sig_cld);
2178 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2181 BlockSignals(False,SIGCLD);
2186 /****************************************************************************
2187 this is called when the client exits abruptly
2188 **************************************************************************/
2189 static int sig_pipe()
2191 extern int password_client;
2192 BlockSignals(True,SIGPIPE);
2194 if (password_client != -1) {
2195 DEBUG(3,("lost connection to password server\n"));
2196 close(password_client);
2197 password_client = -1;
2198 #ifndef DONT_REINSTALL_SIG
2199 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2201 BlockSignals(False,SIGPIPE);
2205 exit_server("Got sigpipe\n");
2209 /****************************************************************************
2210 open the socket communication
2211 ****************************************************************************/
2212 static BOOL open_sockets(BOOL is_daemon,int port)
2219 struct sockaddr addr;
2220 int in_addrlen = sizeof(addr);
2223 #ifdef SIGCLD_IGNORE
2224 signal(SIGCLD, SIG_IGN);
2226 signal(SIGCLD, SIGNAL_CAST sig_cld);
2229 /* open an incoming socket */
2230 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2234 /* ready to listen */
2235 if (listen(s, 5) == -1)
2237 DEBUG(0,("listen: %s\n",strerror(errno)));
2245 /* now accept incoming connections - forking a new process
2246 for each incoming connection */
2247 DEBUG(2,("waiting for a connection\n"));
2250 Client = accept(s,&addr,&in_addrlen);
2252 if (Client == -1 && errno == EINTR)
2257 DEBUG(0,("accept: %s\n",strerror(errno)));
2261 #ifdef NO_FORK_DEBUG
2262 #ifndef NO_SIGNAL_TEST
2263 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2264 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2268 if (Client != -1 && fork()==0)
2270 /* Child code ... */
2271 #ifndef NO_SIGNAL_TEST
2272 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2273 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2275 /* close the listening socket */
2278 /* close our standard file descriptors */
2282 set_socket_options(Client,"SO_KEEPALIVE");
2283 set_socket_options(Client,user_socket_options);
2285 /* Reset global variables in util.c so that
2286 client substitutions will be done correctly
2289 reset_globals_after_fork();
2292 close(Client); /* The parent doesn't need this socket */
2298 /* We will abort gracefully when the client or remote system
2300 #ifndef NO_SIGNAL_TEST
2301 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2305 /* close our standard file descriptors */
2308 set_socket_options(Client,"SO_KEEPALIVE");
2309 set_socket_options(Client,user_socket_options);
2316 /****************************************************************************
2317 open the oplock IPC socket communication
2318 ****************************************************************************/
2319 static BOOL open_oplock_ipc()
2321 struct sockaddr_in sock_name;
2322 int name_len = sizeof(sock_name);
2324 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2326 /* Open a lookback UDP socket on a random port. */
2327 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2328 if (oplock_sock == -1)
2330 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2331 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2336 /* Find out the transient UDP port we have been allocated. */
2337 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &name_len)<0)
2339 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2346 oplock_port = ntohs(sock_name.sin_port);
2351 /****************************************************************************
2352 process an oplock break message.
2353 ****************************************************************************/
2354 static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size)
2358 struct in_addr from_addr;
2361 msg_len = IVAL(buffer,0);
2362 from_port = SVAL(buffer,4);
2363 memcpy((char *)&from_addr, &buffer[6], sizeof(struct in_addr));
2365 msg_start = &buffer[6 + sizeof(struct in_addr)];
2367 /* Validate message length. */
2368 if(msg_len > (buf_size - (6 + sizeof(struct in_addr))))
2370 DEBUG(0,("process_local_message: invalid msg_len (%d) max can be %d\n",
2371 msg_len, buf_size - (6 + sizeof(struct in_addr))));
2375 /* Validate message from address (must be localhost). */
2376 if(from_addr.s_addr != htonl(INADDR_LOOPBACK))
2378 DEBUG(0,("process_local_message: invalid 'from' address \
2379 (was %x should be 127.0.0.1\n", from_addr.s_addr));
2385 #endif /* USE_OPLOCKS */
2387 /****************************************************************************
2388 check if a snum is in use
2389 ****************************************************************************/
2390 BOOL snum_used(int snum)
2393 for (i=0;i<MAX_CONNECTIONS;i++)
2394 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2399 /****************************************************************************
2400 reload the services file
2401 **************************************************************************/
2402 BOOL reload_services(BOOL test)
2409 pstrcpy(fname,lp_configfile());
2410 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2412 pstrcpy(servicesf,fname);
2419 if (test && !lp_file_list_changed())
2422 lp_killunused(snum_used);
2424 ret = lp_load(servicesf,False);
2426 /* perhaps the config filename is now set */
2428 reload_services(True);
2437 set_socket_options(Client,"SO_KEEPALIVE");
2438 set_socket_options(Client,user_socket_options);
2442 create_mangled_stack(lp_mangledstack());
2444 /* this forces service parameters to be flushed */
2445 become_service(-1,True);
2452 /****************************************************************************
2453 this prevents zombie child processes
2454 ****************************************************************************/
2455 static int sig_hup()
2457 BlockSignals(True,SIGHUP);
2458 DEBUG(0,("Got SIGHUP\n"));
2459 reload_services(False);
2460 #ifndef DONT_REINSTALL_SIG
2461 signal(SIGHUP,SIGNAL_CAST sig_hup);
2463 BlockSignals(False,SIGHUP);
2467 /****************************************************************************
2468 Setup the groups a user belongs to.
2469 ****************************************************************************/
2470 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2471 int **p_igroups, gid_t **p_groups)
2473 if (-1 == initgroups(user,gid))
2477 DEBUG(0,("Unable to initgroups!\n"));
2478 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2479 DEBUG(0,("This is probably a problem with the account %s\n",user));
2487 ngroups = getgroups(0,&grp);
2490 igroups = (int *)malloc(sizeof(int)*ngroups);
2491 for (i=0;i<ngroups;i++)
2492 igroups[i] = 0x42424242;
2493 ngroups = getgroups(ngroups,(gid_t *)igroups);
2495 if (igroups[0] == 0x42424242)
2498 *p_ngroups = ngroups;
2500 /* The following bit of code is very strange. It is due to the
2501 fact that some OSes use int* and some use gid_t* for
2502 getgroups, and some (like SunOS) use both, one in prototypes,
2503 and one in man pages and the actual code. Thus we detect it
2504 dynamically using some very ugly code */
2507 /* does getgroups return ints or gid_t ?? */
2508 static BOOL groups_use_ints = True;
2510 if (groups_use_ints &&
2512 SVAL(igroups,2) == 0x4242)
2513 groups_use_ints = False;
2515 for (i=0;groups_use_ints && i<ngroups;i++)
2516 if (igroups[i] == 0x42424242)
2517 groups_use_ints = False;
2519 if (groups_use_ints)
2521 *p_igroups = igroups;
2522 *p_groups = (gid_t *)igroups;
2526 gid_t *groups = (gid_t *)igroups;
2527 igroups = (int *)malloc(sizeof(int)*ngroups);
2528 for (i=0;i<ngroups;i++)
2529 igroups[i] = groups[i];
2530 *p_igroups = igroups;
2531 *p_groups = (gid_t *)groups;
2534 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2535 for (i=0;i<ngroups;i++)
2536 DEBUG(3,("%d ",igroups[i]));
2542 /****************************************************************************
2543 make a connection to a service
2544 ****************************************************************************/
2545 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2549 struct passwd *pass = NULL;
2550 connection_struct *pcon;
2553 static BOOL first_connection = True;
2557 snum = find_service(service);
2560 if (strequal(service,"IPC$"))
2562 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2566 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2570 if (strequal(service,HOMES_NAME))
2572 if (*user && Get_Pwnam(user,True))
2573 return(make_connection(user,user,password,pwlen,dev,vuid));
2575 if (validated_username(vuid))
2577 strcpy(user,validated_username(vuid));
2578 return(make_connection(user,user,password,pwlen,dev,vuid));
2582 if (!lp_snum_ok(snum) || !check_access(snum)) {
2586 /* you can only connect to the IPC$ service as an ipc device */
2587 if (strequal(service,"IPC$"))
2590 if (*dev == '?' || !*dev)
2592 if (lp_print_ok(snum))
2593 strcpy(dev,"LPT1:");
2598 /* if the request is as a printer and you can't print then refuse */
2600 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2601 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2605 /* lowercase the user name */
2608 /* add it as a possible user name */
2609 add_session_user(service);
2611 /* shall we let them in? */
2612 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2614 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2618 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2621 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2625 pcon = &Connections[cnum];
2626 bzero((char *)pcon,sizeof(*pcon));
2628 /* find out some info about the user */
2629 pass = Get_Pwnam(user,True);
2633 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2637 pcon->read_only = lp_readonly(snum);
2641 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2642 string_sub(list,"%S",service);
2644 if (user_in_list(user,list))
2645 pcon->read_only = True;
2647 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2648 string_sub(list,"%S",service);
2650 if (user_in_list(user,list))
2651 pcon->read_only = False;
2654 /* admin user check */
2655 if (user_in_list(user,lp_admin_users(snum)) &&
2658 pcon->admin_user = True;
2659 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2662 pcon->admin_user = False;
2664 pcon->force_user = force;
2666 pcon->uid = pass->pw_uid;
2667 pcon->gid = pass->pw_gid;
2668 pcon->num_files_open = 0;
2669 pcon->lastused = time(NULL);
2670 pcon->service = snum;
2672 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2673 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2674 pcon->dirptr = NULL;
2675 pcon->veto_list = NULL;
2676 pcon->hide_list = NULL;
2677 string_set(&pcon->dirpath,"");
2678 string_set(&pcon->user,user);
2681 if (*lp_force_group(snum))
2686 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2687 /* default service may be a group name */
2688 string_sub(gname,"%S",service);
2689 gptr = (struct group *)getgrnam(gname);
2693 pcon->gid = gptr->gr_gid;
2694 DEBUG(3,("Forced group %s\n",gname));
2697 DEBUG(1,("Couldn't find group %s\n",gname));
2701 if (*lp_force_user(snum))
2703 struct passwd *pass2;
2705 fstrcpy(fuser,lp_force_user(snum));
2706 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2709 pcon->uid = pass2->pw_uid;
2710 string_set(&pcon->user,fuser);
2711 fstrcpy(user,fuser);
2712 pcon->force_user = True;
2713 DEBUG(3,("Forced user %s\n",fuser));
2716 DEBUG(1,("Couldn't find user %s\n",fuser));
2721 pstrcpy(s,lp_pathname(snum));
2722 standard_sub(cnum,s);
2723 string_set(&pcon->connectpath,s);
2724 DEBUG(3,("Connect path is %s\n",s));
2727 /* groups stuff added by ih */
2729 pcon->groups = NULL;
2733 /* Find all the groups this uid is in and store them. Used by become_user() */
2734 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2736 /* check number of connections */
2737 if (!claim_connection(cnum,
2738 lp_servicename(SNUM(cnum)),
2739 lp_max_connections(SNUM(cnum)),False))
2741 DEBUG(1,("too many connections - rejected\n"));
2745 if (lp_status(SNUM(cnum)))
2746 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2748 first_connection = False;
2753 /* execute any "root preexec = " line */
2754 if (*lp_rootpreexec(SNUM(cnum)))
2757 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2758 standard_sub(cnum,cmd);
2759 DEBUG(5,("cmd=%s\n",cmd));
2760 smbrun(cmd,NULL,False);
2763 if (!become_user(cnum,pcon->vuid))
2765 DEBUG(0,("Can't become connected user!\n"));
2767 if (!IS_IPC(cnum)) {
2768 yield_connection(cnum,
2769 lp_servicename(SNUM(cnum)),
2770 lp_max_connections(SNUM(cnum)));
2771 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2776 if (ChDir(pcon->connectpath) != 0)
2778 DEBUG(0,("Can't change directory to %s (%s)\n",
2779 pcon->connectpath,strerror(errno)));
2782 if (!IS_IPC(cnum)) {
2783 yield_connection(cnum,
2784 lp_servicename(SNUM(cnum)),
2785 lp_max_connections(SNUM(cnum)));
2786 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2791 string_set(&pcon->origpath,pcon->connectpath);
2793 #if SOFTLINK_OPTIMISATION
2794 /* resolve any soft links early */
2797 pstrcpy(s,pcon->connectpath);
2799 string_set(&pcon->connectpath,s);
2800 ChDir(pcon->connectpath);
2804 num_connections_open++;
2805 add_session_user(user);
2807 /* execute any "preexec = " line */
2808 if (*lp_preexec(SNUM(cnum)))
2811 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
2812 standard_sub(cnum,cmd);
2813 smbrun(cmd,NULL,False);
2816 /* we've finished with the sensitive stuff */
2819 /* Add veto/hide lists */
2820 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
2822 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
2823 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
2827 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2831 lp_servicename(SNUM(cnum)),user,
2841 /****************************************************************************
2842 find first available file slot
2843 ****************************************************************************/
2844 int find_free_file(void )
2847 /* we start at 1 here for an obscure reason I can't now remember,
2848 but I think is important :-) */
2849 for (i=1;i<MAX_OPEN_FILES;i++)
2852 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2856 /****************************************************************************
2857 find first available connection slot, starting from a random position.
2858 The randomisation stops problems with the server dieing and clients
2859 thinking the server is still available.
2860 ****************************************************************************/
2861 static int find_free_connection(int hash )
2865 hash = (hash % (MAX_CONNECTIONS-2))+1;
2869 for (i=hash+1;i!=hash;)
2871 if (!Connections[i].open && Connections[i].used == used)
2873 DEBUG(3,("found free connection number %d\n",i));
2877 if (i == MAX_CONNECTIONS)
2887 DEBUG(1,("ERROR! Out of connection structures\n"));
2892 /****************************************************************************
2893 reply for the core protocol
2894 ****************************************************************************/
2895 int reply_corep(char *outbuf)
2897 int outsize = set_message(outbuf,1,0,True);
2899 Protocol = PROTOCOL_CORE;
2905 /****************************************************************************
2906 reply for the coreplus protocol
2907 ****************************************************************************/
2908 int reply_coreplus(char *outbuf)
2910 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2911 int outsize = set_message(outbuf,13,0,True);
2912 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2913 readbraw and writebraw (possibly) */
2914 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2915 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2917 Protocol = PROTOCOL_COREPLUS;
2923 /****************************************************************************
2924 reply for the lanman 1.0 protocol
2925 ****************************************************************************/
2926 int reply_lanman1(char *outbuf)
2928 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2930 BOOL doencrypt = SMBENCRYPT();
2931 time_t t = time(NULL);
2932 /* We need to save and restore this as it can be destroyed
2933 if we call another server if security=server
2934 Thanks to Paul Nelson @ Thursby for pointing this out.
2936 uint16 mid = SVAL(outbuf, smb_mid);
2938 if (lp_security()>=SEC_USER) secword |= 1;
2939 if (doencrypt) secword |= 2;
2941 set_message(outbuf,13,doencrypt?8:0,True);
2942 SSVAL(outbuf,smb_vwv1,secword);
2943 /* Create a token value and add it to the outgoing packet. */
2945 generate_next_challenge(smb_buf(outbuf));
2947 Protocol = PROTOCOL_LANMAN1;
2949 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2950 DEBUG(3,("using password server validation\n"));
2951 if (doencrypt) set_challenge(smb_buf(outbuf));
2954 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2955 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2956 SSVAL(outbuf,smb_vwv2,max_recv);
2957 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2958 SSVAL(outbuf,smb_vwv4,1);
2959 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2960 readbraw writebraw (possibly) */
2961 SIVAL(outbuf,smb_vwv6,getpid());
2962 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2964 put_dos_date(outbuf,smb_vwv8,t);
2966 return (smb_len(outbuf)+4);
2970 /****************************************************************************
2971 reply for the lanman 2.0 protocol
2972 ****************************************************************************/
2973 int reply_lanman2(char *outbuf)
2975 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2977 BOOL doencrypt = SMBENCRYPT();
2978 time_t t = time(NULL);
2979 /* We need to save and restore this as it can be destroyed
2980 if we call another server if security=server
2981 Thanks to Paul Nelson @ Thursby for pointing this out.
2983 uint16 mid = SVAL(outbuf, smb_mid);
2985 if (lp_security()>=SEC_USER) secword |= 1;
2986 if (doencrypt) secword |= 2;
2988 set_message(outbuf,13,doencrypt?8:0,True);
2989 SSVAL(outbuf,smb_vwv1,secword);
2990 /* Create a token value and add it to the outgoing packet. */
2992 generate_next_challenge(smb_buf(outbuf));
2994 SIVAL(outbuf,smb_vwv6,getpid());
2996 Protocol = PROTOCOL_LANMAN2;
2998 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2999 DEBUG(3,("using password server validation\n"));
3000 if (doencrypt) set_challenge(smb_buf(outbuf));
3003 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3004 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3005 SSVAL(outbuf,smb_vwv2,max_recv);
3006 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3007 SSVAL(outbuf,smb_vwv4,1);
3008 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3009 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3010 put_dos_date(outbuf,smb_vwv8,t);
3012 return (smb_len(outbuf)+4);
3016 /****************************************************************************
3017 reply for the nt protocol
3018 ****************************************************************************/
3019 int reply_nt1(char *outbuf)
3021 /* dual names + lock_and_read + nt SMBs + remote API calls */
3022 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3024 other valid capabilities which we may support at some time...
3025 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3026 CAP_LARGE_FILES|CAP_LARGE_READX|
3027 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3031 BOOL doencrypt = SMBENCRYPT();
3032 time_t t = time(NULL);
3035 char challenge_len = 8;
3036 /* We need to save and restore this as it can be destroyed
3037 if we call another server if security=server
3038 Thanks to Paul Nelson @ Thursby for pointing this out.
3040 uint16 mid = SVAL(outbuf, smb_mid);
3042 if (lp_readraw() && lp_writeraw())
3044 capabilities |= CAP_RAW_MODE;
3047 if (lp_security()>=SEC_USER) secword |= 1;
3048 if (doencrypt) secword |= 2;
3050 /* decide where (if) to put the encryption challenge, and
3051 follow it with the OEM'd domain name
3053 encrypt_len = doencrypt?challenge_len:0;
3055 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3057 data_len = encrypt_len + strlen(myworkgroup) + 1;
3060 set_message(outbuf,17,data_len,True);
3063 /* put the OEM'd domain name */
3064 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3066 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3069 CVAL(outbuf,smb_vwv1) = secword;
3070 /* Create a token value and add it to the outgoing packet. */
3073 generate_next_challenge(smb_buf(outbuf));
3075 /* Tell the nt machine how long the challenge is. */
3076 SSVALS(outbuf,smb_vwv16+1,challenge_len);
3079 Protocol = PROTOCOL_NT1;
3081 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3082 DEBUG(3,("using password server validation\n"));
3083 if (doencrypt) set_challenge(smb_buf(outbuf));
3086 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3087 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3088 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3089 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3090 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3091 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3092 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3093 put_long_date(outbuf+smb_vwv11+1,t);
3094 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3095 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3097 return (smb_len(outbuf)+4);
3100 /* these are the protocol lists used for auto architecture detection:
3103 protocol [PC NETWORK PROGRAM 1.0]
3104 protocol [XENIX CORE]
3105 protocol [MICROSOFT NETWORKS 1.03]
3106 protocol [LANMAN1.0]
3107 protocol [Windows for Workgroups 3.1a]
3108 protocol [LM1.2X002]
3109 protocol [LANMAN2.1]
3110 protocol [NT LM 0.12]
3113 protocol [PC NETWORK PROGRAM 1.0]
3114 protocol [XENIX CORE]
3115 protocol [MICROSOFT NETWORKS 1.03]
3116 protocol [LANMAN1.0]
3117 protocol [Windows for Workgroups 3.1a]
3118 protocol [LM1.2X002]
3119 protocol [LANMAN2.1]
3120 protocol [NT LM 0.12]
3123 protocol [PC NETWORK PROGRAM 1.0]
3124 protocol [XENIX CORE]
3125 protocol [LANMAN1.0]
3126 protocol [LM1.2X002]
3127 protocol [LANMAN2.1]
3131 * Modified to recognize the architecture of the remote machine better.
3133 * This appears to be the matrix of which protocol is used by which
3135 Protocol WfWg Win95 WinNT OS/2
3136 PC NETWORK PROGRAM 1.0 1 1 1 1
3138 MICROSOFT NETWORKS 3.0 2 2
3140 MICROSOFT NETWORKS 1.03 3
3143 Windows for Workgroups 3.1a 5 5 5
3148 * tim@fsg.com 09/29/95
3151 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3152 #define ARCH_WIN95 0x2
3153 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3154 #define ARCH_WINNT 0x8
3155 #define ARCH_SAMBA 0x10
3157 #define ARCH_ALL 0x1F
3159 /* List of supported protocols, most desired first */
3163 int (*proto_reply_fn)(char *);
3165 } supported_protocols[] = {
3166 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3167 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3168 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3169 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3170 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3171 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3172 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3173 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3174 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3179 /****************************************************************************
3181 ****************************************************************************/
3182 static int reply_negprot(char *inbuf,char *outbuf)
3184 int outsize = set_message(outbuf,1,0,True);
3189 int bcc = SVAL(smb_buf(inbuf),-2);
3190 int arch = ARCH_ALL;
3192 p = smb_buf(inbuf)+1;
3193 while (p < (smb_buf(inbuf) + bcc))
3196 DEBUG(3,("Requested protocol [%s]\n",p));
3197 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3198 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3199 else if (strcsequal(p,"DOS LM1.2X002"))
3200 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3201 else if (strcsequal(p,"DOS LANMAN2.1"))
3202 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3203 else if (strcsequal(p,"NT LM 0.12"))
3204 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3205 else if (strcsequal(p,"LANMAN2.1"))
3206 arch &= ( ARCH_WINNT | ARCH_OS2 );
3207 else if (strcsequal(p,"LM1.2X002"))
3208 arch &= ( ARCH_WINNT | ARCH_OS2 );
3209 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3211 else if (strcsequal(p,"XENIX CORE"))
3212 arch &= ( ARCH_WINNT | ARCH_OS2 );
3213 else if (strcsequal(p,"Samba")) {
3223 set_remote_arch(RA_SAMBA);
3226 set_remote_arch(RA_WFWG);
3229 set_remote_arch(RA_WIN95);
3232 set_remote_arch(RA_WINNT);
3235 set_remote_arch(RA_OS2);
3238 set_remote_arch(RA_UNKNOWN);
3242 /* possibly reload - change of architecture */
3243 reload_services(True);
3245 /* a special case to stop password server loops */
3246 if (Index == 1 && strequal(remote_machine,myhostname) &&
3247 lp_security()==SEC_SERVER)
3248 exit_server("Password server loop!");
3250 /* Check for protocols, most desirable first */
3251 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3253 p = smb_buf(inbuf)+1;
3255 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3256 while (p < (smb_buf(inbuf) + bcc))
3258 if (strequal(p,supported_protocols[protocol].proto_name))
3267 SSVAL(outbuf,smb_vwv0,choice);
3269 extern fstring remote_proto;
3270 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3271 reload_services(True);
3272 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3273 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3276 DEBUG(0,("No protocol supported !\n"));
3278 SSVAL(outbuf,smb_vwv0,choice);
3280 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3286 /****************************************************************************
3287 close all open files for a connection
3288 ****************************************************************************/
3289 static void close_open_files(int cnum)
3292 for (i=0;i<MAX_OPEN_FILES;i++)
3293 if( Files[i].cnum == cnum && Files[i].open) {
3300 /****************************************************************************
3302 ****************************************************************************/
3303 void close_cnum(int cnum, uint16 vuid)
3305 DirCacheFlush(SNUM(cnum));
3309 if (!OPEN_CNUM(cnum))
3311 DEBUG(0,("Can't close cnum %d\n",cnum));
3315 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3317 remote_machine,client_addr(),
3318 lp_servicename(SNUM(cnum))));
3320 yield_connection(cnum,
3321 lp_servicename(SNUM(cnum)),
3322 lp_max_connections(SNUM(cnum)));
3324 if (lp_status(SNUM(cnum)))
3325 yield_connection(cnum,"STATUS.",MAXSTATUS);
3327 close_open_files(cnum);
3328 dptr_closecnum(cnum);
3330 /* execute any "postexec = " line */
3331 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3334 strcpy(cmd,lp_postexec(SNUM(cnum)));
3335 standard_sub(cnum,cmd);
3336 smbrun(cmd,NULL,False);
3341 /* execute any "root postexec = " line */
3342 if (*lp_rootpostexec(SNUM(cnum)))
3345 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3346 standard_sub(cnum,cmd);
3347 smbrun(cmd,NULL,False);
3350 Connections[cnum].open = False;
3351 num_connections_open--;
3352 if (Connections[cnum].ngroups && Connections[cnum].groups)
3354 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3355 free(Connections[cnum].groups);
3356 free(Connections[cnum].igroups);
3357 Connections[cnum].groups = NULL;
3358 Connections[cnum].igroups = NULL;
3359 Connections[cnum].ngroups = 0;
3362 free_namearray(Connections[cnum].veto_list);
3363 free_namearray(Connections[cnum].hide_list);
3365 string_set(&Connections[cnum].user,"");
3366 string_set(&Connections[cnum].dirpath,"");
3367 string_set(&Connections[cnum].connectpath,"");
3371 /****************************************************************************
3372 simple routines to do connection counting
3373 ****************************************************************************/
3374 BOOL yield_connection(int cnum,char *name,int max_connections)
3376 struct connect_record crec;
3379 int mypid = getpid();
3382 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3384 if (max_connections <= 0)
3387 bzero(&crec,sizeof(crec));
3389 pstrcpy(fname,lp_lockdir());
3390 standard_sub(cnum,fname);
3391 trim_string(fname,"","/");
3395 strcat(fname,".LCK");
3397 f = fopen(fname,"r+");
3400 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3404 fseek(f,0,SEEK_SET);
3406 /* find a free spot */
3407 for (i=0;i<max_connections;i++)
3409 if (fread(&crec,sizeof(crec),1,f) != 1)
3411 DEBUG(2,("Entry not found in lock file %s\n",fname));
3415 if (crec.pid == mypid && crec.cnum == cnum)
3419 if (crec.pid != mypid || crec.cnum != cnum)
3422 DEBUG(2,("Entry not found in lock file %s\n",fname));
3426 bzero((void *)&crec,sizeof(crec));
3428 /* remove our mark */
3429 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3430 fwrite(&crec,sizeof(crec),1,f) != 1)
3432 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3437 DEBUG(3,("Yield successful\n"));
3444 /****************************************************************************
3445 simple routines to do connection counting
3446 ****************************************************************************/
3447 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3449 struct connect_record crec;
3452 int snum = SNUM(cnum);
3456 if (max_connections <= 0)
3459 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3461 pstrcpy(fname,lp_lockdir());
3462 standard_sub(cnum,fname);
3463 trim_string(fname,"","/");
3465 if (!directory_exist(fname,NULL))
3470 strcat(fname,".LCK");
3472 if (!file_exist(fname,NULL))
3474 int oldmask = umask(022);
3475 f = fopen(fname,"w");
3480 total_recs = file_size(fname) / sizeof(crec);
3482 f = fopen(fname,"r+");
3486 DEBUG(1,("couldn't open lock file %s\n",fname));
3490 /* find a free spot */
3491 for (i=0;i<max_connections;i++)
3494 if (i>=total_recs ||
3495 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3496 fread(&crec,sizeof(crec),1,f) != 1)
3498 if (foundi < 0) foundi = i;
3502 if (Clear && crec.pid && !process_exists(crec.pid))
3504 fseek(f,i*sizeof(crec),SEEK_SET);
3505 bzero((void *)&crec,sizeof(crec));
3506 fwrite(&crec,sizeof(crec),1,f);
3507 if (foundi < 0) foundi = i;
3510 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3519 DEBUG(3,("no free locks in %s\n",fname));
3524 /* fill in the crec */
3525 bzero((void *)&crec,sizeof(crec));
3526 crec.magic = 0x280267;
3527 crec.pid = getpid();
3529 crec.uid = Connections[cnum].uid;
3530 crec.gid = Connections[cnum].gid;
3531 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3532 crec.start = time(NULL);
3534 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3535 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3538 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3539 fwrite(&crec,sizeof(crec),1,f) != 1)
3550 /*******************************************************************
3551 prepare to dump a core file - carefully!
3552 ********************************************************************/
3553 static BOOL dump_core(void)
3557 pstrcpy(dname,debugf);
3558 if ((p=strrchr(dname,'/'))) *p=0;
3559 strcat(dname,"/corefiles");
3561 sys_chown(dname,getuid(),getgid());
3563 if (chdir(dname)) return(False);
3566 #ifndef NO_GETRLIMIT
3570 getrlimit(RLIMIT_CORE, &rlp);
3571 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3572 setrlimit(RLIMIT_CORE, &rlp);
3573 getrlimit(RLIMIT_CORE, &rlp);
3574 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3580 DEBUG(0,("Dumping core in %s\n",dname));
3585 /****************************************************************************
3587 ****************************************************************************/
3588 void exit_server(char *reason)
3590 static int firsttime=1;
3593 if (!firsttime) exit(0);
3597 DEBUG(2,("Closing connections\n"));
3598 for (i=0;i<MAX_CONNECTIONS;i++)
3599 if (Connections[i].open)
3600 close_cnum(i,(uint16)-1);
3602 if (dcelogin_atmost_once)
3606 int oldlevel = DEBUGLEVEL;
3608 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3610 show_msg(last_inbuf);
3611 DEBUGLEVEL = oldlevel;
3612 DEBUG(0,("===============================================================\n"));
3614 if (dump_core()) return;
3618 #ifdef FAST_SHARE_MODES
3619 stop_share_mode_mgmt();
3620 #endif /* FAST_SHARE_MODES */
3622 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3626 /****************************************************************************
3627 do some standard substitutions in a string
3628 ****************************************************************************/
3629 void standard_sub(int cnum,char *str)
3631 if (VALID_CNUM(cnum)) {
3634 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
3636 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
3637 string_sub(p,"%H",home);
3641 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
3642 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
3643 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
3644 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
3645 case '\0' : p++; break; /* don't run off the end of the string */
3646 default : p+=2; break;
3650 standard_sub_basic(str);
3654 These flags determine some of the permissions required to do an operation
3656 Note that I don't set NEED_WRITE on some write operations because they
3657 are used by some brain-dead clients when printing, and I don't want to
3658 force write permissions on print services.
3660 #define AS_USER (1<<0)
3661 #define NEED_WRITE (1<<1)
3662 #define TIME_INIT (1<<2)
3663 #define CAN_IPC (1<<3)
3664 #define AS_GUEST (1<<5)
3668 define a list of possible SMB messages and their corresponding
3669 functions. Any message that has a NULL function is unimplemented -
3670 please feel free to contribute implementations!
3672 struct smb_message_struct
3686 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3687 {SMBtcon,"SMBtcon",reply_tcon,0},
3688 {SMBtdis,"SMBtdis",reply_tdis,0},
3689 {SMBexit,"SMBexit",reply_exit,0},
3690 {SMBioctl,"SMBioctl",reply_ioctl,0},
3691 {SMBecho,"SMBecho",reply_echo,0},
3692 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3693 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3694 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3695 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3696 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3697 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3698 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3699 {SMBopen,"SMBopen",reply_open,AS_USER},
3701 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3702 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3703 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3705 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3706 {SMBread,"SMBread",reply_read,AS_USER},
3707 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3708 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3709 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3710 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3711 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3712 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3714 /* this is a Pathworks specific call, allowing the
3715 changing of the root path */
3716 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3718 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3719 {SMBflush,"SMBflush",reply_flush,AS_USER},
3720 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3721 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3722 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3723 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3724 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3725 {SMBlock,"SMBlock",reply_lock,AS_USER},
3726 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3728 /* CORE+ PROTOCOL FOLLOWS */
3730 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3731 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3732 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3733 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3734 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3736 /* LANMAN1.0 PROTOCOL FOLLOWS */
3738 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3739 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3740 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3741 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3742 {SMBwritec,"SMBwritec",NULL,AS_USER},
3743 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3744 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3745 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3746 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3747 {SMBioctls,"SMBioctls",NULL,AS_USER},
3748 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3749 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3751 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3752 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3753 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3754 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3756 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3757 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3758 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3760 /* LANMAN2.0 PROTOCOL FOLLOWS */
3761 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3762 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3763 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3764 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3766 /* messaging routines */
3767 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3768 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3769 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3770 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3772 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3774 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3775 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3776 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3777 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3780 /****************************************************************************
3781 return a string containing the function name of a SMB command
3782 ****************************************************************************/
3783 char *smb_fn_name(int type)
3785 static char *unknown_name = "SMBunknown";
3786 static int num_smb_messages =
3787 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3790 for (match=0;match<num_smb_messages;match++)
3791 if (smb_messages[match].code == type)
3794 if (match == num_smb_messages)
3795 return(unknown_name);
3797 return(smb_messages[match].name);
3801 /****************************************************************************
3802 do a switch on the message type, and return the response size
3803 ****************************************************************************/
3804 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3808 static int num_smb_messages =
3809 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3813 struct timeval msg_start_time;
3814 struct timeval msg_end_time;
3815 static unsigned long total_time = 0;
3817 GetTimeOfDay(&msg_start_time);
3824 last_message = type;
3826 /* make sure this is an SMB packet */
3827 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3829 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3833 for (match=0;match<num_smb_messages;match++)
3834 if (smb_messages[match].code == type)
3837 if (match == num_smb_messages)
3839 DEBUG(0,("Unknown message type %d!\n",type));
3840 outsize = reply_unknown(inbuf,outbuf);
3844 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3845 if (smb_messages[match].fn)
3847 int cnum = SVAL(inbuf,smb_tid);
3848 int flags = smb_messages[match].flags;
3849 uint16 session_tag = SVAL(inbuf,smb_uid);
3851 /* does this protocol need to be run as root? */
3852 if (!(flags & AS_USER))
3855 /* does this protocol need to be run as the connected user? */
3856 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3857 if (flags & AS_GUEST)
3860 return(ERROR(ERRSRV,ERRinvnid));
3862 /* this code is to work around a bug is MS client 3 without
3863 introducing a security hole - it needs to be able to do
3864 print queue checks as guest if it isn't logged in properly */
3865 if (flags & AS_USER)
3868 /* does it need write permission? */
3869 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3870 return(ERROR(ERRSRV,ERRaccess));
3872 /* ipc services are limited */
3873 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3874 return(ERROR(ERRSRV,ERRaccess));
3876 /* load service specific parameters */
3877 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3878 return(ERROR(ERRSRV,ERRaccess));
3880 /* does this protocol need to be run as guest? */
3881 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3882 return(ERROR(ERRSRV,ERRaccess));
3886 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3890 outsize = reply_unknown(inbuf,outbuf);
3895 GetTimeOfDay(&msg_end_time);
3896 if (!(smb_messages[match].flags & TIME_INIT))
3898 smb_messages[match].time = 0;
3899 smb_messages[match].flags |= TIME_INIT;
3902 unsigned long this_time =
3903 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3904 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3905 smb_messages[match].time += this_time;
3906 total_time += this_time;
3908 DEBUG(2,("TIME %s %d usecs %g pct\n",
3909 smb_fn_name(type),smb_messages[match].time,
3910 (100.0*smb_messages[match].time) / total_time));
3917 /****************************************************************************
3918 construct a chained reply and add it to the already made reply
3919 **************************************************************************/
3920 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3922 static char *orig_inbuf;
3923 static char *orig_outbuf;
3924 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3925 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3926 char *inbuf2, *outbuf2;
3928 char inbuf_saved[smb_wct];
3929 char outbuf_saved[smb_wct];
3930 extern int chain_size;
3931 int wct = CVAL(outbuf,smb_wct);
3932 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3934 /* maybe its not chained */
3935 if (smb_com2 == 0xFF) {
3936 CVAL(outbuf,smb_vwv0) = 0xFF;
3940 if (chain_size == 0) {
3941 /* this is the first part of the chain */
3943 orig_outbuf = outbuf;
3946 /* we need to tell the client where the next part of the reply will be */
3947 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3948 CVAL(outbuf,smb_vwv0) = smb_com2;
3950 /* remember how much the caller added to the chain, only counting stuff
3951 after the parameter words */
3952 chain_size += outsize - smb_wct;
3954 /* work out pointers into the original packets. The
3955 headers on these need to be filled in */
3956 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3957 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3959 /* remember the original command type */
3960 smb_com1 = CVAL(orig_inbuf,smb_com);
3962 /* save the data which will be overwritten by the new headers */
3963 memcpy(inbuf_saved,inbuf2,smb_wct);
3964 memcpy(outbuf_saved,outbuf2,smb_wct);
3966 /* give the new packet the same header as the last part of the SMB */
3967 memmove(inbuf2,inbuf,smb_wct);
3969 /* create the in buffer */
3970 CVAL(inbuf2,smb_com) = smb_com2;
3972 /* create the out buffer */
3973 bzero(outbuf2,smb_size);
3974 set_message(outbuf2,0,0,True);
3975 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3977 memcpy(outbuf2+4,inbuf2+4,4);
3978 CVAL(outbuf2,smb_rcls) = SUCCESS;
3979 CVAL(outbuf2,smb_reh) = 0;
3980 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3982 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3983 SSVAL(outbuf2,smb_err,SUCCESS);
3984 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3985 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3986 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3987 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3989 DEBUG(3,("Chained message\n"));
3992 /* process the request */
3993 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3994 bufsize-chain_size);
3996 /* copy the new reply and request headers over the old ones, but
3997 preserve the smb_com field */
3998 memmove(orig_outbuf,outbuf2,smb_wct);
3999 CVAL(orig_outbuf,smb_com) = smb_com1;
4001 /* restore the saved data, being careful not to overwrite any
4002 data from the reply header */
4003 memcpy(inbuf2,inbuf_saved,smb_wct);
4005 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4006 if (ofs < 0) ofs = 0;
4007 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4015 /****************************************************************************
4016 construct a reply to the incoming packet
4017 ****************************************************************************/
4018 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4020 int type = CVAL(inbuf,smb_com);
4022 int msg_type = CVAL(inbuf,0);
4023 extern int chain_size;
4025 smb_last_time = time(NULL);
4030 bzero(outbuf,smb_size);
4033 return(reply_special(inbuf,outbuf));
4035 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4036 set_message(outbuf,0,0,True);
4038 memcpy(outbuf+4,inbuf+4,4);
4039 CVAL(outbuf,smb_rcls) = SUCCESS;
4040 CVAL(outbuf,smb_reh) = 0;
4041 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4043 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4044 SSVAL(outbuf,smb_err,SUCCESS);
4045 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4046 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4047 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4048 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4050 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4052 outsize += chain_size;
4055 smb_setlen(outbuf,outsize - 4);
4059 /****************************************************************************
4060 process an smb from the client - split out from the process() code so
4061 it can be used by the oplock break code.
4062 ****************************************************************************/
4064 static void process_smb(char *inbuf, char *outbuf)
4067 static int trans_num = 0;
4069 int msg_type = CVAL(inbuf,0);
4070 int32 len = smb_len(outbuf);
4071 int nread = len + 4;
4073 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
4074 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
4077 if(trans_num == 1 && VT_Check(inbuf))
4087 nread = construct_reply(inbuf,outbuf,nread,max_send);
4091 if (CVAL(outbuf,0) == 0)
4094 if (nread != smb_len(outbuf) + 4)
4096 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
4097 nread, smb_len(outbuf)));
4100 send_smb(Client,outbuf);
4105 /****************************************************************************
4106 process commands from the client
4107 ****************************************************************************/
4108 static void process(void)
4112 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4113 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4114 if ((InBuffer == NULL) || (OutBuffer == NULL))
4117 InBuffer += SMB_ALIGNMENT;
4118 OutBuffer += SMB_ALIGNMENT;
4121 DEBUG(3,("priming nmbd\n"));
4124 ip = *interpret_addr2("localhost");
4125 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4127 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4133 int deadtime = lp_deadtime()*60;
4135 int last_keepalive=0;
4136 int service_load_counter = 0;
4138 BOOL got_smb = False;
4139 #endif /* USE_OPLOCKS */
4142 deadtime = DEFAULT_SMBD_TIMEOUT;
4144 if (lp_readprediction())
4145 do_read_prediction();
4149 for (counter=SMBD_SELECT_LOOP;
4151 !receive_message_or_smb(Client,oplock_sock,
4152 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4153 #else /* USE_OPLOCKS */
4154 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
4155 #endif /* USE_OPLOCKS */
4156 counter += SMBD_SELECT_LOOP)
4160 BOOL allidle = True;
4161 extern int keepalive;
4163 if (counter > 365 * 3600) /* big number of seconds. */
4166 service_load_counter = 0;
4169 if (smb_read_error == READ_EOF)
4171 DEBUG(3,("end of file from client\n"));
4175 if (smb_read_error == READ_ERROR)
4177 DEBUG(3,("receive_smb error (%s) exiting\n",
4184 /* become root again if waiting */
4187 /* check for smb.conf reload */
4188 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4190 service_load_counter = counter;
4192 /* reload services, if files have changed. */
4193 reload_services(True);
4196 /* automatic timeout if all connections are closed */
4197 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4199 DEBUG(2,("%s Closing idle connection\n",timestring()));
4203 if (keepalive && (counter-last_keepalive)>keepalive)
4205 extern int password_client;
4206 if (!send_keepalive(Client))
4208 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4211 /* also send a keepalive to the password server if its still
4213 if (password_client != -1)
4214 send_keepalive(password_client);
4215 last_keepalive = counter;
4218 /* check for connection timeouts */
4219 for (i=0;i<MAX_CONNECTIONS;i++)
4220 if (Connections[i].open)
4222 /* close dirptrs on connections that are idle */
4223 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4226 if (Connections[i].num_files_open > 0 ||
4227 (t-Connections[i].lastused)<deadtime)
4231 if (allidle && num_connections_open>0)
4233 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4240 #endif /* USE_OPLOCKS */
4241 process_smb(InBuffer, OutBuffer);
4244 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4245 #endif /* USE_OPLOCKS */
4250 /****************************************************************************
4251 initialise connect, service and file structs
4252 ****************************************************************************/
4253 static void init_structs(void )
4256 get_myname(myhostname,NULL);
4258 for (i=0;i<MAX_CONNECTIONS;i++)
4260 Connections[i].open = False;
4261 Connections[i].num_files_open=0;
4262 Connections[i].lastused=0;
4263 Connections[i].used=False;
4264 string_init(&Connections[i].user,"");
4265 string_init(&Connections[i].dirpath,"");
4266 string_init(&Connections[i].connectpath,"");
4267 string_init(&Connections[i].origpath,"");
4270 for (i=0;i<MAX_OPEN_FILES;i++)
4272 Files[i].open = False;
4273 string_init(&Files[i].name,"");
4277 for (i=0;i<MAX_OPEN_FILES;i++)
4279 file_fd_struct *fd_ptr = &FileFd[i];
4280 fd_ptr->ref_count = 0;
4281 fd_ptr->dev = (int32)-1;
4282 fd_ptr->inode = (int32)-1;
4284 fd_ptr->fd_readonly = -1;
4285 fd_ptr->fd_writeonly = -1;
4286 fd_ptr->real_open_flags = -1;
4292 /****************************************************************************
4293 usage on the program
4294 ****************************************************************************/
4295 static void usage(char *pname)
4297 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4299 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4300 printf("Version %s\n",VERSION);
4301 printf("\t-D become a daemon\n");
4302 printf("\t-p port listen on the specified port\n");
4303 printf("\t-d debuglevel set the debuglevel\n");
4304 printf("\t-l log basename. Basename for log/debug files\n");
4305 printf("\t-s services file. Filename of services file\n");
4306 printf("\t-P passive only\n");
4307 printf("\t-a overwrite log file, don't append\n");
4312 /****************************************************************************
4314 ****************************************************************************/
4315 int main(int argc,char *argv[])
4317 extern BOOL append_log;
4318 /* shall I run as a daemon */
4319 BOOL is_daemon = False;
4320 int port = SMB_PORT;
4322 extern char *optarg;
4323 char pidFile[100] = { 0 };
4325 #ifdef NEED_AUTH_PARAMETERS
4326 set_auth_parameters(argc,argv);
4337 strcpy(debugf,SMBLOGFILE);
4339 setup_logging(argv[0],False);
4341 charset_initialise();
4343 /* make absolutely sure we run as root - to handle cases whre people
4344 are crazy enough to have it setuid */
4354 fault_setup(exit_server);
4355 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4357 /* we want total control over the permissions on created files,
4358 so set our umask to 0 */
4365 /* this is for people who can't start the program correctly */
4366 while (argc > 1 && (*argv[1] != '-'))
4372 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4376 strncpy(pidFile, optarg, sizeof(pidFile));
4379 strcpy(user_socket_options,optarg);
4382 strcpy(scope,optarg);
4386 extern BOOL passive;
4391 strcpy(servicesf,optarg);
4394 strcpy(debugf,optarg);
4398 extern BOOL append_log;
4399 append_log = !append_log;
4409 DEBUGLEVEL = atoi(optarg);
4412 port = atoi(optarg);
4425 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4426 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4428 #ifndef NO_GETRLIMIT
4429 #ifdef RLIMIT_NOFILE
4432 getrlimit(RLIMIT_NOFILE, &rlp);
4433 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4434 setrlimit(RLIMIT_NOFILE, &rlp);
4435 getrlimit(RLIMIT_NOFILE, &rlp);
4436 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4442 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4443 getuid(),getgid(),geteuid(),getegid()));
4445 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4447 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4453 if (!reload_services(False))
4456 codepage_initialise(lp_client_code_page());
4458 strcpy(myworkgroup, lp_workgroup());
4460 #ifndef NO_SIGNAL_TEST
4461 signal(SIGHUP,SIGNAL_CAST sig_hup);
4464 DEBUG(3,("%s loaded services\n",timestring()));
4466 if (!is_daemon && !is_a_socket(0))
4468 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4474 DEBUG(3,("%s becoming a daemon\n",timestring()));
4483 if ((fd = open(pidFile,
4487 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4489 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4492 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4494 DEBUG(0,("ERROR: smbd is already running\n"));
4497 sprintf(buf, "%u\n", (unsigned int) getpid());
4498 if (write(fd, buf, strlen(buf)) < 0)
4500 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4503 /* Leave pid file open & locked for the duration... */
4506 if (!open_sockets(is_daemon,port))
4509 #ifdef FAST_SHARE_MODES
4510 if (!start_share_mode_mgmt())
4512 #endif /* FAST_SHARE_MODES */
4514 /* possibly reload the services file. */
4515 reload_services(True);
4517 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4521 if (sys_chroot(lp_rootdir()) == 0)
4522 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4526 /* Setup the oplock IPC socket. */
4527 if(!open_oplock_ipc())
4529 #endif /* USE_OPLOCKS */
4534 exit_server("normal exit");