2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1998
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 global_myworkgroup;
29 extern pstring global_myname;
31 char *InBuffer = NULL;
32 char *OutBuffer = NULL;
33 char *last_inbuf = NULL;
38 /* the last message the was processed */
39 int last_message = -1;
41 /* a useful macro to debug the last message processed */
42 #define LAST_MESSAGE() smb_fn_name(last_message)
45 extern int DEBUGLEVEL;
46 extern int case_default;
47 extern BOOL case_sensitive;
48 extern BOOL case_preserve;
49 extern BOOL use_mangled_map;
50 extern BOOL short_case_preserve;
51 extern BOOL case_mangle;
52 time_t smb_last_time=(time_t)0;
54 extern int smb_read_error;
56 extern pstring user_socket_options;
59 extern int dcelogin_atmost_once;
62 connection_struct Connections[MAX_CONNECTIONS];
63 files_struct Files[MAX_OPEN_FILES];
66 * Indirection for file fd's. Needed as POSIX locking
67 * is based on file/process, not fd/process.
69 file_fd_struct FileFd[MAX_OPEN_FILES];
70 int max_file_fd_used = 0;
75 * Size of data we can send to client. Set
76 * by the client for all protocols above CORE.
77 * Set by us for CORE protocol.
79 int max_send = BUFFER_SIZE;
81 * Size of the data we can receive. Set by us.
82 * Can be modified by the max xmit parameter.
84 int max_recv = BUFFER_SIZE;
86 /* a fnum to use when chaining */
89 /* number of open connections */
90 static int num_connections_open = 0;
92 /* Oplock ipc UDP socket. */
94 uint16 oplock_port = 0;
95 /* Current number of oplocks we have outstanding. */
96 int32 global_oplocks_open = 0;
98 BOOL global_oplock_break = False;
100 extern fstring remote_machine;
102 extern pstring OriginalDir;
104 /* these can be set by some functions to override the error codes */
105 int unix_ERR_class=SMB_SUCCESS;
109 extern int extra_time_offset;
111 extern pstring myhostname;
113 static int find_free_connection(int hash);
115 /* for readability... */
116 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
117 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
118 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
119 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
120 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
122 /****************************************************************************
123 when exiting, take the whole family
124 ****************************************************************************/
127 exit_server("caught signal");
128 return 0; /* Keep -Wall happy :-) */
130 /****************************************************************************
131 Send a SIGTERM to our process group.
132 *****************************************************************************/
135 if(am_parent) kill(0,SIGTERM);
138 /****************************************************************************
139 change a dos mode to a unix mode
140 base permission for files:
141 everybody gets read bit set
142 dos readonly is represented in unix by removing everyone's write bit
143 dos archive is represented in unix by the user's execute bit
144 dos system is represented in unix by the group's execute bit
145 dos hidden is represented in unix by the other's execute bit
146 Then apply create mask,
148 base permission for directories:
149 dos directory is represented in unix by unix's dir bit and the exec bit
150 Then apply create mask,
152 ****************************************************************************/
153 mode_t unix_mode(int cnum,int dosmode)
155 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
157 if ( !IS_DOS_READONLY(dosmode) )
158 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
160 if (IS_DOS_DIR(dosmode)) {
161 /* We never make directories read only for the owner as under DOS a user
162 can always create a file in a read-only directory. */
163 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
164 /* Apply directory mask */
165 result &= lp_dir_mode(SNUM(cnum));
166 /* Add in force bits */
167 result |= lp_force_dir_mode(SNUM(cnum));
169 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
172 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
175 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
178 /* Apply mode mask */
179 result &= lp_create_mode(SNUM(cnum));
180 /* Add in force bits */
181 result |= lp_force_create_mode(SNUM(cnum));
187 /****************************************************************************
188 change a unix mode to a dos mode
189 ****************************************************************************/
190 int dos_mode(int cnum,char *path,struct stat *sbuf)
193 extern struct current_user current_user;
195 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
197 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
198 if (!((sbuf->st_mode & S_IWOTH) ||
199 Connections[cnum].admin_user ||
200 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
201 ((sbuf->st_mode & S_IWGRP) &&
202 in_group(sbuf->st_gid,current_user.gid,
203 current_user.ngroups,current_user.igroups))))
206 if ((sbuf->st_mode & S_IWUSR) == 0)
210 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
213 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
216 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
219 if (S_ISDIR(sbuf->st_mode))
220 result = aDIR | (result & aRONLY);
224 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
229 /* hide files with a name starting with a . */
230 if (lp_hide_dot_files(SNUM(cnum)))
232 char *p = strrchr(path,'/');
238 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
242 /* Optimization : Only call is_hidden_path if it's not already
244 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
249 DEBUG(8,("dos_mode returning "));
251 if (result & aHIDDEN) DEBUG(8, ("h"));
252 if (result & aRONLY ) DEBUG(8, ("r"));
253 if (result & aSYSTEM) DEBUG(8, ("s"));
254 if (result & aDIR ) DEBUG(8, ("d"));
255 if (result & aARCH ) DEBUG(8, ("a"));
262 /*******************************************************************
263 chmod a file - but preserve some bits
264 ********************************************************************/
265 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
274 if (sys_stat(fname,st)) return(-1);
277 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
279 if (dos_mode(cnum,fname,st) == dosmode) return(0);
281 unixmode = unix_mode(cnum,dosmode);
283 /* preserve the s bits */
284 mask |= (S_ISUID | S_ISGID);
286 /* preserve the t bit */
291 /* possibly preserve the x bits */
292 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
293 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
294 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
296 unixmode |= (st->st_mode & mask);
298 /* if we previously had any r bits set then leave them alone */
299 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
300 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
304 /* if we previously had any w bits set then leave them alone
305 if the new mode is not rdonly */
306 if (!IS_DOS_READONLY(dosmode) &&
307 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
308 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
312 return(sys_chmod(fname,unixmode));
315 /*******************************************************************
316 Wrapper around sys_utime that possibly allows DOS semantics rather
318 *******************************************************************/
320 int file_utime(int cnum, char *fname, struct utimbuf *times)
322 extern struct current_user current_user;
328 if(sys_utime(fname, times) == 0)
331 if((errno != EPERM) && (errno != EACCES))
334 if(!lp_dos_filetimes(SNUM(cnum)))
337 /* We have permission (given by the Samba admin) to
338 break POSIX semantics and allow a user to change
339 the time on a file they don't own but can write to
343 if(sys_stat(fname,&sb) != 0)
346 /* Check if we have write access. */
347 if (CAN_WRITE(cnum)) {
348 if (((sb.st_mode & S_IWOTH) ||
349 Connections[cnum].admin_user ||
350 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
351 ((sb.st_mode & S_IWGRP) &&
352 in_group(sb.st_gid,current_user.gid,
353 current_user.ngroups,current_user.igroups)))) {
354 /* We are allowed to become root and change the filetime. */
356 ret = sys_utime(fname, times);
357 unbecome_root(False);
364 /*******************************************************************
365 Change a filetime - possibly allowing DOS semantics.
366 *******************************************************************/
368 BOOL set_filetime(int cnum, char *fname, time_t mtime)
370 struct utimbuf times;
372 if (null_mtime(mtime)) return(True);
374 times.modtime = times.actime = mtime;
376 if (file_utime(cnum, fname, ×)) {
377 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
383 /****************************************************************************
384 check if two filenames are equal
386 this needs to be careful about whether we are case sensitive
387 ****************************************************************************/
388 static BOOL fname_equal(char *name1, char *name2)
390 int l1 = strlen(name1);
391 int l2 = strlen(name2);
393 /* handle filenames ending in a single dot */
394 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
398 ret = fname_equal(name1,name2);
403 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
407 ret = fname_equal(name1,name2);
412 /* now normal filename handling */
414 return(strcmp(name1,name2) == 0);
416 return(strequal(name1,name2));
420 /****************************************************************************
421 mangle the 2nd name and check if it is then equal to the first name
422 ****************************************************************************/
423 static BOOL mangled_equal(char *name1, char *name2)
427 if (is_8_3(name2, True))
430 strcpy(tmpname,name2);
431 mangle_name_83(tmpname);
433 return(strequal(name1,tmpname));
437 /****************************************************************************
438 scan a directory to find a filename, matching without case sensitivity
440 If the name looks like a mangled name then try via the mangling functions
441 ****************************************************************************/
442 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
449 mangled = is_mangled(name);
451 /* handle null paths */
455 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
461 * The incoming name can be mangled, and if we de-mangle it
462 * here it will not compare correctly against the filename (name2)
463 * read from the directory and then mangled by the name_map_mangle()
464 * call. We need to mangle both names or neither.
468 mangled = !check_mangled_cache( name );
470 /* open the directory */
471 if (!(cur_dir = OpenDir(cnum, path, True)))
473 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
477 /* now scan for matching names */
478 while ((dname = ReadDirName(cur_dir)))
481 (strequal(dname,".") || strequal(dname,"..")))
484 pstrcpy(name2,dname);
485 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
487 if ((mangled && mangled_equal(name,name2))
488 || fname_equal(name, name2))
490 /* we've found the file, change it's name and return */
491 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
502 /****************************************************************************
503 This routine is called to convert names from the dos namespace to unix
504 namespace. It needs to handle any case conversions, mangling, format
507 We assume that we have already done a chdir() to the right "root" directory
510 The function will return False if some part of the name except for the last
511 part cannot be resolved
513 If the saved_last_component != 0, then the unmodified last component
514 of the pathname is returned there. This is used in an exceptional
515 case in reply_mv (so far). If saved_last_component == 0 then nothing
518 The bad_path arg is set to True if the filename walk failed. This is
519 used to pick the correct error code to return between ENOENT and ENOTDIR
520 as Windows applications depend on ERRbadpath being returned if a component
521 of a pathname does not exist.
522 ****************************************************************************/
523 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
533 if(saved_last_component)
534 *saved_last_component = 0;
536 /* convert to basic unix format - removing \ chars and cleaning it up */
538 unix_clean_name(name);
540 /* names must be relative to the root of the service - trim any leading /.
541 also trim trailing /'s */
542 trim_string(name,"/","/");
545 * Ensure saved_last_component is valid even if file exists.
547 if(saved_last_component) {
548 end = strrchr(name, '/');
550 strcpy(saved_last_component, end + 1);
552 strcpy(saved_last_component, name);
555 if (!case_sensitive &&
556 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
559 /* check if it's a printer file */
560 if (Connections[cnum].printer)
562 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
566 sprintf(name2,"%.6s.XXXXXX",remote_machine);
567 /* sanitise the name */
568 for (s=name2 ; *s ; s++)
569 if (!issafe(*s)) *s = '_';
570 strcpy(name,(char *)mktemp(name2));
575 /* stat the name - if it exists then we are all done! */
576 if (sys_stat(name,&st) == 0)
581 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
583 /* a special case - if we don't have any mangling chars and are case
584 sensitive then searching won't help */
585 if (case_sensitive && !is_mangled(name) &&
586 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
589 /* now we need to recursively match the name against the real
590 directory structure */
593 while (strncmp(start,"./",2) == 0)
596 /* now match each part of the path name separately, trying the names
597 as is first, then trying to scan the directory for matching names */
598 for (;start;start = (end?end+1:(char *)NULL))
600 /* pinpoint the end of this section of the filename */
601 end = strchr(start, '/');
603 /* chop the name at this point */
606 if(saved_last_component != 0)
607 strcpy(saved_last_component, end ? end + 1 : start);
609 /* check if the name exists up to this point */
610 if (sys_stat(name, &st) == 0)
612 /* it exists. it must either be a directory or this must be
613 the last part of the path for it to be OK */
614 if (end && !(st.st_mode & S_IFDIR))
616 /* an intermediate part of the name isn't a directory */
617 DEBUG(5,("Not a dir %s\n",start));
628 /* remember the rest of the pathname so it can be restored
630 if (end) pstrcpy(rest,end+1);
632 /* try to find this part of the path in the directory */
633 if (strchr(start,'?') || strchr(start,'*') ||
634 !scan_directory(dirpath, start, cnum, end?True:False))
638 /* an intermediate part of the name can't be found */
639 DEBUG(5,("Intermediate not found %s\n",start));
641 /* We need to return the fact that the intermediate
642 name resolution failed. This is used to return an
643 error of ERRbadpath rather than ERRbadfile. Some
644 Windows applications depend on the difference between
651 /* just the last part of the name doesn't exist */
652 /* we may need to strupper() or strlower() it in case
653 this conversion is being used for file creation
655 /* if the filename is of mixed case then don't normalise it */
656 if (!case_preserve &&
657 (!strhasupper(start) || !strhaslower(start)))
660 /* check on the mangled stack to see if we can recover the
661 base of the filename */
662 if (is_mangled(start))
663 check_mangled_cache( start );
665 DEBUG(5,("New file %s\n",start));
669 /* restore the rest of the string */
672 strcpy(start+strlen(start)+1,rest);
673 end = start + strlen(start);
677 /* add to the dirpath that we have resolved so far */
678 if (*dirpath) strcat(dirpath,"/");
679 strcat(dirpath,start);
681 /* restore the / that we wiped out earlier */
685 /* the name has been resolved */
686 DEBUG(5,("conversion finished %s\n",name));
691 /****************************************************************************
692 normalise for DOS usage
693 ****************************************************************************/
694 static void disk_norm(int *bsize,int *dfree,int *dsize)
696 /* check if the disk is beyond the max disk size */
697 int maxdisksize = lp_maxdisksize();
699 /* convert to blocks - and don't overflow */
700 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
701 if (*dsize > maxdisksize) *dsize = maxdisksize;
702 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
707 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
712 if (*bsize > WORDMAX )
715 if (*dsize > WORDMAX)
717 if (*dfree > WORDMAX)
724 /****************************************************************************
725 return number of 1K blocks available on a path and total number
726 ****************************************************************************/
727 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
729 char *df_command = lp_dfree_command();
750 /* possibly use system() to get the result */
751 if (df_command && *df_command)
757 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
758 sprintf(syscmd,"%s %s",df_command,path);
759 standard_sub_basic(syscmd);
761 ret = smbrun(syscmd,outfile,False);
762 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
765 FILE *f = fopen(outfile,"r");
771 fscanf(f,"%d %d %d",dsize,dfree,bsize);
775 DEBUG(0,("Can't open %s\n",outfile));
779 disk_norm(bsize,dfree,dsize);
780 dfree_retval = ((*bsize)/1024)*(*dfree);
782 /* Ensure we return the min value between the users quota and
783 what's free on the disk. Thanks to Albrecht Gebhardt
784 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
786 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
788 disk_norm(&bsizeq, &dfreeq, &dsizeq);
789 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
790 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
791 dfree_retval : dfreeq_retval ;
792 /* maybe dfree and dfreeq are calculated using different bsizes
793 so convert dfree from bsize into bsizeq */
794 /* avoid overflows due to multiplication, so do not:
795 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
796 bsize and bsizeq are powers of 2 so its better to
797 to divide them getting a multiplication or division factor
798 for dfree. Rene Nieuwenhuizen (07-10-1997) */
799 if (*bsize >= bsizeq)
800 *dfree = *dfree * (*bsize / bsizeq);
802 *dfree = *dfree / (bsizeq / *bsize);
803 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
808 return(dfree_retval);
812 DEBUG(1,("Warning - no statfs function\n"));
816 if (statfs(path,&fs,sizeof(fs),0) != 0)
819 if (statvfs(path, &fs))
822 if (statfs(path,&fs,sizeof(fs)) == -1)
824 if (statfs(path,&fs) == -1)
826 #endif /* USE_STATVFS */
829 DEBUG(3,("dfree call failed code errno=%d\n",errno));
833 return(((*bsize)/1024)*(*dfree));
838 *dfree = fs.fd_req.bfree;
839 *dsize = fs.fd_req.btot;
842 *bsize = fs.f_frsize;
845 /* eg: osf1 has f_fsize = fundamental filesystem block size,
846 f_bsize = optimal transfer block size (MX: 94-04-19) */
851 #endif /* USE_STATVFS */
856 *dfree = fs.f_bavail;
858 *dsize = fs.f_blocks;
861 #if defined(SCO) || defined(ISC) || defined(MIPS)
865 /* handle rediculous bsize values - some OSes are broken */
866 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
868 disk_norm(bsize,dfree,dsize);
874 DEBUG(0,("dfree seems to be broken on your system\n"));
875 *dsize = 20*1024*1024/(*bsize);
876 *dfree = MAX(1,*dfree);
878 dfree_retval = ((*bsize)/1024)*(*dfree);
880 /* Ensure we return the min value between the users quota and
881 what's free on the disk. Thanks to Albrecht Gebhardt
882 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
884 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
886 disk_norm(&bsizeq, &dfreeq, &dsizeq);
887 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
888 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
889 dfree_retval : dfreeq_retval ;
890 /* maybe dfree and dfreeq are calculated using different bsizes
891 so convert dfree from bsize into bsizeq */
892 /* avoid overflows due to multiplication, so do not:
893 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
894 bsize and bsizeq are powers of 2 so its better to
895 to divide them getting a multiplication or division factor
896 for dfree. Rene Nieuwenhuizen (07-10-1997) */
897 if (*bsize >= bsizeq)
898 *dfree = *dfree * (*bsize / bsizeq);
900 *dfree = *dfree / (bsizeq / *bsize);
901 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
906 return(dfree_retval);
911 /****************************************************************************
912 wrap it to get filenames right
913 ****************************************************************************/
914 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
916 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
921 /****************************************************************************
922 check a filename - possibly caling reducename
924 This is called by every routine before it allows an operation on a filename.
925 It does any final confirmation necessary to ensure that the filename is
926 a valid one for the user to access.
927 ****************************************************************************/
928 BOOL check_name(char *name,int cnum)
934 if( IS_VETO_PATH(cnum, name))
936 DEBUG(5,("file path name %s vetoed\n",name));
940 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
942 /* Check if we are allowing users to follow symlinks */
943 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
944 University of Geneva */
947 if (!lp_symlinks(SNUM(cnum)))
950 if ( (sys_lstat(name,&statbuf) != -1) &&
951 (S_ISLNK(statbuf.st_mode)) )
953 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
960 DEBUG(5,("check_name on %s failed\n",name));
965 /****************************************************************************
966 check a filename - possibly caling reducename
967 ****************************************************************************/
968 static void check_for_pipe(char *fname)
970 /* special case of pipe opens */
974 if (strstr(s,"pipe/"))
976 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
977 unix_ERR_class = ERRSRV;
978 unix_ERR_code = ERRaccess;
982 /****************************************************************************
983 fd support routines - attempt to do a sys_open
984 ****************************************************************************/
985 static int fd_attempt_open(char *fname, int flags, int mode)
987 int fd = sys_open(fname,flags,mode);
989 /* Fix for files ending in '.' */
990 if((fd == -1) && (errno == ENOENT) &&
991 (strchr(fname,'.')==NULL))
994 fd = sys_open(fname,flags,mode);
997 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
998 if ((fd == -1) && (errno == ENAMETOOLONG))
1001 char *p = strrchr(fname, '/');
1003 if (p == fname) /* name is "/xxx" */
1005 max_len = pathconf("/", _PC_NAME_MAX);
1008 else if ((p == NULL) || (p == fname))
1011 max_len = pathconf(".", _PC_NAME_MAX);
1016 max_len = pathconf(fname, _PC_NAME_MAX);
1020 if (strlen(p) > max_len)
1022 char tmp = p[max_len];
1025 if ((fd = sys_open(fname,flags,mode)) == -1)
1033 /****************************************************************************
1034 fd support routines - attempt to find an already open file by dev
1035 and inode - increments the ref_count of the returned file_fd_struct *.
1036 ****************************************************************************/
1037 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1040 file_fd_struct *fd_ptr;
1045 for(i = 0; i <= max_file_fd_used; i++) {
1046 fd_ptr = &FileFd[i];
1047 if((fd_ptr->ref_count > 0) &&
1048 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1049 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1050 fd_ptr->ref_count++;
1052 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1053 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1060 /****************************************************************************
1061 fd support routines - attempt to find a empty slot in the FileFd array.
1062 Increments the ref_count of the returned entry.
1063 ****************************************************************************/
1064 static file_fd_struct *fd_get_new(void)
1067 file_fd_struct *fd_ptr;
1069 for(i = 0; i < MAX_OPEN_FILES; i++) {
1070 fd_ptr = &FileFd[i];
1071 if(fd_ptr->ref_count == 0) {
1072 fd_ptr->dev = (uint32)-1;
1073 fd_ptr->inode = (uint32)-1;
1075 fd_ptr->fd_readonly = -1;
1076 fd_ptr->fd_writeonly = -1;
1077 fd_ptr->real_open_flags = -1;
1078 fd_ptr->ref_count++;
1079 /* Increment max used counter if neccessary, cuts down
1080 on search time when re-using */
1081 if(i > max_file_fd_used)
1082 max_file_fd_used = i;
1083 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1084 i, fd_ptr->dev, fd_ptr->inode));
1088 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1093 /****************************************************************************
1094 fd support routines - attempt to re-open an already open fd as O_RDWR.
1095 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1096 ****************************************************************************/
1097 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1099 int fd = sys_open( fname, O_RDWR, mode);
1104 if(fd_ptr->real_open_flags == O_RDONLY)
1105 fd_ptr->fd_readonly = fd_ptr->fd;
1106 if(fd_ptr->real_open_flags == O_WRONLY)
1107 fd_ptr->fd_writeonly = fd_ptr->fd;
1110 fd_ptr->real_open_flags = O_RDWR;
1113 /****************************************************************************
1114 fd support routines - attempt to close the file referenced by this fd.
1115 Decrements the ref_count and returns it.
1116 ****************************************************************************/
1117 static int fd_attempt_close(file_fd_struct *fd_ptr)
1119 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1120 fd_ptr - &FileFd[0],
1121 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1122 fd_ptr->real_open_flags,
1123 fd_ptr->ref_count));
1124 if(fd_ptr->ref_count > 0) {
1125 fd_ptr->ref_count--;
1126 if(fd_ptr->ref_count == 0) {
1127 if(fd_ptr->fd != -1)
1129 if(fd_ptr->fd_readonly != -1)
1130 close(fd_ptr->fd_readonly);
1131 if(fd_ptr->fd_writeonly != -1)
1132 close(fd_ptr->fd_writeonly);
1134 fd_ptr->fd_readonly = -1;
1135 fd_ptr->fd_writeonly = -1;
1136 fd_ptr->real_open_flags = -1;
1137 fd_ptr->dev = (uint32)-1;
1138 fd_ptr->inode = (uint32)-1;
1141 return fd_ptr->ref_count;
1144 /****************************************************************************
1146 ****************************************************************************/
1147 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1149 extern struct current_user current_user;
1151 struct stat statbuf;
1152 file_fd_struct *fd_ptr;
1153 files_struct *fsp = &Files[fnum];
1154 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1158 fsp->granted_oplock = False;
1161 pstrcpy(fname,fname1);
1163 /* check permissions */
1166 * This code was changed after seeing a client open request
1167 * containing the open mode of (DENY_WRITE/read-only) with
1168 * the 'create if not exist' bit set. The previous code
1169 * would fail to open the file read only on a read-only share
1170 * as it was checking the flags parameter directly against O_RDONLY,
1171 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1175 if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1176 /* It's a read-only share - fail if we wanted to write. */
1177 if(accmode != O_RDONLY) {
1178 DEBUG(3,("Permission denied opening %s\n",fname));
1179 check_for_pipe(fname);
1182 else if(flags & O_CREAT) {
1183 /* We don't want to write - but we must make sure that O_CREAT
1184 doesn't create the file if we have write access into the
1191 /* this handles a bug in Win95 - it doesn't say to create the file when it
1193 if (Connections[cnum].printer)
1197 if (flags == O_WRONLY)
1198 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1202 * Ensure we have a valid struct stat so we can search the
1206 if(stat(fname, &statbuf) < 0) {
1207 if(errno != ENOENT) {
1208 DEBUG(3,("Error doing stat on file %s (%s)\n",
1209 fname,strerror(errno)));
1211 check_for_pipe(fname);
1221 * Check to see if we have this file already
1222 * open. If we do, just use the already open fd and increment the
1223 * reference count (fd_get_already_open increments the ref_count).
1225 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1227 /* File was already open. */
1228 if((flags & O_CREAT) && (flags & O_EXCL)) {
1229 fd_ptr->ref_count--;
1235 * If not opened O_RDWR try
1236 * and do that here - a chmod may have been done
1237 * between the last open and now.
1239 if(fd_ptr->real_open_flags != O_RDWR)
1240 fd_attempt_reopen(fname, mode, fd_ptr);
1243 * Ensure that if we wanted write access
1244 * it has been opened for write, and if we wanted read it
1245 * was open for read.
1247 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1248 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1249 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1250 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1251 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1252 check_for_pipe(fname);
1253 fd_ptr->ref_count--;
1259 /* We need to allocate a new file_fd_struct (this increments the
1261 if((fd_ptr = fd_get_new()) == 0)
1264 * Whatever the requested flags, attempt read/write access,
1265 * as we don't know what flags future file opens may require.
1266 * If this fails, try again with the required flags.
1267 * Even if we open read/write when only read access was
1268 * requested the setting of the can_write flag in
1269 * the file_struct will protect us from errant
1270 * write requests. We never need to worry about O_APPEND
1271 * as this is not set anywhere in Samba.
1273 fd_ptr->real_open_flags = O_RDWR;
1274 /* Set the flags as needed without the read/write modes. */
1275 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1276 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1278 * On some systems opening a file for R/W access on a read only
1279 * filesystems sets errno to EROFS.
1282 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1283 #else /* No EROFS */
1284 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1286 if(flags & O_WRONLY) {
1287 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1288 fd_ptr->real_open_flags = O_WRONLY;
1290 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1291 fd_ptr->real_open_flags = O_RDONLY;
1296 if ((fd_ptr->fd >=0) &&
1297 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1301 pstrcpy(dname,fname);
1302 p = strrchr(dname,'/');
1304 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1305 lp_minprintspace(SNUM(cnum))) {
1306 fd_attempt_close(fd_ptr);
1308 if(fd_ptr->ref_count == 0)
1317 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1318 fname,strerror(errno),flags));
1319 /* Ensure the ref_count is decremented. */
1320 fd_attempt_close(fd_ptr);
1321 check_for_pipe(fname);
1325 if (fd_ptr->fd >= 0)
1329 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1330 /* Error - backout !! */
1331 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1332 fd_ptr->fd, fname,strerror(errno)));
1333 /* Ensure the ref_count is decremented. */
1334 fd_attempt_close(fd_ptr);
1339 /* Set the correct entries in fd_ptr. */
1340 fd_ptr->dev = (uint32)sbuf->st_dev;
1341 fd_ptr->inode = (uint32)sbuf->st_ino;
1343 fsp->fd_ptr = fd_ptr;
1344 Connections[cnum].num_files_open++;
1345 fsp->mode = sbuf->st_mode;
1346 GetTimeOfDay(&fsp->open_time);
1347 fsp->vuid = current_user.vuid;
1351 fsp->mmap_ptr = NULL;
1353 fsp->can_lock = True;
1354 fsp->can_read = ((flags & O_WRONLY)==0);
1355 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1356 fsp->share_mode = 0;
1357 fsp->print_file = Connections[cnum].printer;
1358 fsp->modified = False;
1359 fsp->granted_oplock = False;
1360 fsp->sent_oplock_break = False;
1362 string_set(&fsp->name,dos_to_unix(fname,False));
1363 fsp->wbmpx_ptr = NULL;
1366 * If the printer is marked as postscript output a leading
1367 * file identifier to ensure the file is treated as a raw
1369 * This has a similar effect as CtrlD=0 in WIN.INI file.
1370 * tim@fsg.com 09/06/94
1372 if (fsp->print_file && POSTSCRIPT(cnum) &&
1375 DEBUG(3,("Writing postscript line\n"));
1376 write_file(fnum,"%!\n",3);
1379 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1380 timestring(),Connections[cnum].user,fname,
1381 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1382 Connections[cnum].num_files_open,fnum));
1387 /* mmap it if read-only */
1388 if (!fsp->can_write)
1390 fsp->mmap_size = file_size(fname);
1391 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1392 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1394 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1396 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1397 fsp->mmap_ptr = NULL;
1403 /*******************************************************************
1405 ********************************************************************/
1406 void sync_file(int fnum)
1409 fsync(Files[fnum].fd_ptr->fd);
1413 /****************************************************************************
1414 run a file if it is a magic script
1415 ****************************************************************************/
1416 static void check_magic(int fnum,int cnum)
1418 if (!*lp_magicscript(SNUM(cnum)))
1421 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1425 if (!(p = strrchr(Files[fnum].name,'/')))
1426 p = Files[fnum].name;
1430 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1436 pstring magic_output;
1438 pstrcpy(fname,Files[fnum].name);
1440 if (*lp_magicoutput(SNUM(cnum)))
1441 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1443 sprintf(magic_output,"%s.out",fname);
1446 ret = smbrun(fname,magic_output,False);
1447 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1453 /****************************************************************************
1454 close a file - possibly invalidating the read prediction
1456 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1457 operation otherwise it came as the result of some other operation such as
1458 the closing of the connection. In the latter case printing and
1459 magic scripts are not run
1460 ****************************************************************************/
1461 void close_file(int fnum, BOOL normal_close)
1463 files_struct *fs_p = &Files[fnum];
1464 int cnum = fs_p->cnum;
1465 uint32 dev = fs_p->fd_ptr->dev;
1466 uint32 inode = fs_p->fd_ptr->inode;
1469 Files[fnum].reserved = False;
1471 #if USE_READ_PREDICTION
1472 invalidate_read_prediction(fs_p->fd_ptr->fd);
1476 Connections[cnum].num_files_open--;
1479 free((char *)fs_p->wbmpx_ptr);
1480 fs_p->wbmpx_ptr = NULL;
1486 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1487 fs_p->mmap_ptr = NULL;
1491 if (lp_share_modes(SNUM(cnum)))
1493 lock_share_entry( cnum, dev, inode, &token);
1494 del_share_mode(token, fnum);
1497 fd_attempt_close(fs_p->fd_ptr);
1499 if (lp_share_modes(SNUM(cnum)))
1500 unlock_share_entry( cnum, dev, inode, token);
1502 /* NT uses smbclose to start a print - weird */
1503 if (normal_close && fs_p->print_file)
1506 /* check for magic scripts */
1508 check_magic(fnum,cnum);
1510 if(fs_p->granted_oplock == True)
1511 global_oplocks_open--;
1513 fs_p->sent_oplock_break = False;
1515 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1516 timestring(),Connections[cnum].user,fs_p->name,
1517 Connections[cnum].num_files_open));
1520 string_free(&fs_p->name);
1523 /* we will catch bugs faster by zeroing this structure */
1524 memset(fs_p, 0, sizeof(*fs_p));
1527 enum {AFAIL,AREAD,AWRITE,AALL};
1529 /*******************************************************************
1530 reproduce the share mode access table
1531 ********************************************************************/
1532 static int access_table(int new_deny,int old_deny,int old_mode,
1533 int share_pid,char *fname)
1535 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1537 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1539 if (old_deny == new_deny && share_pid == pid)
1542 if (old_mode == 0) return(AREAD);
1544 /* the new smbpub.zip spec says that if the file extension is
1545 .com, .dll, .exe or .sym then allow the open. I will force
1546 it to read-only as this seems sensible although the spec is
1547 a little unclear on this. */
1548 if ((fname = strrchr(fname,'.'))) {
1549 if (strequal(fname,".com") ||
1550 strequal(fname,".dll") ||
1551 strequal(fname,".exe") ||
1552 strequal(fname,".sym"))
1562 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1563 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1564 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1567 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1568 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1569 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1572 if (old_deny==DENY_WRITE) return(AREAD);
1573 if (old_deny==DENY_READ) return(AWRITE);
1574 if (old_deny==DENY_NONE) return(AALL);
1580 /*******************************************************************
1581 check if the share mode on a file allows it to be deleted or unlinked
1582 return True if sharing doesn't prevent the operation
1583 ********************************************************************/
1584 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1588 share_mode_entry *old_shares = 0;
1589 int num_share_modes;
1595 if(!lp_share_modes(SNUM(cnum)))
1598 if (stat(fname,&sbuf) == -1) return(True);
1600 dev = (uint32)sbuf.st_dev;
1601 inode = (uint32)sbuf.st_ino;
1603 lock_share_entry(cnum, dev, inode, &token);
1604 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1607 * Check if the share modes will give us access.
1610 if(num_share_modes != 0)
1617 broke_oplock = False;
1618 for(i = 0; i < num_share_modes; i++)
1620 share_mode_entry *share_entry = &old_shares[i];
1623 * Break oplocks before checking share modes. See comment in
1624 * open_file_shared for details.
1625 * Check if someone has an oplock on this file. If so we must
1626 * break it before continuing.
1628 if(share_entry->op_type & BATCH_OPLOCK)
1632 * It appears that the NT redirector may have a bug, in that
1633 * it tries to do an SMBmv on a file that it has open with a
1634 * batch oplock, and then fails to respond to the oplock break
1635 * request. This only seems to occur when the client is doing an
1636 * SMBmv to the smbd it is using - thus we try and detect this
1637 * condition by checking if the file being moved is open and oplocked by
1638 * this smbd process, and then not sending the oplock break in this
1639 * special case. If the file was open with a deny mode that
1640 * prevents the move the SMBmv will fail anyway with a share
1641 * violation error. JRA.
1643 if(rename_op && (share_entry->pid == pid))
1645 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1646 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1648 * This next line is a test that allows the deny-mode
1649 * processing to be skipped. This seems to be needed as
1650 * NT insists on the rename succeeding (in Office 9x no less !).
1651 * This should be removed as soon as (a) MS fix the redirector
1652 * bug or (b) NT SMB support in Samba makes NT not issue the
1653 * call (as is my fervent hope). JRA.
1659 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1660 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1662 /* Oplock break.... */
1663 unlock_share_entry(cnum, dev, inode, token);
1664 if(request_oplock_break(share_entry, dev, inode) == False)
1666 free((char *)old_shares);
1667 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1668 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1671 lock_share_entry(cnum, dev, inode, &token);
1672 broke_oplock = True;
1677 /* someone else has a share lock on it, check to see
1679 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1686 free((char *)old_shares);
1687 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1689 } while(broke_oplock);
1692 /* XXXX exactly what share mode combinations should be allowed for
1693 deleting/renaming? */
1694 /* If we got here then either there were no share modes or
1695 all share modes were DENY_DOS and the pid == getpid() */
1700 unlock_share_entry(cnum, dev, inode, token);
1701 if(old_shares != NULL)
1702 free((char *)old_shares);
1706 /****************************************************************************
1708 Helper for open_file_shared.
1709 Truncate a file after checking locking; close file if locked.
1710 **************************************************************************/
1711 static void truncate_unless_locked(int fnum, int cnum, int token,
1714 if (Files[fnum].can_write){
1715 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1716 /* If share modes are in force for this connection we
1717 have the share entry locked. Unlock it before closing. */
1718 if (*share_locked && lp_share_modes(SNUM(cnum)))
1719 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1720 Files[fnum].fd_ptr->inode, token);
1721 close_file(fnum,False);
1722 /* Share mode no longer locked. */
1723 *share_locked = False;
1725 unix_ERR_class = ERRDOS;
1726 unix_ERR_code = ERRlock;
1729 ftruncate(Files[fnum].fd_ptr->fd,0);
1733 /****************************************************************************
1734 check if we can open a file with a share mode
1735 ****************************************************************************/
1736 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1737 BOOL fcbopen, int *flags)
1739 int old_open_mode = share->share_mode &0xF;
1740 int old_deny_mode = (share->share_mode >>4)&7;
1742 if (old_deny_mode > 4 || old_open_mode > 2)
1744 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1745 deny_mode,old_deny_mode,old_open_mode,fname));
1750 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1753 if ((access_allowed == AFAIL) ||
1754 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1755 (access_allowed == AREAD && *flags == O_WRONLY) ||
1756 (access_allowed == AWRITE && *flags == O_RDONLY))
1758 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1759 deny_mode,old_deny_mode,old_open_mode,
1760 share->pid,fname, fcbopen, *flags, access_allowed));
1764 if (access_allowed == AREAD)
1767 if (access_allowed == AWRITE)
1774 /****************************************************************************
1775 open a file with a share mode
1776 ****************************************************************************/
1777 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1778 int mode,int oplock_request, int *Access,int *action)
1780 files_struct *fs_p = &Files[fnum];
1783 int deny_mode = (share_mode>>4)&7;
1785 BOOL file_existed = file_exist(fname,&sbuf);
1786 BOOL share_locked = False;
1787 BOOL fcbopen = False;
1791 int num_share_modes = 0;
1796 /* this is for OS/2 EAs - try and say we don't support them */
1797 if (strstr(fname,".+,;=[]."))
1799 unix_ERR_class = ERRDOS;
1800 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1801 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1802 unix_ERR_code = ERRcannotopen;
1803 #else /* OS2_WPS_FIX */
1804 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1805 #endif /* OS2_WPS_FIX */
1810 if ((ofun & 0x3) == 0 && file_existed)
1818 if ((ofun & 0x3) == 2)
1821 /* note that we ignore the append flag as
1822 append does not mean the same thing under dos and unix */
1824 switch (share_mode&0xF)
1842 if (share_mode&(1<<14)) {
1847 if (flags != O_RDONLY && file_existed &&
1848 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1858 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1860 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1865 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1867 if (lp_share_modes(SNUM(cnum)))
1870 share_mode_entry *old_shares = 0;
1874 dev = (uint32)sbuf.st_dev;
1875 inode = (uint32)sbuf.st_ino;
1876 lock_share_entry(cnum, dev, inode, &token);
1877 share_locked = True;
1878 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1882 * Check if the share modes will give us access.
1885 if(share_locked && (num_share_modes != 0))
1892 broke_oplock = False;
1893 for(i = 0; i < num_share_modes; i++)
1895 share_mode_entry *share_entry = &old_shares[i];
1898 * By observation of NetBench, oplocks are broken *before* share
1899 * modes are checked. This allows a file to be closed by the client
1900 * if the share mode would deny access and the client has an oplock.
1901 * Check if someone has an oplock on this file. If so we must break
1902 * it before continuing.
1904 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1907 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1908 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1910 /* Oplock break.... */
1911 unlock_share_entry(cnum, dev, inode, token);
1912 if(request_oplock_break(share_entry, dev, inode) == False)
1914 free((char *)old_shares);
1915 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1916 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1918 unix_ERR_class = ERRDOS;
1919 unix_ERR_code = ERRbadshare;
1922 lock_share_entry(cnum, dev, inode, &token);
1923 broke_oplock = True;
1927 /* someone else has a share lock on it, check to see
1929 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1931 free((char *)old_shares);
1932 unlock_share_entry(cnum, dev, inode, token);
1934 unix_ERR_class = ERRDOS;
1935 unix_ERR_code = ERRbadshare;
1943 free((char *)old_shares);
1944 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1946 } while(broke_oplock);
1950 free((char *)old_shares);
1953 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1954 flags,flags2,mode));
1956 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1957 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1960 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1967 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1969 /* We created the file - thus we must now lock the share entry before creating it. */
1970 dev = fs_p->fd_ptr->dev;
1971 inode = fs_p->fd_ptr->inode;
1972 lock_share_entry(cnum, dev, inode, &token);
1973 share_locked = True;
1989 fs_p->share_mode = (deny_mode<<4) | open_mode;
1992 (*Access) = open_mode;
1996 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1997 if (!file_existed) *action = 2;
1998 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
2000 /* We must create the share mode entry before truncate as
2001 truncate can fail due to locking and have to close the
2002 file (which expects the share_mode_entry to be there).
2004 if (lp_share_modes(SNUM(cnum)))
2007 /* JRA. Currently this only services Exlcusive and batch
2008 oplocks (no other opens on this file). This needs to
2009 be extended to level II oplocks (multiple reader
2012 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
2013 !IS_VETO_OPLOCK_PATH(cnum,fname))
2015 fs_p->granted_oplock = True;
2016 fs_p->sent_oplock_break = False;
2017 global_oplocks_open++;
2020 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2021 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2029 set_share_mode(token, fnum, port, oplock_request);
2032 if ((flags2&O_TRUNC) && file_existed)
2033 truncate_unless_locked(fnum,cnum,token,&share_locked);
2036 if (share_locked && lp_share_modes(SNUM(cnum)))
2037 unlock_share_entry( cnum, dev, inode, token);
2040 /****************************************************************************
2041 seek a file. Try to avoid the seek if possible
2042 ****************************************************************************/
2043 int seek_file(int fnum,uint32 pos)
2046 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2049 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2051 return(Files[fnum].pos);
2054 /****************************************************************************
2056 ****************************************************************************/
2057 int read_file(int fnum,char *data,uint32 pos,int n)
2061 #if USE_READ_PREDICTION
2062 if (!Files[fnum].can_write)
2064 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2073 if (Files[fnum].mmap_ptr)
2075 int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2079 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2091 if (seek_file(fnum,pos) != pos)
2093 DEBUG(3,("Failed to seek to %d\n",pos));
2098 readret = read(Files[fnum].fd_ptr->fd,data,n);
2099 if (readret > 0) ret += readret;
2106 /****************************************************************************
2108 ****************************************************************************/
2109 int write_file(int fnum,char *data,int n)
2111 if (!Files[fnum].can_write) {
2116 if (!Files[fnum].modified) {
2118 Files[fnum].modified = True;
2119 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2120 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2121 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2122 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2127 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2131 /****************************************************************************
2132 load parameters specific to a connection/service
2133 ****************************************************************************/
2134 BOOL become_service(int cnum,BOOL do_chdir)
2136 extern char magic_char;
2137 static int last_cnum = -1;
2140 if (!OPEN_CNUM(cnum))
2146 Connections[cnum].lastused = smb_last_time;
2151 ChDir(Connections[cnum].connectpath) != 0 &&
2152 ChDir(Connections[cnum].origpath) != 0)
2154 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2155 Connections[cnum].connectpath,cnum));
2159 if (cnum == last_cnum)
2164 case_default = lp_defaultcase(snum);
2165 case_preserve = lp_preservecase(snum);
2166 short_case_preserve = lp_shortpreservecase(snum);
2167 case_mangle = lp_casemangle(snum);
2168 case_sensitive = lp_casesensitive(snum);
2169 magic_char = lp_magicchar(snum);
2170 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2175 /****************************************************************************
2176 find a service entry
2177 ****************************************************************************/
2178 int find_service(char *service)
2182 string_sub(service,"\\","/");
2184 iService = lp_servicenumber(service);
2186 /* now handle the special case of a home directory */
2189 char *phome_dir = get_home_dir(service);
2190 DEBUG(3,("checking for home directory %s gave %s\n",service,
2191 phome_dir?phome_dir:"(NULL)"));
2195 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2197 lp_add_home(service,iHomeService,phome_dir);
2198 iService = lp_servicenumber(service);
2203 /* If we still don't have a service, attempt to add it as a printer. */
2206 int iPrinterService;
2208 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2212 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2214 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2216 DEBUG(3,("%s is a valid printer name\n", service));
2217 DEBUG(3,("adding %s as a printer service\n", service));
2218 lp_add_printer(service,iPrinterService);
2219 iService = lp_servicenumber(service);
2221 DEBUG(0,("failed to add %s as a printer service!\n", service));
2224 DEBUG(3,("%s is not a valid printer name\n", service));
2228 /* just possibly it's a default service? */
2231 char *pdefservice = lp_defaultservice();
2232 if (pdefservice && *pdefservice && !strequal(pdefservice,service)) {
2234 * We need to do a local copy here as lp_defaultservice()
2235 * returns one of the rotating lp_string buffers that
2236 * could get overwritten by the recursive find_service() call
2237 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2240 pstrcpy(defservice, pdefservice);
2241 iService = find_service(defservice);
2242 if (iService >= 0) {
2243 string_sub(service,"_","/");
2244 iService = lp_add_service(service,iService);
2250 if (!VALID_SNUM(iService))
2252 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2257 DEBUG(3,("find_service() failed to find service %s\n", service));
2263 /****************************************************************************
2264 create an error packet from a cached error.
2265 ****************************************************************************/
2266 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2268 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2270 int32 eclass = wbmpx->wr_errclass;
2271 int32 err = wbmpx->wr_error;
2273 /* We can now delete the auxiliary struct */
2274 free((char *)wbmpx);
2275 Files[fnum].wbmpx_ptr = NULL;
2276 return error_packet(inbuf,outbuf,eclass,err,line);
2285 } unix_smb_errmap[] =
2287 {EPERM,ERRDOS,ERRnoaccess},
2288 {EACCES,ERRDOS,ERRnoaccess},
2289 {ENOENT,ERRDOS,ERRbadfile},
2290 {ENOTDIR,ERRDOS,ERRbadpath},
2291 {EIO,ERRHRD,ERRgeneral},
2292 {EBADF,ERRSRV,ERRsrverror},
2293 {EINVAL,ERRSRV,ERRsrverror},
2294 {EEXIST,ERRDOS,ERRfilexists},
2295 {ENFILE,ERRDOS,ERRnofids},
2296 {EMFILE,ERRDOS,ERRnofids},
2297 {ENOSPC,ERRHRD,ERRdiskfull},
2299 {EDQUOT,ERRHRD,ERRdiskfull},
2302 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2305 {EXDEV,ERRDOS,ERRdiffdevice},
2307 {EROFS,ERRHRD,ERRnowrite},
2311 /****************************************************************************
2312 create an error packet from errno
2313 ****************************************************************************/
2314 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2316 int eclass=def_class;
2320 if (unix_ERR_class != SMB_SUCCESS)
2322 eclass = unix_ERR_class;
2323 ecode = unix_ERR_code;
2324 unix_ERR_class = SMB_SUCCESS;
2329 while (unix_smb_errmap[i].smbclass != 0)
2331 if (unix_smb_errmap[i].unixerror == errno)
2333 eclass = unix_smb_errmap[i].smbclass;
2334 ecode = unix_smb_errmap[i].smbcode;
2341 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2345 /****************************************************************************
2346 create an error packet. Normally called using the ERROR() macro
2347 ****************************************************************************/
2348 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2350 int outsize = set_message(outbuf,0,0,True);
2351 int cmd = CVAL(inbuf,smb_com);
2352 int flgs2 = SVAL(outbuf,smb_flg2);
2354 if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2356 SIVAL(outbuf,smb_rcls,error_code);
2358 DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2359 timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2363 CVAL(outbuf,smb_rcls) = error_class;
2364 SSVAL(outbuf,smb_err,error_code);
2365 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2368 (int)CVAL(inbuf,smb_com),
2369 smb_fn_name(CVAL(inbuf,smb_com)),
2376 DEBUG(3,("error string = %s\n",strerror(errno)));
2382 #ifndef SIGCLD_IGNORE
2383 /****************************************************************************
2384 this prevents zombie child processes
2385 ****************************************************************************/
2386 static int sig_cld(void)
2388 static int depth = 0;
2391 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2397 BlockSignals(True,SIGCLD);
2398 DEBUG(5,("got SIGCLD\n"));
2401 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2405 /* Stevens, Adv. Unix Prog. says that on system V you must call
2406 wait before reinstalling the signal handler, because the kernel
2407 calls the handler from within the signal-call when there is a
2408 child that has exited. This would lead to an infinite recursion
2409 if done vice versa. */
2411 #ifndef DONT_REINSTALL_SIG
2412 #ifdef SIGCLD_IGNORE
2413 signal(SIGCLD, SIG_IGN);
2415 signal(SIGCLD, SIGNAL_CAST sig_cld);
2420 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2423 BlockSignals(False,SIGCLD);
2428 /****************************************************************************
2429 this is called when the client exits abruptly
2430 **************************************************************************/
2431 static int sig_pipe(void)
2433 struct cli_state *cli;
2434 BlockSignals(True,SIGPIPE);
2436 if ((cli = server_client()) && cli->initialised) {
2437 DEBUG(3,("lost connection to password server\n"));
2439 #ifndef DONT_REINSTALL_SIG
2440 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2442 BlockSignals(False,SIGPIPE);
2446 exit_server("Got sigpipe\n");
2450 /****************************************************************************
2451 open the socket communication
2452 ****************************************************************************/
2453 static BOOL open_sockets(BOOL is_daemon,int port)
2459 int num_interfaces = iface_count();
2460 int fd_listenset[FD_SETSIZE];
2466 #ifdef SIGCLD_IGNORE
2467 signal(SIGCLD, SIG_IGN);
2469 signal(SIGCLD, SIGNAL_CAST sig_cld);
2475 FD_ZERO(&listen_set);
2477 if(lp_interfaces() && lp_bind_interfaces_only())
2479 /* We have been given an interfaces line, and been
2480 told to only bind to those interfaces. Create a
2481 socket per interface and bind to only these.
2484 if(num_interfaces > FD_SETSIZE)
2486 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2487 max can be %d\n", num_interfaces, FD_SETSIZE));
2491 /* Now open a listen socket for each of the interfaces. */
2492 for(i = 0; i < num_interfaces; i++)
2494 struct in_addr *ifip = iface_n_ip(i);
2498 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2501 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2504 /* ready to listen */
2505 if (listen(s, 5) == -1)
2507 DEBUG(0,("listen: %s\n",strerror(errno)));
2511 FD_SET(s,&listen_set);
2516 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2519 /* open an incoming socket */
2520 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2524 /* ready to listen */
2525 if (listen(s, 5) == -1)
2527 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2532 fd_listenset[0] = s;
2533 FD_SET(s,&listen_set);
2536 /* now accept incoming connections - forking a new process
2537 for each incoming connection */
2538 DEBUG(2,("waiting for a connection\n"));
2544 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2546 num = sys_select(&lfds,NULL);
2548 if (num == -1 && errno == EINTR)
2551 /* Find the sockets that are read-ready - accept on these. */
2552 for( ; num > 0; num--)
2554 struct sockaddr addr;
2555 int in_addrlen = sizeof(addr);
2558 for(i = 0; i < num_interfaces; i++)
2560 if(FD_ISSET(fd_listenset[i],&lfds))
2562 s = fd_listenset[i];
2563 /* Clear this so we don't look at it again. */
2564 FD_CLR(fd_listenset[i],&lfds);
2569 Client = accept(s,&addr,&in_addrlen);
2571 if (Client == -1 && errno == EINTR)
2576 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2580 #ifdef NO_FORK_DEBUG
2581 #ifndef NO_SIGNAL_TEST
2582 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2583 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2584 #endif /* NO_SIGNAL_TEST */
2586 #else /* NO_FORK_DEBUG */
2587 if (Client != -1 && fork()==0)
2589 /* Child code ... */
2591 #ifndef NO_SIGNAL_TEST
2592 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2593 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2594 #endif /* NO_SIGNAL_TEST */
2595 /* close the listening socket(s) */
2596 for(i = 0; i < num_interfaces; i++)
2597 close(fd_listenset[i]);
2599 /* close our standard file descriptors */
2603 set_socket_options(Client,"SO_KEEPALIVE");
2604 set_socket_options(Client,user_socket_options);
2606 /* Reset global variables in util.c so that
2607 client substitutions will be done correctly
2610 reset_globals_after_fork();
2613 close(Client); /* The parent doesn't need this socket */
2614 #endif /* NO_FORK_DEBUG */
2617 } /* end if is_daemon */
2620 /* Started from inetd. fd 0 is the socket. */
2621 /* We will abort gracefully when the client or remote system
2623 #ifndef NO_SIGNAL_TEST
2624 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2628 /* close our standard file descriptors */
2631 set_socket_options(Client,"SO_KEEPALIVE");
2632 set_socket_options(Client,user_socket_options);
2638 /****************************************************************************
2639 process an smb from the client - split out from the process() code so
2640 it can be used by the oplock break code.
2641 ****************************************************************************/
2643 static void process_smb(char *inbuf, char *outbuf)
2646 static int trans_num;
2647 int msg_type = CVAL(inbuf,0);
2648 int32 len = smb_len(inbuf);
2649 int nread = len + 4;
2651 if (trans_num == 0) {
2652 /* on the first packet, check the global hosts allow/ hosts
2653 deny parameters before doing any parsing of the packet
2654 passed to us by the client. This prevents attacks on our
2655 parsing code from hosts not in the hosts allow list */
2656 if (!check_access(-1)) {
2657 /* send a negative session response "not listining on calling
2659 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2660 DEBUG(1,("%s Connection denied from %s\n",
2661 timestring(),client_addr(Client)));
2662 send_smb(Client,(char *)buf);
2663 exit_server("connection denied");
2667 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2668 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2671 if(trans_num == 1 && VT_Check(inbuf))
2680 else if(msg_type == 0x85)
2681 return; /* Keepalive packet. */
2683 nread = construct_reply(inbuf,outbuf,nread,max_send);
2687 if (CVAL(outbuf,0) == 0)
2690 if (nread != smb_len(outbuf) + 4)
2692 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2693 nread, smb_len(outbuf)));
2696 send_smb(Client,outbuf);
2701 /****************************************************************************
2702 open the oplock IPC socket communication
2703 ****************************************************************************/
2704 static BOOL open_oplock_ipc(void)
2706 struct sockaddr_in sock_name;
2707 int len = sizeof(sock_name);
2709 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2711 /* Open a lookback UDP socket on a random port. */
2712 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2713 if (oplock_sock == -1)
2715 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2716 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2721 /* Find out the transient UDP port we have been allocated. */
2722 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2724 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2731 oplock_port = ntohs(sock_name.sin_port);
2733 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2734 getpid(), oplock_port));
2739 /****************************************************************************
2740 process an oplock break message.
2741 ****************************************************************************/
2742 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2748 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2749 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2751 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2753 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2754 msg_len, from_port));
2756 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2757 only valid request. */
2759 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2761 case OPLOCK_BREAK_CMD:
2762 /* Ensure that the msg length is correct. */
2763 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2765 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2766 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2770 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2771 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2772 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2773 struct timeval tval;
2774 struct sockaddr_in toaddr;
2776 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2777 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2779 DEBUG(5,("process_local_message: oplock break request from \
2780 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2783 * If we have no record of any currently open oplocks,
2784 * it's not an error, as a close command may have
2785 * just been issued on the file that was oplocked.
2786 * Just return success in this case.
2789 if(global_oplocks_open != 0)
2791 if(oplock_break(dev, inode, &tval) == False)
2793 DEBUG(0,("process_local_message: oplock break failed - \
2794 not returning udp message.\n"));
2800 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2801 oplocks. Returning success.\n"));
2804 /* Send the message back after OR'ing in the 'REPLY' bit. */
2805 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2807 bzero((char *)&toaddr,sizeof(toaddr));
2808 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2809 toaddr.sin_port = htons(from_port);
2810 toaddr.sin_family = AF_INET;
2812 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2813 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2815 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2816 remotepid, strerror(errno)));
2820 DEBUG(5,("process_local_message: oplock break reply sent to \
2821 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2822 from_port, dev, inode));
2827 * Keep this as a debug case - eventually we can remove it.
2830 DEBUG(0,("process_local_message: Received unsolicited break \
2831 reply - dumping info.\n"));
2833 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2835 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2836 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2841 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2842 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2843 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2845 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2846 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2852 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2853 (unsigned int)SVAL(msg_start,0)));
2859 /****************************************************************************
2860 Process an oplock break directly.
2861 ****************************************************************************/
2862 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2866 char *outbuf = NULL;
2867 files_struct *fsp = NULL;
2870 BOOL shutdown_server = False;
2872 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2873 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2875 /* We need to search the file open table for the
2876 entry containing this dev and inode, and ensure
2877 we have an oplock on it. */
2878 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2882 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2883 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2884 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2893 /* The file could have been closed in the meantime - return success. */
2894 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2895 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2899 /* Ensure we have an oplock on the file */
2901 /* There is a potential race condition in that an oplock could
2902 have been broken due to another udp request, and yet there are
2903 still oplock break messages being sent in the udp message
2904 queue for this file. So return true if we don't have an oplock,
2905 as we may have just freed it.
2908 if(!fsp->granted_oplock)
2910 DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2914 /* mark the oplock break as sent - we don't want to send twice! */
2915 if (fsp->sent_oplock_break)
2917 DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
2919 /* We have to fail the open here as we cannot send another oplock break on this
2920 file whilst we are awaiting a response from the client - neither can we
2921 allow another open to succeed while we are waiting for the client. */
2925 /* Now comes the horrid part. We must send an oplock break to the client,
2926 and then process incoming messages until we get a close or oplock release.
2927 At this point we know we need a new inbuf/outbuf buffer pair.
2928 We cannot use these staticaly as we may recurse into here due to
2929 messages crossing on the wire.
2932 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2934 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2938 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2940 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2946 /* Prepare the SMBlockingX message. */
2947 bzero(outbuf,smb_size);
2948 set_message(outbuf,8,0,True);
2950 SCVAL(outbuf,smb_com,SMBlockingX);
2951 SSVAL(outbuf,smb_tid,fsp->cnum);
2952 SSVAL(outbuf,smb_pid,0xFFFF);
2953 SSVAL(outbuf,smb_uid,0);
2954 SSVAL(outbuf,smb_mid,0xFFFF);
2955 SCVAL(outbuf,smb_vwv0,0xFF);
2956 SSVAL(outbuf,smb_vwv2,fnum);
2957 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2958 /* Change this when we have level II oplocks. */
2959 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2961 send_smb(Client, outbuf);
2963 /* Remember we just sent an oplock break on this file. */
2964 fsp->sent_oplock_break = True;
2966 /* We need this in case a readraw crosses on the wire. */
2967 global_oplock_break = True;
2969 /* Process incoming messages. */
2971 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2972 seconds we should just die.... */
2974 start_time = time(NULL);
2976 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2978 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2981 * Die if we got an error.
2984 if (smb_read_error == READ_EOF)
2985 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2987 if (smb_read_error == READ_ERROR)
2988 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2989 timestring(), strerror(errno)));
2991 if (smb_read_error == READ_TIMEOUT)
2992 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2993 timestring(), OPLOCK_BREAK_TIMEOUT));
2995 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2996 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2997 shutdown_server = True;
3002 * There are certain SMB requests that we shouldn't allow
3003 * to recurse. opens, renames and deletes are the obvious
3004 * ones. This is handled in the switch_message() function.
3005 * If global_oplock_break is set they will push the packet onto
3006 * the pending smb queue and return -1 (no reply).
3010 process_smb(inbuf, outbuf);
3013 * Die if we go over the time limit.
3016 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3018 DEBUG(0,("%s oplock_break: no break received from client within \
3019 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3020 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3021 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3022 shutdown_server = True;
3027 /* Free the buffers we've been using to recurse. */
3031 /* We need this in case a readraw crossed on the wire. */
3032 if(global_oplock_break)
3033 global_oplock_break = False;
3036 * If the client did not respond we must die.
3041 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3045 exit_server("oplock break failure");
3050 /* The lockingX reply will have removed the oplock flag
3051 from the sharemode. */
3053 fsp->granted_oplock = False;
3054 fsp->sent_oplock_break = False;
3055 global_oplocks_open--;
3058 /* Santity check - remove this later. JRA */
3059 if(global_oplocks_open < 0)
3061 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3062 global_oplocks_open));
3063 exit_server("oplock_break: global_oplocks_open < 0");
3066 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3067 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3072 /****************************************************************************
3073 Send an oplock break message to another smbd process. If the oplock is held
3074 by the local smbd then call the oplock break function directly.
3075 ****************************************************************************/
3077 BOOL request_oplock_break(share_mode_entry *share_entry,
3078 uint32 dev, uint32 inode)
3080 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3081 struct sockaddr_in addr_out;
3086 if(pid == share_entry->pid)
3088 /* We are breaking our own oplock, make sure it's us. */
3089 if(share_entry->op_port != oplock_port)
3091 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3092 should be %d\n", pid, share_entry->op_port, oplock_port));
3096 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3098 /* Call oplock break direct. */
3099 return oplock_break(dev, inode, &share_entry->time);
3102 /* We need to send a OPLOCK_BREAK_CMD message to the
3103 port in the share mode entry. */
3105 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3106 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3107 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3108 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3109 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3110 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3112 /* set the address and port */
3113 bzero((char *)&addr_out,sizeof(addr_out));
3114 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3115 addr_out.sin_port = htons( share_entry->op_port );
3116 addr_out.sin_family = AF_INET;
3118 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3119 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3121 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3122 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3124 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3125 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3126 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3132 * Now we must await the oplock broken message coming back
3133 * from the target smbd process. Timeout if it fails to
3134 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3135 * While we get messages that aren't ours, loop.
3138 start_time = time(NULL);
3139 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3141 while(time_left >= 0)
3143 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3144 int32 reply_msg_len;
3145 uint16 reply_from_port;
3146 char *reply_msg_start;
3148 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3149 time_left ? time_left * 1000 : 1) == False)
3151 if(smb_read_error == READ_TIMEOUT)
3153 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3154 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3155 share_entry->op_port, dev, inode));
3157 * This is a hack to make handling of failing clients more robust.
3158 * If a oplock break response message is not received in the timeout
3159 * period we may assume that the smbd servicing that client holding
3160 * the oplock has died and the client changes were lost anyway, so
3161 * we should continue to try and open the file.
3166 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3167 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3168 share_entry->op_port, dev, inode, strerror(errno)));
3172 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3173 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3175 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3177 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3180 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3186 * Test to see if this is the reply we are awaiting.
3189 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3190 (reply_from_port == share_entry->op_port) &&
3191 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3192 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3193 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3196 * This is the reply we've been waiting for.
3203 * This is another message - probably a break request.
3204 * Process it to prevent potential deadlock.
3205 * Note that the code in switch_message() prevents
3206 * us from recursing into here as any SMB requests
3207 * we might process that would cause another oplock
3208 * break request to be made will be queued.
3212 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3215 time_left -= (time(NULL) - start_time);
3218 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3223 /****************************************************************************
3224 Get the next SMB packet, doing the local message processing automatically.
3225 ****************************************************************************/
3227 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3229 BOOL got_smb = False;
3234 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3239 /* Deal with oplock break requests from other smbd's. */
3240 process_local_message(oplock_sock, inbuf, bufsize);
3244 if(ret && (CVAL(inbuf,0) == 0x85))
3246 /* Keepalive packet. */
3251 while(ret && !got_smb);
3256 /****************************************************************************
3257 check if a snum is in use
3258 ****************************************************************************/
3259 BOOL snum_used(int snum)
3262 for (i=0;i<MAX_CONNECTIONS;i++)
3263 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3268 /****************************************************************************
3269 reload the services file
3270 **************************************************************************/
3271 BOOL reload_services(BOOL test)
3278 pstrcpy(fname,lp_configfile());
3279 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3281 pstrcpy(servicesf,fname);
3288 if (test && !lp_file_list_changed())
3291 lp_killunused(snum_used);
3293 ret = lp_load(servicesf,False,False,True);
3295 /* perhaps the config filename is now set */
3297 reload_services(True);
3306 set_socket_options(Client,"SO_KEEPALIVE");
3307 set_socket_options(Client,user_socket_options);
3311 reset_mangled_cache();
3313 /* this forces service parameters to be flushed */
3314 become_service(-1,True);
3321 /****************************************************************************
3322 this prevents zombie child processes
3323 ****************************************************************************/
3324 static int sig_hup(void)
3326 BlockSignals(True,SIGHUP);
3327 DEBUG(0,("Got SIGHUP\n"));
3328 reload_services(False);
3329 #ifndef DONT_REINSTALL_SIG
3330 signal(SIGHUP,SIGNAL_CAST sig_hup);
3332 BlockSignals(False,SIGHUP);
3337 /****************************************************************************
3338 make a connection to a service
3339 ****************************************************************************/
3340 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3344 struct passwd *pass = NULL;
3345 connection_struct *pcon;
3351 snum = find_service(service);
3355 if (strequal(service,"IPC$"))
3357 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3361 DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));
3365 if (strequal(service,HOMES_NAME))
3367 if (*user && Get_Pwnam(user,True))
3368 return(make_connection(user,user,password,pwlen,dev,vuid));
3370 if(lp_security() != SEC_SHARE)
3372 if (validated_username(vuid))
3374 strcpy(user,validated_username(vuid));
3375 return(make_connection(user,user,password,pwlen,dev,vuid));
3381 * Security = share. Try with sesssetup_user as the username.
3385 strcpy(user,sesssetup_user);
3386 return(make_connection(user,user,password,pwlen,dev,vuid));
3391 if (!lp_snum_ok(snum) || !check_access(snum)) {
3395 /* you can only connect to the IPC$ service as an ipc device */
3396 if (strequal(service,"IPC$"))
3399 if (*dev == '?' || !*dev)
3401 if (lp_print_ok(snum))
3402 strcpy(dev,"LPT1:");
3407 /* if the request is as a printer and you can't print then refuse */
3409 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3410 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3414 /* lowercase the user name */
3417 /* add it as a possible user name */
3418 add_session_user(service);
3420 /* shall we let them in? */
3421 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3423 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3427 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3430 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3434 pcon = &Connections[cnum];
3435 bzero((char *)pcon,sizeof(*pcon));
3437 /* find out some info about the user */
3438 pass = Get_Pwnam(user,True);
3442 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3446 pcon->read_only = lp_readonly(snum);
3450 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3451 string_sub(list,"%S",service);
3453 if (user_in_list(user,list))
3454 pcon->read_only = True;
3456 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3457 string_sub(list,"%S",service);
3459 if (user_in_list(user,list))
3460 pcon->read_only = False;
3463 /* admin user check */
3465 /* JRA - original code denied admin user if the share was
3466 marked read_only. Changed as I don't think this is needed,
3467 but old code left in case there is a problem here.
3469 if (user_in_list(user,lp_admin_users(snum))
3471 && !pcon->read_only)
3476 pcon->admin_user = True;
3477 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3480 pcon->admin_user = False;
3482 pcon->force_user = force;
3484 pcon->uid = pass->pw_uid;
3485 pcon->gid = pass->pw_gid;
3486 pcon->num_files_open = 0;
3487 pcon->lastused = time(NULL);
3488 pcon->service = snum;
3490 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3491 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3492 pcon->dirptr = NULL;
3493 pcon->veto_list = NULL;
3494 pcon->hide_list = NULL;
3495 pcon->veto_oplock_list = NULL;
3496 string_set(&pcon->dirpath,"");
3497 string_set(&pcon->user,user);
3500 if (*lp_force_group(snum))
3505 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3506 /* default service may be a group name */
3507 string_sub(gname,"%S",service);
3508 gptr = (struct group *)getgrnam(gname);
3512 pcon->gid = gptr->gr_gid;
3513 DEBUG(3,("Forced group %s\n",gname));
3516 DEBUG(1,("Couldn't find group %s\n",gname));
3520 if (*lp_force_user(snum))
3522 struct passwd *pass2;
3524 fstrcpy(fuser,lp_force_user(snum));
3525 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3528 pcon->uid = pass2->pw_uid;
3529 string_set(&pcon->user,fuser);
3530 fstrcpy(user,fuser);
3531 pcon->force_user = True;
3532 DEBUG(3,("Forced user %s\n",fuser));
3535 DEBUG(1,("Couldn't find user %s\n",fuser));
3540 pstrcpy(s,lp_pathname(snum));
3541 standard_sub(cnum,s);
3542 string_set(&pcon->connectpath,s);
3543 DEBUG(3,("Connect path is %s\n",s));
3546 /* groups stuff added by ih */
3548 pcon->igroups = NULL;
3549 pcon->groups = NULL;
3554 /* Find all the groups this uid is in and store them. Used by become_user() */
3555 setup_groups(pcon->user,pcon->uid,pcon->gid,
3556 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3558 /* check number of connections */
3559 if (!claim_connection(cnum,
3560 lp_servicename(SNUM(cnum)),
3561 lp_max_connections(SNUM(cnum)),False))
3563 DEBUG(1,("too many connections - rejected\n"));
3567 if (lp_status(SNUM(cnum)))
3568 claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3573 /* execute any "root preexec = " line */
3574 if (*lp_rootpreexec(SNUM(cnum)))
3577 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3578 standard_sub(cnum,cmd);
3579 DEBUG(5,("cmd=%s\n",cmd));
3580 smbrun(cmd,NULL,False);
3583 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3585 DEBUG(0,("Can't become connected user!\n"));
3587 if (!IS_IPC(cnum)) {
3588 yield_connection(cnum,
3589 lp_servicename(SNUM(cnum)),
3590 lp_max_connections(SNUM(cnum)));
3591 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3596 if (ChDir(pcon->connectpath) != 0)
3598 DEBUG(0,("Can't change directory to %s (%s)\n",
3599 pcon->connectpath,strerror(errno)));
3602 if (!IS_IPC(cnum)) {
3603 yield_connection(cnum,
3604 lp_servicename(SNUM(cnum)),
3605 lp_max_connections(SNUM(cnum)));
3606 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3611 string_set(&pcon->origpath,pcon->connectpath);
3613 #if SOFTLINK_OPTIMISATION
3614 /* resolve any soft links early */
3617 pstrcpy(s,pcon->connectpath);
3619 string_set(&pcon->connectpath,s);
3620 ChDir(pcon->connectpath);
3624 num_connections_open++;
3625 add_session_user(user);
3627 /* execute any "preexec = " line */
3628 if (*lp_preexec(SNUM(cnum)))
3631 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3632 standard_sub(cnum,cmd);
3633 smbrun(cmd,NULL,False);
3636 /* we've finished with the sensitive stuff */
3639 /* Add veto/hide lists */
3640 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3642 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3643 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3644 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3649 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3652 client_addr(Client),
3653 lp_servicename(SNUM(cnum)),user,
3662 /****************************************************************************
3663 Attempt to break an oplock on a file (if oplocked).
3664 Returns True if the file was closed as a result of
3665 the oplock break, False otherwise.
3666 Used as a last ditch attempt to free a space in the
3667 file table when we have run out.
3668 ****************************************************************************/
3670 static BOOL attempt_close_oplocked_file(files_struct *fp)
3673 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3675 if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3677 /* Try and break the oplock. */
3678 file_fd_struct *fsp = fp->fd_ptr;
3679 if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3680 if(!fp->open) /* Did the oplock break close the file ? */
3688 /****************************************************************************
3689 find first available file slot
3690 ****************************************************************************/
3691 int find_free_file(void )
3694 static int first_file;
3696 /* we want to give out file handles differently on each new
3697 connection because of a common bug in MS clients where they try to
3698 reuse a file descriptor from an earlier smb connection. This code
3699 increases the chance that the errant client will get an error rather
3700 than causing corruption */
3701 if (first_file == 0) {
3702 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3703 if (first_file == 0) first_file = 1;
3706 if (first_file >= MAX_OPEN_FILES)
3709 for (i=first_file;i<MAX_OPEN_FILES;i++)
3710 if (!Files[i].open && !Files[i].reserved) {
3711 memset(&Files[i], 0, sizeof(Files[i]));
3713 Files[i].reserved = True;
3717 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3718 for (i=1;i<first_file;i++)
3719 if (!Files[i].open && !Files[i].reserved) {
3720 memset(&Files[i], 0, sizeof(Files[i]));
3722 Files[i].reserved = True;
3727 * Before we give up, go through the open files
3728 * and see if there are any files opened with a
3729 * batch oplock. If so break the oplock and then
3730 * re-use that entry (if it becomes closed).
3731 * This may help as NT/95 clients tend to keep
3732 * files batch oplocked for quite a long time
3733 * after they have finished with them.
3735 for (i=first_file;i<MAX_OPEN_FILES;i++) {
3736 if(attempt_close_oplocked_file( &Files[i])) {
3737 memset(&Files[i], 0, sizeof(Files[i]));
3739 Files[i].reserved = True;
3744 for (i=1;i<MAX_OPEN_FILES;i++) {
3745 if(attempt_close_oplocked_file( &Files[i])) {
3746 memset(&Files[i], 0, sizeof(Files[i]));
3748 Files[i].reserved = True;
3753 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3757 /****************************************************************************
3758 find first available connection slot, starting from a random position.
3759 The randomisation stops problems with the server dieing and clients
3760 thinking the server is still available.
3761 ****************************************************************************/
3762 static int find_free_connection(int hash )
3766 hash = (hash % (MAX_CONNECTIONS-2))+1;
3770 for (i=hash+1;i!=hash;)
3772 if (!Connections[i].open && Connections[i].used == used)
3774 DEBUG(3,("found free connection number %d\n",i));
3778 if (i == MAX_CONNECTIONS)
3788 DEBUG(1,("ERROR! Out of connection structures\n"));
3793 /****************************************************************************
3794 reply for the core protocol
3795 ****************************************************************************/
3796 int reply_corep(char *outbuf)
3798 int outsize = set_message(outbuf,1,0,True);
3800 Protocol = PROTOCOL_CORE;
3806 /****************************************************************************
3807 reply for the coreplus protocol
3808 ****************************************************************************/
3809 int reply_coreplus(char *outbuf)
3811 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3812 int outsize = set_message(outbuf,13,0,True);
3813 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3814 readbraw and writebraw (possibly) */
3815 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3816 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3818 Protocol = PROTOCOL_COREPLUS;
3824 /****************************************************************************
3825 reply for the lanman 1.0 protocol
3826 ****************************************************************************/
3827 int reply_lanman1(char *outbuf)
3829 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3831 BOOL doencrypt = SMBENCRYPT();
3832 time_t t = time(NULL);
3834 if (lp_security()>=SEC_USER) secword |= 1;
3835 if (doencrypt) secword |= 2;
3837 set_message(outbuf,13,doencrypt?8:0,True);
3838 SSVAL(outbuf,smb_vwv1,secword);
3839 /* Create a token value and add it to the outgoing packet. */
3841 generate_next_challenge(smb_buf(outbuf));
3843 Protocol = PROTOCOL_LANMAN1;
3845 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3846 SSVAL(outbuf,smb_vwv2,max_recv);
3847 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3848 SSVAL(outbuf,smb_vwv4,1);
3849 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3850 readbraw writebraw (possibly) */
3851 SIVAL(outbuf,smb_vwv6,getpid());
3852 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3854 put_dos_date(outbuf,smb_vwv8,t);
3856 return (smb_len(outbuf)+4);
3860 /****************************************************************************
3861 reply for the lanman 2.0 protocol
3862 ****************************************************************************/
3863 int reply_lanman2(char *outbuf)
3865 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3867 BOOL doencrypt = SMBENCRYPT();
3868 time_t t = time(NULL);
3869 struct cli_state *cli = NULL;
3873 if (lp_security() == SEC_SERVER) {
3874 cli = server_cryptkey();
3878 DEBUG(3,("using password server validation\n"));
3879 doencrypt = ((cli->sec_mode & 2) != 0);
3882 if (lp_security()>=SEC_USER) secword |= 1;
3883 if (doencrypt) secword |= 2;
3888 generate_next_challenge(cryptkey);
3890 memcpy(cryptkey, cli->cryptkey, 8);
3891 set_challenge(cli->cryptkey);
3895 set_message(outbuf,13,crypt_len,True);
3896 SSVAL(outbuf,smb_vwv1,secword);
3897 SIVAL(outbuf,smb_vwv6,getpid());
3899 memcpy(smb_buf(outbuf), cryptkey, 8);
3901 Protocol = PROTOCOL_LANMAN2;
3903 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3904 SSVAL(outbuf,smb_vwv2,max_recv);
3905 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3906 SSVAL(outbuf,smb_vwv4,1);
3907 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3908 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3909 put_dos_date(outbuf,smb_vwv8,t);
3911 return (smb_len(outbuf)+4);
3915 /****************************************************************************
3916 reply for the nt protocol
3917 ****************************************************************************/
3918 int reply_nt1(char *outbuf)
3920 /* dual names + lock_and_read + nt SMBs + remote API calls */
3921 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
3923 other valid capabilities which we may support at some time...
3924 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3925 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3929 BOOL doencrypt = SMBENCRYPT();
3930 time_t t = time(NULL);
3932 struct cli_state *cli = NULL;
3936 if (lp_security() == SEC_SERVER) {
3937 cli = server_cryptkey();
3941 DEBUG(3,("using password server validation\n"));
3942 doencrypt = ((cli->sec_mode & 2) != 0);
3948 generate_next_challenge(cryptkey);
3950 memcpy(cryptkey, cli->cryptkey, 8);
3951 set_challenge(cli->cryptkey);
3955 if (lp_readraw() && lp_writeraw()) {
3956 capabilities |= CAP_RAW_MODE;
3959 if (lp_security() >= SEC_USER) secword |= 1;
3960 if (doencrypt) secword |= 2;
3962 /* decide where (if) to put the encryption challenge, and
3963 follow it with the OEM'd domain name
3965 data_len = crypt_len + strlen(global_myworkgroup) + 1;
3967 set_message(outbuf,17,data_len,True);
3968 strcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
3970 CVAL(outbuf,smb_vwv1) = secword;
3971 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3973 memcpy(smb_buf(outbuf), cryptkey, 8);
3975 Protocol = PROTOCOL_NT1;
3977 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3978 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3979 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3980 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
3981 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3982 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3983 put_long_date(outbuf+smb_vwv11+1,t);
3984 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3985 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3987 return (smb_len(outbuf)+4);
3990 /* these are the protocol lists used for auto architecture detection:
3993 protocol [PC NETWORK PROGRAM 1.0]
3994 protocol [XENIX CORE]
3995 protocol [MICROSOFT NETWORKS 1.03]
3996 protocol [LANMAN1.0]
3997 protocol [Windows for Workgroups 3.1a]
3998 protocol [LM1.2X002]
3999 protocol [LANMAN2.1]
4000 protocol [NT LM 0.12]
4003 protocol [PC NETWORK PROGRAM 1.0]
4004 protocol [XENIX CORE]
4005 protocol [MICROSOFT NETWORKS 1.03]
4006 protocol [LANMAN1.0]
4007 protocol [Windows for Workgroups 3.1a]
4008 protocol [LM1.2X002]
4009 protocol [LANMAN2.1]
4010 protocol [NT LM 0.12]
4013 protocol [PC NETWORK PROGRAM 1.0]
4014 protocol [XENIX CORE]
4015 protocol [LANMAN1.0]
4016 protocol [LM1.2X002]
4017 protocol [LANMAN2.1]
4021 * Modified to recognize the architecture of the remote machine better.
4023 * This appears to be the matrix of which protocol is used by which
4025 Protocol WfWg Win95 WinNT OS/2
4026 PC NETWORK PROGRAM 1.0 1 1 1 1
4028 MICROSOFT NETWORKS 3.0 2 2
4030 MICROSOFT NETWORKS 1.03 3
4033 Windows for Workgroups 3.1a 5 5 5
4038 * tim@fsg.com 09/29/95
4041 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4042 #define ARCH_WIN95 0x2
4043 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4044 #define ARCH_WINNT 0x8
4045 #define ARCH_SAMBA 0x10
4047 #define ARCH_ALL 0x1F
4049 /* List of supported protocols, most desired first */
4053 int (*proto_reply_fn)(char *);
4055 } supported_protocols[] = {
4056 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4057 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4058 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4059 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4060 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4061 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4062 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4063 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4064 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4069 /****************************************************************************
4071 ****************************************************************************/
4072 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4074 int outsize = set_message(outbuf,1,0,True);
4079 int bcc = SVAL(smb_buf(inbuf),-2);
4080 int arch = ARCH_ALL;
4082 p = smb_buf(inbuf)+1;
4083 while (p < (smb_buf(inbuf) + bcc))
4086 DEBUG(3,("Requested protocol [%s]\n",p));
4087 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4088 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4089 else if (strcsequal(p,"DOS LM1.2X002"))
4090 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4091 else if (strcsequal(p,"DOS LANMAN2.1"))
4092 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4093 else if (strcsequal(p,"NT LM 0.12"))
4094 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4095 else if (strcsequal(p,"LANMAN2.1"))
4096 arch &= ( ARCH_WINNT | ARCH_OS2 );
4097 else if (strcsequal(p,"LM1.2X002"))
4098 arch &= ( ARCH_WINNT | ARCH_OS2 );
4099 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4101 else if (strcsequal(p,"XENIX CORE"))
4102 arch &= ( ARCH_WINNT | ARCH_OS2 );
4103 else if (strcsequal(p,"Samba")) {
4113 set_remote_arch(RA_SAMBA);
4116 set_remote_arch(RA_WFWG);
4119 set_remote_arch(RA_WIN95);
4122 set_remote_arch(RA_WINNT);
4125 set_remote_arch(RA_OS2);
4128 set_remote_arch(RA_UNKNOWN);
4132 /* possibly reload - change of architecture */
4133 reload_services(True);
4135 /* a special case to stop password server loops */
4136 if (Index == 1 && strequal(remote_machine,myhostname) &&
4137 (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4138 exit_server("Password server loop!");
4140 /* Check for protocols, most desirable first */
4141 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4143 p = smb_buf(inbuf)+1;
4145 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4146 while (p < (smb_buf(inbuf) + bcc))
4148 if (strequal(p,supported_protocols[protocol].proto_name))
4157 SSVAL(outbuf,smb_vwv0,choice);
4159 extern fstring remote_proto;
4160 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4161 reload_services(True);
4162 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4163 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4166 DEBUG(0,("No protocol supported !\n"));
4168 SSVAL(outbuf,smb_vwv0,choice);
4170 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4176 /****************************************************************************
4177 close all open files for a connection
4178 ****************************************************************************/
4179 static void close_open_files(int cnum)
4182 for (i=0;i<MAX_OPEN_FILES;i++)
4183 if( Files[i].cnum == cnum && Files[i].open) {
4184 close_file(i,False);
4190 /****************************************************************************
4192 ****************************************************************************/
4193 void close_cnum(int cnum, uint16 vuid)
4196 DirCacheFlush(SNUM(cnum));
4200 if (!OPEN_CNUM(cnum))
4202 DEBUG(0,("Can't close cnum %d\n",cnum));
4206 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4208 remote_machine,client_addr(Client),
4209 lp_servicename(SNUM(cnum))));
4211 yield_connection(cnum,
4212 lp_servicename(SNUM(cnum)),
4213 lp_max_connections(SNUM(cnum)));
4215 if (lp_status(SNUM(cnum)))
4216 yield_connection(cnum,"STATUS.",MAXSTATUS);
4218 close_open_files(cnum);
4219 dptr_closecnum(cnum);
4221 /* execute any "postexec = " line */
4222 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4225 strcpy(cmd,lp_postexec(SNUM(cnum)));
4226 standard_sub(cnum,cmd);
4227 smbrun(cmd,NULL,False);
4232 /* execute any "root postexec = " line */
4233 if (*lp_rootpostexec(SNUM(cnum)))
4236 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4237 standard_sub(cnum,cmd);
4238 smbrun(cmd,NULL,False);
4241 Connections[cnum].open = False;
4242 num_connections_open--;
4243 if (Connections[cnum].ngroups && Connections[cnum].groups)
4245 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4246 free(Connections[cnum].groups);
4247 free(Connections[cnum].igroups);
4248 Connections[cnum].groups = NULL;
4249 Connections[cnum].igroups = NULL;
4250 Connections[cnum].ngroups = 0;
4253 free_namearray(Connections[cnum].veto_list);
4254 free_namearray(Connections[cnum].hide_list);
4255 free_namearray(Connections[cnum].veto_oplock_list);
4257 string_set(&Connections[cnum].user,"");
4258 string_set(&Connections[cnum].dirpath,"");
4259 string_set(&Connections[cnum].connectpath,"");
4265 /*******************************************************************
4266 prepare to dump a core file - carefully!
4267 ********************************************************************/
4268 static BOOL dump_core(void)
4272 pstrcpy(dname,debugf);
4273 if ((p=strrchr(dname,'/'))) *p=0;
4274 strcat(dname,"/corefiles");
4276 sys_chown(dname,getuid(),getgid());
4278 if (chdir(dname)) return(False);
4281 #ifndef NO_GETRLIMIT
4285 getrlimit(RLIMIT_CORE, &rlp);
4286 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4287 setrlimit(RLIMIT_CORE, &rlp);
4288 getrlimit(RLIMIT_CORE, &rlp);
4289 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4295 DEBUG(0,("Dumping core in %s\n",dname));
4300 /****************************************************************************
4302 ****************************************************************************/
4303 void exit_server(char *reason)
4305 static int firsttime=1;
4308 if (!firsttime) exit(0);
4312 DEBUG(2,("Closing connections\n"));
4313 for (i=0;i<MAX_CONNECTIONS;i++)
4314 if (Connections[i].open)
4315 close_cnum(i,(uint16)-1);
4317 if (dcelogin_atmost_once)
4321 int oldlevel = DEBUGLEVEL;
4323 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4325 show_msg(last_inbuf);
4326 DEBUGLEVEL = oldlevel;
4327 DEBUG(0,("===============================================================\n"));
4329 if (dump_core()) return;
4335 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4339 /****************************************************************************
4340 do some standard substitutions in a string
4341 ****************************************************************************/
4342 void standard_sub(int cnum,char *str)
4344 if (VALID_CNUM(cnum)) {
4347 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4349 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4350 string_sub(p,"%H",home);
4354 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4355 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4356 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4357 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4359 * Patch from jkf@soton.ac.uk
4360 * Left the %N (NIS server name) in standard_sub_basic as it
4361 * is a feature for logon servers, hence uses the username.
4362 * The %p (NIS server path) code is here as it is used
4363 * instead of the default "path =" string in [homes] and so
4364 * needs the service name, not the username.
4366 case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4367 case '\0' : p++; break; /* don't run off the end of the string */
4368 default : p+=2; break;
4372 standard_sub_basic(str);
4376 These flags determine some of the permissions required to do an operation
4378 Note that I don't set NEED_WRITE on some write operations because they
4379 are used by some brain-dead clients when printing, and I don't want to
4380 force write permissions on print services.
4382 #define AS_USER (1<<0)
4383 #define NEED_WRITE (1<<1)
4384 #define TIME_INIT (1<<2)
4385 #define CAN_IPC (1<<3)
4386 #define AS_GUEST (1<<5)
4387 #define QUEUE_IN_OPLOCK (1<<6)
4390 define a list of possible SMB messages and their corresponding
4391 functions. Any message that has a NULL function is unimplemented -
4392 please feel free to contribute implementations!
4394 struct smb_message_struct
4398 int (*fn)(char *, char *, int, int);
4408 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4409 {SMBtcon,"SMBtcon",reply_tcon,0},
4410 {SMBtdis,"SMBtdis",reply_tdis,0},
4411 {SMBexit,"SMBexit",reply_exit,0},
4412 {SMBioctl,"SMBioctl",reply_ioctl,0},
4413 {SMBecho,"SMBecho",reply_echo,0},
4414 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4415 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4416 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4417 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4418 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4419 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4420 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4421 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4423 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4424 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4425 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4427 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4428 {SMBread,"SMBread",reply_read,AS_USER},
4429 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4430 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4431 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4432 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4433 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4434 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4436 /* this is a Pathworks specific call, allowing the
4437 changing of the root path */
4438 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4440 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4441 {SMBflush,"SMBflush",reply_flush,AS_USER},
4442 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4443 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4444 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4445 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4446 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4447 {SMBlock,"SMBlock",reply_lock,AS_USER},
4448 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4450 /* CORE+ PROTOCOL FOLLOWS */
4452 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4453 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4454 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4455 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4456 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4458 /* LANMAN1.0 PROTOCOL FOLLOWS */
4460 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4461 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4462 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4463 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4464 {SMBwritec,"SMBwritec",NULL,AS_USER},
4465 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4466 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4467 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4468 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4469 {SMBioctls,"SMBioctls",NULL,AS_USER},
4470 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4471 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4473 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4474 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4475 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4476 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4478 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4479 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4480 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4482 /* LANMAN2.0 PROTOCOL FOLLOWS */
4483 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4484 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4485 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4486 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4488 /* messaging routines */
4489 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4490 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4491 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4492 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4494 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4496 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4497 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4498 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4499 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4502 /****************************************************************************
4503 return a string containing the function name of a SMB command
4504 ****************************************************************************/
4505 char *smb_fn_name(int type)
4507 static char *unknown_name = "SMBunknown";
4508 static int num_smb_messages =
4509 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4512 for (match=0;match<num_smb_messages;match++)
4513 if (smb_messages[match].code == type)
4516 if (match == num_smb_messages)
4517 return(unknown_name);
4519 return(smb_messages[match].name);
4523 /****************************************************************************
4524 do a switch on the message type, and return the response size
4525 ****************************************************************************/
4526 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4530 static int num_smb_messages =
4531 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4535 struct timeval msg_start_time;
4536 struct timeval msg_end_time;
4537 static unsigned long total_time = 0;
4539 GetTimeOfDay(&msg_start_time);
4546 last_message = type;
4548 /* make sure this is an SMB packet */
4549 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4551 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4555 for (match=0;match<num_smb_messages;match++)
4556 if (smb_messages[match].code == type)
4559 if (match == num_smb_messages)
4561 DEBUG(0,("Unknown message type %d!\n",type));
4562 outsize = reply_unknown(inbuf,outbuf);
4566 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4568 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4571 * Queue this message as we are the process of an oplock break.
4574 DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4577 push_smb_message( inbuf, size);
4581 if (smb_messages[match].fn)
4583 int cnum = SVAL(inbuf,smb_tid);
4584 int flags = smb_messages[match].flags;
4585 /* In share mode security we must ignore the vuid. */
4586 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4587 /* Ensure this value is replaced in the incoming packet. */
4588 SSVAL(inbuf,smb_uid,session_tag);
4590 /* does this protocol need to be run as root? */
4591 if (!(flags & AS_USER))
4594 /* does this protocol need to be run as the connected user? */
4595 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4596 if (flags & AS_GUEST)
4599 return(ERROR(ERRSRV,ERRinvnid));
4601 /* this code is to work around a bug is MS client 3 without
4602 introducing a security hole - it needs to be able to do
4603 print queue checks as guest if it isn't logged in properly */
4604 if (flags & AS_USER)
4607 /* does it need write permission? */
4608 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4609 return(ERROR(ERRSRV,ERRaccess));
4611 /* ipc services are limited */
4612 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4613 return(ERROR(ERRSRV,ERRaccess));
4615 /* load service specific parameters */
4616 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4617 return(ERROR(ERRSRV,ERRaccess));
4619 /* does this protocol need to be run as guest? */
4620 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4621 return(ERROR(ERRSRV,ERRaccess));
4625 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4629 outsize = reply_unknown(inbuf,outbuf);
4634 GetTimeOfDay(&msg_end_time);
4635 if (!(smb_messages[match].flags & TIME_INIT))
4637 smb_messages[match].time = 0;
4638 smb_messages[match].flags |= TIME_INIT;
4641 unsigned long this_time =
4642 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4643 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4644 smb_messages[match].time += this_time;
4645 total_time += this_time;
4647 DEBUG(2,("TIME %s %d usecs %g pct\n",
4648 smb_fn_name(type),smb_messages[match].time,
4649 (100.0*smb_messages[match].time) / total_time));
4656 /****************************************************************************
4657 construct a chained reply and add it to the already made reply
4658 **************************************************************************/
4659 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4661 static char *orig_inbuf;
4662 static char *orig_outbuf;
4663 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4664 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4665 char *inbuf2, *outbuf2;
4667 char inbuf_saved[smb_wct];
4668 char outbuf_saved[smb_wct];
4669 extern int chain_size;
4670 int wct = CVAL(outbuf,smb_wct);
4671 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4673 /* maybe its not chained */
4674 if (smb_com2 == 0xFF) {
4675 CVAL(outbuf,smb_vwv0) = 0xFF;
4679 if (chain_size == 0) {
4680 /* this is the first part of the chain */
4682 orig_outbuf = outbuf;
4685 /* we need to tell the client where the next part of the reply will be */
4686 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4687 CVAL(outbuf,smb_vwv0) = smb_com2;
4689 /* remember how much the caller added to the chain, only counting stuff
4690 after the parameter words */
4691 chain_size += outsize - smb_wct;
4693 /* work out pointers into the original packets. The
4694 headers on these need to be filled in */
4695 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4696 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4698 /* remember the original command type */
4699 smb_com1 = CVAL(orig_inbuf,smb_com);
4701 /* save the data which will be overwritten by the new headers */
4702 memcpy(inbuf_saved,inbuf2,smb_wct);
4703 memcpy(outbuf_saved,outbuf2,smb_wct);
4705 /* give the new packet the same header as the last part of the SMB */
4706 memmove(inbuf2,inbuf,smb_wct);
4708 /* create the in buffer */
4709 CVAL(inbuf2,smb_com) = smb_com2;
4711 /* create the out buffer */
4712 bzero(outbuf2,smb_size);
4713 set_message(outbuf2,0,0,True);
4714 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4716 memcpy(outbuf2+4,inbuf2+4,4);
4717 CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4718 CVAL(outbuf2,smb_reh) = 0;
4719 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4721 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4722 SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4723 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4724 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4725 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4726 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4728 DEBUG(3,("Chained message\n"));
4731 /* process the request */
4732 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4733 bufsize-chain_size);
4735 /* copy the new reply and request headers over the old ones, but
4736 preserve the smb_com field */
4737 memmove(orig_outbuf,outbuf2,smb_wct);
4738 CVAL(orig_outbuf,smb_com) = smb_com1;
4740 /* restore the saved data, being careful not to overwrite any
4741 data from the reply header */
4742 memcpy(inbuf2,inbuf_saved,smb_wct);
4744 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4745 if (ofs < 0) ofs = 0;
4746 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4754 /****************************************************************************
4755 construct a reply to the incoming packet
4756 ****************************************************************************/
4757 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4759 int type = CVAL(inbuf,smb_com);
4761 int msg_type = CVAL(inbuf,0);
4762 extern int chain_size;
4764 smb_last_time = time(NULL);
4770 bzero(outbuf,smb_size);
4773 return(reply_special(inbuf,outbuf));
4775 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4776 set_message(outbuf,0,0,True);
4778 memcpy(outbuf+4,inbuf+4,4);
4779 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4780 CVAL(outbuf,smb_reh) = 0;
4781 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4783 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4784 SSVAL(outbuf,smb_err,SMB_SUCCESS);
4785 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4786 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4787 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4788 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4790 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4792 outsize += chain_size;
4795 smb_setlen(outbuf,outsize - 4);
4799 /****************************************************************************
4800 process commands from the client
4801 ****************************************************************************/
4802 static void process(void)
4806 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4807 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4808 if ((InBuffer == NULL) || (OutBuffer == NULL))
4811 InBuffer += SMB_ALIGNMENT;
4812 OutBuffer += SMB_ALIGNMENT;
4815 DEBUG(3,("priming nmbd\n"));
4818 ip = *interpret_addr2("localhost");
4819 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4821 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4825 /* re-initialise the timezone */
4830 int deadtime = lp_deadtime()*60;
4832 int last_keepalive=0;
4833 int service_load_counter = 0;
4834 BOOL got_smb = False;
4837 deadtime = DEFAULT_SMBD_TIMEOUT;
4839 #if USE_READ_PREDICTION
4840 if (lp_readprediction())
4841 do_read_prediction();
4846 for (counter=SMBD_SELECT_LOOP;
4847 !receive_message_or_smb(Client,oplock_sock,
4848 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4849 counter += SMBD_SELECT_LOOP)
4853 BOOL allidle = True;
4854 extern int keepalive;
4856 if (counter > 365 * 3600) /* big number of seconds. */
4859 service_load_counter = 0;
4862 if (smb_read_error == READ_EOF)
4864 DEBUG(3,("end of file from client\n"));
4868 if (smb_read_error == READ_ERROR)
4870 DEBUG(3,("receive_smb error (%s) exiting\n",
4877 /* become root again if waiting */
4880 /* check for smb.conf reload */
4881 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4883 service_load_counter = counter;
4885 /* reload services, if files have changed. */
4886 reload_services(True);
4889 /* automatic timeout if all connections are closed */
4890 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4892 DEBUG(2,("%s Closing idle connection\n",timestring()));
4896 if (keepalive && (counter-last_keepalive)>keepalive)
4898 struct cli_state *cli = server_client();
4899 if (!send_keepalive(Client)) {
4900 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4903 /* also send a keepalive to the password server if its still
4905 if (cli && cli->initialised)
4906 send_keepalive(cli->fd);
4907 last_keepalive = counter;
4910 /* check for connection timeouts */
4911 for (i=0;i<MAX_CONNECTIONS;i++)
4912 if (Connections[i].open)
4914 /* close dirptrs on connections that are idle */
4915 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4918 if (Connections[i].num_files_open > 0 ||
4919 (t-Connections[i].lastused)<deadtime)
4923 if (allidle && num_connections_open>0)
4925 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4931 process_smb(InBuffer, OutBuffer);
4933 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4938 /****************************************************************************
4939 initialise connect, service and file structs
4940 ****************************************************************************/
4941 static void init_structs(void )
4944 get_myname(myhostname,NULL);
4947 * Set the machine NETBIOS name if not already
4948 * set from the config file.
4951 if (!*global_myname)
4954 fstrcpy( global_myname, myhostname );
4955 p = strchr( global_myname, '.' );
4959 strupper( global_myname );
4961 for (i=0;i<MAX_CONNECTIONS;i++)
4963 Connections[i].open = False;
4964 Connections[i].num_files_open=0;
4965 Connections[i].lastused=0;
4966 Connections[i].used=False;
4967 string_init(&Connections[i].user,"");
4968 string_init(&Connections[i].dirpath,"");
4969 string_init(&Connections[i].connectpath,"");
4970 string_init(&Connections[i].origpath,"");
4973 for (i=0;i<MAX_OPEN_FILES;i++)
4975 Files[i].open = False;
4976 string_init(&Files[i].name,"");
4979 for (i=0;i<MAX_OPEN_FILES;i++)
4981 file_fd_struct *fd_ptr = &FileFd[i];
4982 fd_ptr->ref_count = 0;
4983 fd_ptr->dev = (int32)-1;
4984 fd_ptr->inode = (int32)-1;
4986 fd_ptr->fd_readonly = -1;
4987 fd_ptr->fd_writeonly = -1;
4988 fd_ptr->real_open_flags = -1;
4992 init_rpc_pipe_hnd();
4994 /* for LSA handles */
4995 init_lsa_policy_hnd();
5000 /****************************************************************************
5001 usage on the program
5002 ****************************************************************************/
5003 static void usage(char *pname)
5005 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5007 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5008 printf("Version %s\n",VERSION);
5009 printf("\t-D become a daemon\n");
5010 printf("\t-p port listen on the specified port\n");
5011 printf("\t-d debuglevel set the debuglevel\n");
5012 printf("\t-l log basename. Basename for log/debug files\n");
5013 printf("\t-s services file. Filename of services file\n");
5014 printf("\t-P passive only\n");
5015 printf("\t-a overwrite log file, don't append\n");
5020 /****************************************************************************
5022 ****************************************************************************/
5023 int main(int argc,char *argv[])
5025 extern BOOL append_log;
5026 /* shall I run as a daemon */
5027 BOOL is_daemon = False;
5028 int port = SMB_PORT;
5030 extern char *optarg;
5032 #ifdef NEED_AUTH_PARAMETERS
5033 set_auth_parameters(argc,argv);
5044 strcpy(debugf,SMBLOGFILE);
5046 strcpy(remote_machine, "smb");
5048 setup_logging(argv[0],False);
5050 charset_initialise();
5052 /* make absolutely sure we run as root - to handle cases where people
5053 are crazy enough to have it setuid */
5063 fault_setup((void (*)(void *))exit_server);
5064 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5066 /* we want total control over the permissions on created files,
5067 so set our umask to 0 */
5074 /* this is for people who can't start the program correctly */
5075 while (argc > 1 && (*argv[1] != '-'))
5081 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5085 strcpy(user_socket_options,optarg);
5088 strcpy(scope,optarg);
5092 extern BOOL passive;
5097 strcpy(servicesf,optarg);
5100 strcpy(debugf,optarg);
5104 extern BOOL append_log;
5105 append_log = !append_log;
5115 DEBUGLEVEL = atoi(optarg);
5118 port = atoi(optarg);
5131 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5132 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5134 #ifndef NO_GETRLIMIT
5135 #ifdef RLIMIT_NOFILE
5138 getrlimit(RLIMIT_NOFILE, &rlp);
5140 * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5141 * extra fd we need to read directories, as well as the log files
5142 * and standard handles etc.
5144 rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5145 setrlimit(RLIMIT_NOFILE, &rlp);
5146 getrlimit(RLIMIT_NOFILE, &rlp);
5147 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5153 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5154 getuid(),getgid(),geteuid(),getegid()));
5156 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5158 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5164 if (!reload_services(False))
5167 codepage_initialise(lp_client_code_page());
5169 strcpy(global_myworkgroup, lp_workgroup());
5171 #ifndef NO_SIGNAL_TEST
5172 signal(SIGHUP,SIGNAL_CAST sig_hup);
5175 /* Setup the signals that allow the debug log level
5176 to by dynamically changed. */
5178 /* If we are using the malloc debug code we can't use
5179 SIGUSR1 and SIGUSR2 to do debug level changes. */
5182 #if defined(SIGUSR1)
5183 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5184 #endif /* SIGUSR1 */
5186 #if defined(SIGUSR2)
5187 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5188 #endif /* SIGUSR2 */
5189 #endif /* MEM_MAN */
5191 DEBUG(3,("%s loaded services\n",timestring()));
5193 if (!is_daemon && !is_a_socket(0))
5195 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5201 DEBUG(3,("%s becoming a daemon\n",timestring()));
5205 if (!directory_exist(lp_lockdir(), NULL)) {
5206 mkdir(lp_lockdir(), 0755);
5210 pidfile_create("smbd");
5213 if (!open_sockets(is_daemon,port))
5216 if (!locking_init(0))
5219 /* possibly reload the services file. */
5220 reload_services(True);
5222 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5226 if (sys_chroot(lp_rootdir()) == 0)
5227 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5230 /* Setup the oplock IPC socket. */
5231 if(!open_oplock_ipc())
5237 exit_server("normal exit");