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?\n"));
1092 /****************************************************************************
1093 fd support routines - attempt to re-open an already open fd as O_RDWR.
1094 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1095 ****************************************************************************/
1096 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1098 int fd = sys_open( fname, O_RDWR, mode);
1103 if(fd_ptr->real_open_flags == O_RDONLY)
1104 fd_ptr->fd_readonly = fd_ptr->fd;
1105 if(fd_ptr->real_open_flags == O_WRONLY)
1106 fd_ptr->fd_writeonly = fd_ptr->fd;
1109 fd_ptr->real_open_flags = O_RDWR;
1112 /****************************************************************************
1113 fd support routines - attempt to close the file referenced by this fd.
1114 Decrements the ref_count and returns it.
1115 ****************************************************************************/
1116 static int fd_attempt_close(file_fd_struct *fd_ptr)
1118 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1119 fd_ptr - &FileFd[0],
1120 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1121 fd_ptr->real_open_flags,
1122 fd_ptr->ref_count));
1123 if(fd_ptr->ref_count > 0) {
1124 fd_ptr->ref_count--;
1125 if(fd_ptr->ref_count == 0) {
1126 if(fd_ptr->fd != -1)
1128 if(fd_ptr->fd_readonly != -1)
1129 close(fd_ptr->fd_readonly);
1130 if(fd_ptr->fd_writeonly != -1)
1131 close(fd_ptr->fd_writeonly);
1133 fd_ptr->fd_readonly = -1;
1134 fd_ptr->fd_writeonly = -1;
1135 fd_ptr->real_open_flags = -1;
1136 fd_ptr->dev = (uint32)-1;
1137 fd_ptr->inode = (uint32)-1;
1140 return fd_ptr->ref_count;
1143 /****************************************************************************
1145 ****************************************************************************/
1146 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1148 extern struct current_user current_user;
1150 struct stat statbuf;
1151 file_fd_struct *fd_ptr;
1152 files_struct *fsp = &Files[fnum];
1153 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1157 fsp->granted_oplock = False;
1160 pstrcpy(fname,fname1);
1162 /* check permissions */
1165 * This code was changed after seeing a client open request
1166 * containing the open mode of (DENY_WRITE/read-only) with
1167 * the 'create if not exist' bit set. The previous code
1168 * would fail to open the file read only on a read-only share
1169 * as it was checking the flags parameter directly against O_RDONLY,
1170 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1174 if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1175 /* It's a read-only share - fail if we wanted to write. */
1176 if(accmode != O_RDONLY) {
1177 DEBUG(3,("Permission denied opening %s\n",fname));
1178 check_for_pipe(fname);
1181 else if(flags & O_CREAT) {
1182 /* We don't want to write - but we must make sure that O_CREAT
1183 doesn't create the file if we have write access into the
1190 /* this handles a bug in Win95 - it doesn't say to create the file when it
1192 if (Connections[cnum].printer)
1196 if (flags == O_WRONLY)
1197 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1201 * Ensure we have a valid struct stat so we can search the
1205 if(stat(fname, &statbuf) < 0) {
1206 if(errno != ENOENT) {
1207 DEBUG(3,("Error doing stat on file %s (%s)\n",
1208 fname,strerror(errno)));
1210 check_for_pipe(fname);
1220 * Check to see if we have this file already
1221 * open. If we do, just use the already open fd and increment the
1222 * reference count (fd_get_already_open increments the ref_count).
1224 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1226 /* File was already open. */
1227 if((flags & O_CREAT) && (flags & O_EXCL)) {
1228 fd_ptr->ref_count--;
1234 * If not opened O_RDWR try
1235 * and do that here - a chmod may have been done
1236 * between the last open and now.
1238 if(fd_ptr->real_open_flags != O_RDWR)
1239 fd_attempt_reopen(fname, mode, fd_ptr);
1242 * Ensure that if we wanted write access
1243 * it has been opened for write, and if we wanted read it
1244 * was open for read.
1246 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1247 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1248 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1249 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1250 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1251 check_for_pipe(fname);
1252 fd_ptr->ref_count--;
1258 /* We need to allocate a new file_fd_struct (this increments the
1260 if((fd_ptr = fd_get_new()) == 0)
1263 * Whatever the requested flags, attempt read/write access,
1264 * as we don't know what flags future file opens may require.
1265 * If this fails, try again with the required flags.
1266 * Even if we open read/write when only read access was
1267 * requested the setting of the can_write flag in
1268 * the file_struct will protect us from errant
1269 * write requests. We never need to worry about O_APPEND
1270 * as this is not set anywhere in Samba.
1272 fd_ptr->real_open_flags = O_RDWR;
1273 /* Set the flags as needed without the read/write modes. */
1274 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1275 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1277 * On some systems opening a file for R/W access on a read only
1278 * filesystems sets errno to EROFS.
1281 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1282 #else /* No EROFS */
1283 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1285 if(flags & O_WRONLY) {
1286 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1287 fd_ptr->real_open_flags = O_WRONLY;
1289 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1290 fd_ptr->real_open_flags = O_RDONLY;
1295 if ((fd_ptr->fd >=0) &&
1296 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1300 pstrcpy(dname,fname);
1301 p = strrchr(dname,'/');
1303 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1304 lp_minprintspace(SNUM(cnum))) {
1305 fd_attempt_close(fd_ptr);
1307 if(fd_ptr->ref_count == 0)
1316 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1317 fname,strerror(errno),flags));
1318 /* Ensure the ref_count is decremented. */
1319 fd_attempt_close(fd_ptr);
1320 check_for_pipe(fname);
1324 if (fd_ptr->fd >= 0)
1328 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1329 /* Error - backout !! */
1330 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1331 fd_ptr->fd, fname,strerror(errno)));
1332 /* Ensure the ref_count is decremented. */
1333 fd_attempt_close(fd_ptr);
1338 /* Set the correct entries in fd_ptr. */
1339 fd_ptr->dev = (uint32)sbuf->st_dev;
1340 fd_ptr->inode = (uint32)sbuf->st_ino;
1342 fsp->fd_ptr = fd_ptr;
1343 Connections[cnum].num_files_open++;
1344 fsp->mode = sbuf->st_mode;
1345 GetTimeOfDay(&fsp->open_time);
1346 fsp->vuid = current_user.vuid;
1350 fsp->mmap_ptr = NULL;
1352 fsp->can_lock = True;
1353 fsp->can_read = ((flags & O_WRONLY)==0);
1354 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1355 fsp->share_mode = 0;
1356 fsp->print_file = Connections[cnum].printer;
1357 fsp->modified = False;
1358 fsp->granted_oplock = False;
1359 fsp->sent_oplock_break = False;
1361 string_set(&fsp->name,dos_to_unix(fname,False));
1362 fsp->wbmpx_ptr = NULL;
1365 * If the printer is marked as postscript output a leading
1366 * file identifier to ensure the file is treated as a raw
1368 * This has a similar effect as CtrlD=0 in WIN.INI file.
1369 * tim@fsg.com 09/06/94
1371 if (fsp->print_file && POSTSCRIPT(cnum) &&
1374 DEBUG(3,("Writing postscript line\n"));
1375 write_file(fnum,"%!\n",3);
1378 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1379 timestring(),Connections[cnum].user,fname,
1380 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1381 Connections[cnum].num_files_open,fnum));
1386 /* mmap it if read-only */
1387 if (!fsp->can_write)
1389 fsp->mmap_size = file_size(fname);
1390 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1391 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1393 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1395 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1396 fsp->mmap_ptr = NULL;
1402 /*******************************************************************
1404 ********************************************************************/
1405 void sync_file(int fnum)
1408 fsync(Files[fnum].fd_ptr->fd);
1412 /****************************************************************************
1413 run a file if it is a magic script
1414 ****************************************************************************/
1415 static void check_magic(int fnum,int cnum)
1417 if (!*lp_magicscript(SNUM(cnum)))
1420 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1424 if (!(p = strrchr(Files[fnum].name,'/')))
1425 p = Files[fnum].name;
1429 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1435 pstring magic_output;
1437 pstrcpy(fname,Files[fnum].name);
1439 if (*lp_magicoutput(SNUM(cnum)))
1440 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1442 sprintf(magic_output,"%s.out",fname);
1445 ret = smbrun(fname,magic_output,False);
1446 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1452 /****************************************************************************
1453 close a file - possibly invalidating the read prediction
1455 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1456 operation otherwise it came as the result of some other operation such as
1457 the closing of the connection. In the latter case printing and
1458 magic scripts are not run
1459 ****************************************************************************/
1460 void close_file(int fnum, BOOL normal_close)
1462 files_struct *fs_p = &Files[fnum];
1463 int cnum = fs_p->cnum;
1464 uint32 dev = fs_p->fd_ptr->dev;
1465 uint32 inode = fs_p->fd_ptr->inode;
1468 Files[fnum].reserved = False;
1470 #if USE_READ_PREDICTION
1471 invalidate_read_prediction(fs_p->fd_ptr->fd);
1475 Connections[cnum].num_files_open--;
1478 free((char *)fs_p->wbmpx_ptr);
1479 fs_p->wbmpx_ptr = NULL;
1485 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1486 fs_p->mmap_ptr = NULL;
1490 if (lp_share_modes(SNUM(cnum)))
1492 lock_share_entry( cnum, dev, inode, &token);
1493 del_share_mode(token, fnum);
1496 fd_attempt_close(fs_p->fd_ptr);
1498 if (lp_share_modes(SNUM(cnum)))
1499 unlock_share_entry( cnum, dev, inode, token);
1501 /* NT uses smbclose to start a print - weird */
1502 if (normal_close && fs_p->print_file)
1505 /* check for magic scripts */
1507 check_magic(fnum,cnum);
1509 if(fs_p->granted_oplock == True)
1510 global_oplocks_open--;
1512 fs_p->sent_oplock_break = False;
1514 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1515 timestring(),Connections[cnum].user,fs_p->name,
1516 Connections[cnum].num_files_open));
1519 string_free(&fs_p->name);
1522 /* we will catch bugs faster by zeroing this structure */
1523 memset(fs_p, 0, sizeof(*fs_p));
1526 enum {AFAIL,AREAD,AWRITE,AALL};
1528 /*******************************************************************
1529 reproduce the share mode access table
1530 ********************************************************************/
1531 static int access_table(int new_deny,int old_deny,int old_mode,
1532 int share_pid,char *fname)
1534 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1536 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1538 if (old_deny == new_deny && share_pid == pid)
1541 if (old_mode == 0) return(AREAD);
1543 /* the new smbpub.zip spec says that if the file extension is
1544 .com, .dll, .exe or .sym then allow the open. I will force
1545 it to read-only as this seems sensible although the spec is
1546 a little unclear on this. */
1547 if ((fname = strrchr(fname,'.'))) {
1548 if (strequal(fname,".com") ||
1549 strequal(fname,".dll") ||
1550 strequal(fname,".exe") ||
1551 strequal(fname,".sym"))
1561 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1562 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1563 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1566 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1567 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1568 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1571 if (old_deny==DENY_WRITE) return(AREAD);
1572 if (old_deny==DENY_READ) return(AWRITE);
1573 if (old_deny==DENY_NONE) return(AALL);
1579 /*******************************************************************
1580 check if the share mode on a file allows it to be deleted or unlinked
1581 return True if sharing doesn't prevent the operation
1582 ********************************************************************/
1583 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1587 share_mode_entry *old_shares = 0;
1588 int num_share_modes;
1594 if(!lp_share_modes(SNUM(cnum)))
1597 if (stat(fname,&sbuf) == -1) return(True);
1599 dev = (uint32)sbuf.st_dev;
1600 inode = (uint32)sbuf.st_ino;
1602 lock_share_entry(cnum, dev, inode, &token);
1603 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1606 * Check if the share modes will give us access.
1609 if(num_share_modes != 0)
1616 broke_oplock = False;
1617 for(i = 0; i < num_share_modes; i++)
1619 share_mode_entry *share_entry = &old_shares[i];
1622 * Break oplocks before checking share modes. See comment in
1623 * open_file_shared for details.
1624 * Check if someone has an oplock on this file. If so we must
1625 * break it before continuing.
1627 if(share_entry->op_type & BATCH_OPLOCK)
1631 * It appears that the NT redirector may have a bug, in that
1632 * it tries to do an SMBmv on a file that it has open with a
1633 * batch oplock, and then fails to respond to the oplock break
1634 * request. This only seems to occur when the client is doing an
1635 * SMBmv to the smbd it is using - thus we try and detect this
1636 * condition by checking if the file being moved is open and oplocked by
1637 * this smbd process, and then not sending the oplock break in this
1638 * special case. If the file was open with a deny mode that
1639 * prevents the move the SMBmv will fail anyway with a share
1640 * violation error. JRA.
1642 if(rename_op && (share_entry->pid == pid))
1644 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1645 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1647 * This next line is a test that allows the deny-mode
1648 * processing to be skipped. This seems to be needed as
1649 * NT insists on the rename succeeding (in Office 9x no less !).
1650 * This should be removed as soon as (a) MS fix the redirector
1651 * bug or (b) NT SMB support in Samba makes NT not issue the
1652 * call (as is my fervent hope). JRA.
1658 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1659 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1661 /* Oplock break.... */
1662 unlock_share_entry(cnum, dev, inode, token);
1663 if(request_oplock_break(share_entry, dev, inode) == False)
1665 free((char *)old_shares);
1666 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1667 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1670 lock_share_entry(cnum, dev, inode, &token);
1671 broke_oplock = True;
1676 /* someone else has a share lock on it, check to see
1678 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1685 free((char *)old_shares);
1686 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1688 } while(broke_oplock);
1691 /* XXXX exactly what share mode combinations should be allowed for
1692 deleting/renaming? */
1693 /* If we got here then either there were no share modes or
1694 all share modes were DENY_DOS and the pid == getpid() */
1699 unlock_share_entry(cnum, dev, inode, token);
1700 if(old_shares != NULL)
1701 free((char *)old_shares);
1705 /****************************************************************************
1707 Helper for open_file_shared.
1708 Truncate a file after checking locking; close file if locked.
1709 **************************************************************************/
1710 static void truncate_unless_locked(int fnum, int cnum, int token,
1713 if (Files[fnum].can_write){
1714 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1715 /* If share modes are in force for this connection we
1716 have the share entry locked. Unlock it before closing. */
1717 if (*share_locked && lp_share_modes(SNUM(cnum)))
1718 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1719 Files[fnum].fd_ptr->inode, token);
1720 close_file(fnum,False);
1721 /* Share mode no longer locked. */
1722 *share_locked = False;
1724 unix_ERR_class = ERRDOS;
1725 unix_ERR_code = ERRlock;
1728 ftruncate(Files[fnum].fd_ptr->fd,0);
1732 /****************************************************************************
1733 check if we can open a file with a share mode
1734 ****************************************************************************/
1735 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1736 BOOL fcbopen, int *flags)
1738 int old_open_mode = share->share_mode &0xF;
1739 int old_deny_mode = (share->share_mode >>4)&7;
1741 if (old_deny_mode > 4 || old_open_mode > 2)
1743 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1744 deny_mode,old_deny_mode,old_open_mode,fname));
1749 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1752 if ((access_allowed == AFAIL) ||
1753 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1754 (access_allowed == AREAD && *flags == O_WRONLY) ||
1755 (access_allowed == AWRITE && *flags == O_RDONLY))
1757 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1758 deny_mode,old_deny_mode,old_open_mode,
1759 share->pid,fname, fcbopen, *flags, access_allowed));
1763 if (access_allowed == AREAD)
1766 if (access_allowed == AWRITE)
1773 /****************************************************************************
1774 open a file with a share mode
1775 ****************************************************************************/
1776 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1777 int mode,int oplock_request, int *Access,int *action)
1779 files_struct *fs_p = &Files[fnum];
1782 int deny_mode = (share_mode>>4)&7;
1784 BOOL file_existed = file_exist(fname,&sbuf);
1785 BOOL share_locked = False;
1786 BOOL fcbopen = False;
1790 int num_share_modes = 0;
1795 /* this is for OS/2 EAs - try and say we don't support them */
1796 if (strstr(fname,".+,;=[]."))
1798 unix_ERR_class = ERRDOS;
1799 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1800 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1801 unix_ERR_code = ERRcannotopen;
1802 #else /* OS2_WPS_FIX */
1803 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1804 #endif /* OS2_WPS_FIX */
1809 if ((ofun & 0x3) == 0 && file_existed)
1817 if ((ofun & 0x3) == 2)
1820 /* note that we ignore the append flag as
1821 append does not mean the same thing under dos and unix */
1823 switch (share_mode&0xF)
1841 if (share_mode&(1<<14)) {
1846 if (flags != O_RDONLY && file_existed &&
1847 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1857 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1859 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1864 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1866 if (lp_share_modes(SNUM(cnum)))
1869 share_mode_entry *old_shares = 0;
1873 dev = (uint32)sbuf.st_dev;
1874 inode = (uint32)sbuf.st_ino;
1875 lock_share_entry(cnum, dev, inode, &token);
1876 share_locked = True;
1877 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1881 * Check if the share modes will give us access.
1884 if(share_locked && (num_share_modes != 0))
1891 broke_oplock = False;
1892 for(i = 0; i < num_share_modes; i++)
1894 share_mode_entry *share_entry = &old_shares[i];
1897 * By observation of NetBench, oplocks are broken *before* share
1898 * modes are checked. This allows a file to be closed by the client
1899 * if the share mode would deny access and the client has an oplock.
1900 * Check if someone has an oplock on this file. If so we must break
1901 * it before continuing.
1903 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1906 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1907 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1909 /* Oplock break.... */
1910 unlock_share_entry(cnum, dev, inode, token);
1911 if(request_oplock_break(share_entry, dev, inode) == False)
1913 free((char *)old_shares);
1914 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1915 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1917 unix_ERR_class = ERRDOS;
1918 unix_ERR_code = ERRbadshare;
1921 lock_share_entry(cnum, dev, inode, &token);
1922 broke_oplock = True;
1926 /* someone else has a share lock on it, check to see
1928 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1930 free((char *)old_shares);
1931 unlock_share_entry(cnum, dev, inode, token);
1933 unix_ERR_class = ERRDOS;
1934 unix_ERR_code = ERRbadshare;
1942 free((char *)old_shares);
1943 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1945 } while(broke_oplock);
1949 free((char *)old_shares);
1952 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1953 flags,flags2,mode));
1955 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1956 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1959 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1966 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1968 /* We created the file - thus we must now lock the share entry before creating it. */
1969 dev = fs_p->fd_ptr->dev;
1970 inode = fs_p->fd_ptr->inode;
1971 lock_share_entry(cnum, dev, inode, &token);
1972 share_locked = True;
1988 fs_p->share_mode = (deny_mode<<4) | open_mode;
1991 (*Access) = open_mode;
1995 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1996 if (!file_existed) *action = 2;
1997 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1999 /* We must create the share mode entry before truncate as
2000 truncate can fail due to locking and have to close the
2001 file (which expects the share_mode_entry to be there).
2003 if (lp_share_modes(SNUM(cnum)))
2006 /* JRA. Currently this only services Exlcusive and batch
2007 oplocks (no other opens on this file). This needs to
2008 be extended to level II oplocks (multiple reader
2011 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
2012 !IS_VETO_OPLOCK_PATH(cnum,fname))
2014 fs_p->granted_oplock = True;
2015 fs_p->sent_oplock_break = False;
2016 global_oplocks_open++;
2019 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2020 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2028 set_share_mode(token, fnum, port, oplock_request);
2031 if ((flags2&O_TRUNC) && file_existed)
2032 truncate_unless_locked(fnum,cnum,token,&share_locked);
2035 if (share_locked && lp_share_modes(SNUM(cnum)))
2036 unlock_share_entry( cnum, dev, inode, token);
2039 /****************************************************************************
2040 seek a file. Try to avoid the seek if possible
2041 ****************************************************************************/
2042 int seek_file(int fnum,uint32 pos)
2045 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2048 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2050 return(Files[fnum].pos);
2053 /****************************************************************************
2055 ****************************************************************************/
2056 int read_file(int fnum,char *data,uint32 pos,int n)
2060 #if USE_READ_PREDICTION
2061 if (!Files[fnum].can_write)
2063 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2072 if (Files[fnum].mmap_ptr)
2074 int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2078 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2090 if (seek_file(fnum,pos) != pos)
2092 DEBUG(3,("Failed to seek to %d\n",pos));
2097 readret = read(Files[fnum].fd_ptr->fd,data,n);
2098 if (readret > 0) ret += readret;
2105 /****************************************************************************
2107 ****************************************************************************/
2108 int write_file(int fnum,char *data,int n)
2110 if (!Files[fnum].can_write) {
2115 if (!Files[fnum].modified) {
2117 Files[fnum].modified = True;
2118 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2119 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2120 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2121 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2126 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2130 /****************************************************************************
2131 load parameters specific to a connection/service
2132 ****************************************************************************/
2133 BOOL become_service(int cnum,BOOL do_chdir)
2135 extern char magic_char;
2136 static int last_cnum = -1;
2139 if (!OPEN_CNUM(cnum))
2145 Connections[cnum].lastused = smb_last_time;
2150 ChDir(Connections[cnum].connectpath) != 0 &&
2151 ChDir(Connections[cnum].origpath) != 0)
2153 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2154 Connections[cnum].connectpath,cnum));
2158 if (cnum == last_cnum)
2163 case_default = lp_defaultcase(snum);
2164 case_preserve = lp_preservecase(snum);
2165 short_case_preserve = lp_shortpreservecase(snum);
2166 case_mangle = lp_casemangle(snum);
2167 case_sensitive = lp_casesensitive(snum);
2168 magic_char = lp_magicchar(snum);
2169 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2174 /****************************************************************************
2175 find a service entry
2176 ****************************************************************************/
2177 int find_service(char *service)
2181 string_sub(service,"\\","/");
2183 iService = lp_servicenumber(service);
2185 /* now handle the special case of a home directory */
2188 char *phome_dir = get_home_dir(service);
2189 DEBUG(3,("checking for home directory %s gave %s\n",service,
2190 phome_dir?phome_dir:"(NULL)"));
2194 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2196 lp_add_home(service,iHomeService,phome_dir);
2197 iService = lp_servicenumber(service);
2202 /* If we still don't have a service, attempt to add it as a printer. */
2205 int iPrinterService;
2207 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2211 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2213 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2215 DEBUG(3,("%s is a valid printer name\n", service));
2216 DEBUG(3,("adding %s as a printer service\n", service));
2217 lp_add_printer(service,iPrinterService);
2218 iService = lp_servicenumber(service);
2220 DEBUG(0,("failed to add %s as a printer service!\n", service));
2223 DEBUG(3,("%s is not a valid printer name\n", service));
2227 /* just possibly it's a default service? */
2230 char *pdefservice = lp_defaultservice();
2231 if (pdefservice && *pdefservice && !strequal(pdefservice,service)) {
2233 * We need to do a local copy here as lp_defaultservice()
2234 * returns one of the rotating lp_string buffers that
2235 * could get overwritten by the recursive find_service() call
2236 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2239 pstrcpy(defservice, pdefservice);
2240 iService = find_service(defservice);
2241 if (iService >= 0) {
2242 string_sub(service,"_","/");
2243 iService = lp_add_service(service,iService);
2249 if (!VALID_SNUM(iService))
2251 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2256 DEBUG(3,("find_service() failed to find service %s\n", service));
2262 /****************************************************************************
2263 create an error packet from a cached error.
2264 ****************************************************************************/
2265 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2267 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2269 int32 eclass = wbmpx->wr_errclass;
2270 int32 err = wbmpx->wr_error;
2272 /* We can now delete the auxiliary struct */
2273 free((char *)wbmpx);
2274 Files[fnum].wbmpx_ptr = NULL;
2275 return error_packet(inbuf,outbuf,eclass,err,line);
2284 } unix_smb_errmap[] =
2286 {EPERM,ERRDOS,ERRnoaccess},
2287 {EACCES,ERRDOS,ERRnoaccess},
2288 {ENOENT,ERRDOS,ERRbadfile},
2289 {ENOTDIR,ERRDOS,ERRbadpath},
2290 {EIO,ERRHRD,ERRgeneral},
2291 {EBADF,ERRSRV,ERRsrverror},
2292 {EINVAL,ERRSRV,ERRsrverror},
2293 {EEXIST,ERRDOS,ERRfilexists},
2294 {ENFILE,ERRDOS,ERRnofids},
2295 {EMFILE,ERRDOS,ERRnofids},
2296 {ENOSPC,ERRHRD,ERRdiskfull},
2298 {EDQUOT,ERRHRD,ERRdiskfull},
2301 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2304 {EXDEV,ERRDOS,ERRdiffdevice},
2306 {EROFS,ERRHRD,ERRnowrite},
2310 /****************************************************************************
2311 create an error packet from errno
2312 ****************************************************************************/
2313 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2315 int eclass=def_class;
2319 if (unix_ERR_class != SMB_SUCCESS)
2321 eclass = unix_ERR_class;
2322 ecode = unix_ERR_code;
2323 unix_ERR_class = SMB_SUCCESS;
2328 while (unix_smb_errmap[i].smbclass != 0)
2330 if (unix_smb_errmap[i].unixerror == errno)
2332 eclass = unix_smb_errmap[i].smbclass;
2333 ecode = unix_smb_errmap[i].smbcode;
2340 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2344 /****************************************************************************
2345 create an error packet. Normally called using the ERROR() macro
2346 ****************************************************************************/
2347 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2349 int outsize = set_message(outbuf,0,0,True);
2350 int cmd = CVAL(inbuf,smb_com);
2351 int flgs2 = SVAL(outbuf,smb_flg2);
2353 if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2355 SIVAL(outbuf,smb_rcls,error_code);
2357 DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2358 timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2362 CVAL(outbuf,smb_rcls) = error_class;
2363 SSVAL(outbuf,smb_err,error_code);
2364 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2367 (int)CVAL(inbuf,smb_com),
2368 smb_fn_name(CVAL(inbuf,smb_com)),
2375 DEBUG(3,("error string = %s\n",strerror(errno)));
2381 #ifndef SIGCLD_IGNORE
2382 /****************************************************************************
2383 this prevents zombie child processes
2384 ****************************************************************************/
2385 static int sig_cld(void)
2387 static int depth = 0;
2390 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2396 BlockSignals(True,SIGCLD);
2397 DEBUG(5,("got SIGCLD\n"));
2400 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2404 /* Stevens, Adv. Unix Prog. says that on system V you must call
2405 wait before reinstalling the signal handler, because the kernel
2406 calls the handler from within the signal-call when there is a
2407 child that has exited. This would lead to an infinite recursion
2408 if done vice versa. */
2410 #ifndef DONT_REINSTALL_SIG
2411 #ifdef SIGCLD_IGNORE
2412 signal(SIGCLD, SIG_IGN);
2414 signal(SIGCLD, SIGNAL_CAST sig_cld);
2419 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2422 BlockSignals(False,SIGCLD);
2427 /****************************************************************************
2428 this is called when the client exits abruptly
2429 **************************************************************************/
2430 static int sig_pipe(void)
2432 struct cli_state *cli;
2433 BlockSignals(True,SIGPIPE);
2435 if ((cli = server_client()) && cli->initialised) {
2436 DEBUG(3,("lost connection to password server\n"));
2438 #ifndef DONT_REINSTALL_SIG
2439 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2441 BlockSignals(False,SIGPIPE);
2445 exit_server("Got sigpipe\n");
2449 /****************************************************************************
2450 open the socket communication
2451 ****************************************************************************/
2452 static BOOL open_sockets(BOOL is_daemon,int port)
2458 int num_interfaces = iface_count();
2459 int fd_listenset[FD_SETSIZE];
2465 #ifdef SIGCLD_IGNORE
2466 signal(SIGCLD, SIG_IGN);
2468 signal(SIGCLD, SIGNAL_CAST sig_cld);
2474 FD_ZERO(&listen_set);
2476 if(lp_interfaces() && lp_bind_interfaces_only())
2478 /* We have been given an interfaces line, and been
2479 told to only bind to those interfaces. Create a
2480 socket per interface and bind to only these.
2483 if(num_interfaces > FD_SETSIZE)
2485 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2486 max can be %d\n", num_interfaces, FD_SETSIZE));
2490 /* Now open a listen socket for each of the interfaces. */
2491 for(i = 0; i < num_interfaces; i++)
2493 struct in_addr *ifip = iface_n_ip(i);
2497 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2500 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2503 /* ready to listen */
2504 if (listen(s, 5) == -1)
2506 DEBUG(0,("listen: %s\n",strerror(errno)));
2510 FD_SET(s,&listen_set);
2515 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2518 /* open an incoming socket */
2519 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2523 /* ready to listen */
2524 if (listen(s, 5) == -1)
2526 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2531 fd_listenset[0] = s;
2532 FD_SET(s,&listen_set);
2535 /* now accept incoming connections - forking a new process
2536 for each incoming connection */
2537 DEBUG(2,("waiting for a connection\n"));
2543 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2545 num = sys_select(&lfds,NULL);
2547 if (num == -1 && errno == EINTR)
2550 /* Find the sockets that are read-ready - accept on these. */
2551 for( ; num > 0; num--)
2553 struct sockaddr addr;
2554 int in_addrlen = sizeof(addr);
2557 for(i = 0; i < num_interfaces; i++)
2559 if(FD_ISSET(fd_listenset[i],&lfds))
2561 s = fd_listenset[i];
2562 /* Clear this so we don't look at it again. */
2563 FD_CLR(fd_listenset[i],&lfds);
2568 Client = accept(s,&addr,&in_addrlen);
2570 if (Client == -1 && errno == EINTR)
2575 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2579 #ifdef NO_FORK_DEBUG
2580 #ifndef NO_SIGNAL_TEST
2581 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2582 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2583 #endif /* NO_SIGNAL_TEST */
2585 #else /* NO_FORK_DEBUG */
2586 if (Client != -1 && fork()==0)
2588 /* Child code ... */
2590 #ifndef NO_SIGNAL_TEST
2591 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2592 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2593 #endif /* NO_SIGNAL_TEST */
2594 /* close the listening socket(s) */
2595 for(i = 0; i < num_interfaces; i++)
2596 close(fd_listenset[i]);
2598 /* close our standard file descriptors */
2602 set_socket_options(Client,"SO_KEEPALIVE");
2603 set_socket_options(Client,user_socket_options);
2605 /* Reset global variables in util.c so that
2606 client substitutions will be done correctly
2609 reset_globals_after_fork();
2612 close(Client); /* The parent doesn't need this socket */
2613 #endif /* NO_FORK_DEBUG */
2616 } /* end if is_daemon */
2619 /* Started from inetd. fd 0 is the socket. */
2620 /* We will abort gracefully when the client or remote system
2622 #ifndef NO_SIGNAL_TEST
2623 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2627 /* close our standard file descriptors */
2630 set_socket_options(Client,"SO_KEEPALIVE");
2631 set_socket_options(Client,user_socket_options);
2637 /****************************************************************************
2638 process an smb from the client - split out from the process() code so
2639 it can be used by the oplock break code.
2640 ****************************************************************************/
2642 static void process_smb(char *inbuf, char *outbuf)
2645 static int trans_num;
2646 int msg_type = CVAL(inbuf,0);
2647 int32 len = smb_len(inbuf);
2648 int nread = len + 4;
2650 if (trans_num == 0) {
2651 /* on the first packet, check the global hosts allow/ hosts
2652 deny parameters before doing any parsing of the packet
2653 passed to us by the client. This prevents attacks on our
2654 parsing code from hosts not in the hosts allow list */
2655 if (!check_access(-1)) {
2656 /* send a negative session response "not listining on calling
2658 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2659 DEBUG(1,("%s Connection denied from %s\n",
2660 timestring(),client_addr(Client)));
2661 send_smb(Client,(char *)buf);
2662 exit_server("connection denied");
2666 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2667 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2670 if(trans_num == 1 && VT_Check(inbuf))
2679 else if(msg_type == 0x85)
2680 return; /* Keepalive packet. */
2682 nread = construct_reply(inbuf,outbuf,nread,max_send);
2686 if (CVAL(outbuf,0) == 0)
2689 if (nread != smb_len(outbuf) + 4)
2691 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2692 nread, smb_len(outbuf)));
2695 send_smb(Client,outbuf);
2700 /****************************************************************************
2701 open the oplock IPC socket communication
2702 ****************************************************************************/
2703 static BOOL open_oplock_ipc(void)
2705 struct sockaddr_in sock_name;
2706 int len = sizeof(sock_name);
2708 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2710 /* Open a lookback UDP socket on a random port. */
2711 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2712 if (oplock_sock == -1)
2714 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2715 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2720 /* Find out the transient UDP port we have been allocated. */
2721 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2723 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2730 oplock_port = ntohs(sock_name.sin_port);
2732 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2733 getpid(), oplock_port));
2738 /****************************************************************************
2739 process an oplock break message.
2740 ****************************************************************************/
2741 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2747 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2748 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2750 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2752 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2753 msg_len, from_port));
2755 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2756 only valid request. */
2758 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2760 case OPLOCK_BREAK_CMD:
2761 /* Ensure that the msg length is correct. */
2762 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2764 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2765 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2769 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2770 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2771 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2772 struct timeval tval;
2773 struct sockaddr_in toaddr;
2775 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2776 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2778 DEBUG(5,("process_local_message: oplock break request from \
2779 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2782 * If we have no record of any currently open oplocks,
2783 * it's not an error, as a close command may have
2784 * just been issued on the file that was oplocked.
2785 * Just return success in this case.
2788 if(global_oplocks_open != 0)
2790 if(oplock_break(dev, inode, &tval) == False)
2792 DEBUG(0,("process_local_message: oplock break failed - \
2793 not returning udp message.\n"));
2799 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2800 oplocks. Returning success.\n"));
2803 /* Send the message back after OR'ing in the 'REPLY' bit. */
2804 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2806 bzero((char *)&toaddr,sizeof(toaddr));
2807 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2808 toaddr.sin_port = htons(from_port);
2809 toaddr.sin_family = AF_INET;
2811 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2812 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2814 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2815 remotepid, strerror(errno)));
2819 DEBUG(5,("process_local_message: oplock break reply sent to \
2820 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2821 from_port, dev, inode));
2826 * Keep this as a debug case - eventually we can remove it.
2829 DEBUG(0,("process_local_message: Received unsolicited break \
2830 reply - dumping info.\n"));
2832 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2834 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2835 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2840 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2841 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2842 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2844 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2845 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2851 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2852 (unsigned int)SVAL(msg_start,0)));
2858 /****************************************************************************
2859 Process an oplock break directly.
2860 ****************************************************************************/
2861 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2865 char *outbuf = NULL;
2866 files_struct *fsp = NULL;
2869 BOOL shutdown_server = False;
2871 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2872 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2874 /* We need to search the file open table for the
2875 entry containing this dev and inode, and ensure
2876 we have an oplock on it. */
2877 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2881 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2882 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2883 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2892 /* The file could have been closed in the meantime - return success. */
2893 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2894 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2898 /* Ensure we have an oplock on the file */
2900 /* There is a potential race condition in that an oplock could
2901 have been broken due to another udp request, and yet there are
2902 still oplock break messages being sent in the udp message
2903 queue for this file. So return true if we don't have an oplock,
2904 as we may have just freed it.
2907 if(!fsp->granted_oplock)
2909 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));
2913 /* mark the oplock break as sent - we don't want to send twice! */
2914 if (fsp->sent_oplock_break)
2916 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));
2918 /* We have to fail the open here as we cannot send another oplock break on this
2919 file whilst we are awaiting a response from the client - neither can we
2920 allow another open to succeed while we are waiting for the client. */
2924 /* Now comes the horrid part. We must send an oplock break to the client,
2925 and then process incoming messages until we get a close or oplock release.
2926 At this point we know we need a new inbuf/outbuf buffer pair.
2927 We cannot use these staticaly as we may recurse into here due to
2928 messages crossing on the wire.
2931 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2933 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2937 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2939 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2945 /* Prepare the SMBlockingX message. */
2946 bzero(outbuf,smb_size);
2947 set_message(outbuf,8,0,True);
2949 SCVAL(outbuf,smb_com,SMBlockingX);
2950 SSVAL(outbuf,smb_tid,fsp->cnum);
2951 SSVAL(outbuf,smb_pid,0xFFFF);
2952 SSVAL(outbuf,smb_uid,0);
2953 SSVAL(outbuf,smb_mid,0xFFFF);
2954 SCVAL(outbuf,smb_vwv0,0xFF);
2955 SSVAL(outbuf,smb_vwv2,fnum);
2956 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2957 /* Change this when we have level II oplocks. */
2958 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2960 send_smb(Client, outbuf);
2962 /* Remember we just sent an oplock break on this file. */
2963 fsp->sent_oplock_break = True;
2965 /* We need this in case a readraw crosses on the wire. */
2966 global_oplock_break = True;
2968 /* Process incoming messages. */
2970 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2971 seconds we should just die.... */
2973 start_time = time(NULL);
2975 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2977 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2980 * Die if we got an error.
2983 if (smb_read_error == READ_EOF)
2984 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2986 if (smb_read_error == READ_ERROR)
2987 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2988 timestring(), strerror(errno)));
2990 if (smb_read_error == READ_TIMEOUT)
2991 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2992 timestring(), OPLOCK_BREAK_TIMEOUT));
2994 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2995 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2996 shutdown_server = True;
3001 * There are certain SMB requests that we shouldn't allow
3002 * to recurse. opens, renames and deletes are the obvious
3003 * ones. This is handled in the switch_message() function.
3004 * If global_oplock_break is set they will push the packet onto
3005 * the pending smb queue and return -1 (no reply).
3009 process_smb(inbuf, outbuf);
3012 * Die if we go over the time limit.
3015 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3017 DEBUG(0,("%s oplock_break: no break received from client within \
3018 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3019 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3020 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3021 shutdown_server = True;
3026 /* Free the buffers we've been using to recurse. */
3030 /* We need this in case a readraw crossed on the wire. */
3031 if(global_oplock_break)
3032 global_oplock_break = False;
3035 * If the client did not respond we must die.
3040 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3044 exit_server("oplock break failure");
3049 /* The lockingX reply will have removed the oplock flag
3050 from the sharemode. */
3052 fsp->granted_oplock = False;
3053 fsp->sent_oplock_break = False;
3054 global_oplocks_open--;
3057 /* Santity check - remove this later. JRA */
3058 if(global_oplocks_open < 0)
3060 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3061 global_oplocks_open));
3062 exit_server("oplock_break: global_oplocks_open < 0");
3065 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3066 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3071 /****************************************************************************
3072 Send an oplock break message to another smbd process. If the oplock is held
3073 by the local smbd then call the oplock break function directly.
3074 ****************************************************************************/
3076 BOOL request_oplock_break(share_mode_entry *share_entry,
3077 uint32 dev, uint32 inode)
3079 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3080 struct sockaddr_in addr_out;
3085 if(pid == share_entry->pid)
3087 /* We are breaking our own oplock, make sure it's us. */
3088 if(share_entry->op_port != oplock_port)
3090 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3091 should be %d\n", pid, share_entry->op_port, oplock_port));
3095 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3097 /* Call oplock break direct. */
3098 return oplock_break(dev, inode, &share_entry->time);
3101 /* We need to send a OPLOCK_BREAK_CMD message to the
3102 port in the share mode entry. */
3104 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3105 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3106 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3107 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3108 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3109 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3111 /* set the address and port */
3112 bzero((char *)&addr_out,sizeof(addr_out));
3113 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3114 addr_out.sin_port = htons( share_entry->op_port );
3115 addr_out.sin_family = AF_INET;
3117 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3118 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3120 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3121 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3123 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3124 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3125 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3131 * Now we must await the oplock broken message coming back
3132 * from the target smbd process. Timeout if it fails to
3133 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3134 * While we get messages that aren't ours, loop.
3137 start_time = time(NULL);
3138 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3140 while(time_left >= 0)
3142 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3143 int32 reply_msg_len;
3144 uint16 reply_from_port;
3145 char *reply_msg_start;
3147 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3148 time_left ? time_left * 1000 : 1) == False)
3150 if(smb_read_error == READ_TIMEOUT)
3152 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3153 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3154 share_entry->op_port, dev, inode));
3156 * This is a hack to make handling of failing clients more robust.
3157 * If a oplock break response message is not received in the timeout
3158 * period we may assume that the smbd servicing that client holding
3159 * the oplock has died and the client changes were lost anyway, so
3160 * we should continue to try and open the file.
3165 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3166 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3167 share_entry->op_port, dev, inode, strerror(errno)));
3171 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3172 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3174 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3176 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3179 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3185 * Test to see if this is the reply we are awaiting.
3188 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3189 (reply_from_port == share_entry->op_port) &&
3190 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3191 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3192 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3195 * This is the reply we've been waiting for.
3202 * This is another message - probably a break request.
3203 * Process it to prevent potential deadlock.
3204 * Note that the code in switch_message() prevents
3205 * us from recursing into here as any SMB requests
3206 * we might process that would cause another oplock
3207 * break request to be made will be queued.
3211 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3214 time_left -= (time(NULL) - start_time);
3217 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3222 /****************************************************************************
3223 Get the next SMB packet, doing the local message processing automatically.
3224 ****************************************************************************/
3226 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3228 BOOL got_smb = False;
3233 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3238 /* Deal with oplock break requests from other smbd's. */
3239 process_local_message(oplock_sock, inbuf, bufsize);
3243 if(ret && (CVAL(inbuf,0) == 0x85))
3245 /* Keepalive packet. */
3250 while(ret && !got_smb);
3255 /****************************************************************************
3256 check if a snum is in use
3257 ****************************************************************************/
3258 BOOL snum_used(int snum)
3261 for (i=0;i<MAX_CONNECTIONS;i++)
3262 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3267 /****************************************************************************
3268 reload the services file
3269 **************************************************************************/
3270 BOOL reload_services(BOOL test)
3277 pstrcpy(fname,lp_configfile());
3278 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3280 pstrcpy(servicesf,fname);
3287 if (test && !lp_file_list_changed())
3290 lp_killunused(snum_used);
3292 ret = lp_load(servicesf,False,False,True);
3294 /* perhaps the config filename is now set */
3296 reload_services(True);
3305 set_socket_options(Client,"SO_KEEPALIVE");
3306 set_socket_options(Client,user_socket_options);
3310 reset_mangled_cache();
3312 /* this forces service parameters to be flushed */
3313 become_service(-1,True);
3320 /****************************************************************************
3321 this prevents zombie child processes
3322 ****************************************************************************/
3323 static int sig_hup(void)
3325 BlockSignals(True,SIGHUP);
3326 DEBUG(0,("Got SIGHUP\n"));
3327 reload_services(False);
3328 #ifndef DONT_REINSTALL_SIG
3329 signal(SIGHUP,SIGNAL_CAST sig_hup);
3331 BlockSignals(False,SIGHUP);
3336 /****************************************************************************
3337 make a connection to a service
3338 ****************************************************************************/
3339 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3343 struct passwd *pass = NULL;
3344 connection_struct *pcon;
3350 snum = find_service(service);
3354 if (strequal(service,"IPC$"))
3356 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3360 DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));
3364 if (strequal(service,HOMES_NAME))
3366 if (*user && Get_Pwnam(user,True))
3367 return(make_connection(user,user,password,pwlen,dev,vuid));
3369 if(lp_security() != SEC_SHARE)
3371 if (validated_username(vuid))
3373 strcpy(user,validated_username(vuid));
3374 return(make_connection(user,user,password,pwlen,dev,vuid));
3380 * Security = share. Try with sesssetup_user as the username.
3384 strcpy(user,sesssetup_user);
3385 return(make_connection(user,user,password,pwlen,dev,vuid));
3390 if (!lp_snum_ok(snum) || !check_access(snum)) {
3394 /* you can only connect to the IPC$ service as an ipc device */
3395 if (strequal(service,"IPC$"))
3398 if (*dev == '?' || !*dev)
3400 if (lp_print_ok(snum))
3401 strcpy(dev,"LPT1:");
3406 /* if the request is as a printer and you can't print then refuse */
3408 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3409 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3413 /* lowercase the user name */
3416 /* add it as a possible user name */
3417 add_session_user(service);
3419 /* shall we let them in? */
3420 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3422 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3426 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3429 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3433 pcon = &Connections[cnum];
3434 bzero((char *)pcon,sizeof(*pcon));
3436 /* find out some info about the user */
3437 pass = Get_Pwnam(user,True);
3441 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3445 pcon->read_only = lp_readonly(snum);
3449 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3450 string_sub(list,"%S",service);
3452 if (user_in_list(user,list))
3453 pcon->read_only = True;
3455 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3456 string_sub(list,"%S",service);
3458 if (user_in_list(user,list))
3459 pcon->read_only = False;
3462 /* admin user check */
3464 /* JRA - original code denied admin user if the share was
3465 marked read_only. Changed as I don't think this is needed,
3466 but old code left in case there is a problem here.
3468 if (user_in_list(user,lp_admin_users(snum))
3470 && !pcon->read_only)
3475 pcon->admin_user = True;
3476 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3479 pcon->admin_user = False;
3481 pcon->force_user = force;
3483 pcon->uid = pass->pw_uid;
3484 pcon->gid = pass->pw_gid;
3485 pcon->num_files_open = 0;
3486 pcon->lastused = time(NULL);
3487 pcon->service = snum;
3489 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3490 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3491 pcon->dirptr = NULL;
3492 pcon->veto_list = NULL;
3493 pcon->hide_list = NULL;
3494 pcon->veto_oplock_list = NULL;
3495 string_set(&pcon->dirpath,"");
3496 string_set(&pcon->user,user);
3499 if (*lp_force_group(snum))
3504 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3505 /* default service may be a group name */
3506 string_sub(gname,"%S",service);
3507 gptr = (struct group *)getgrnam(gname);
3511 pcon->gid = gptr->gr_gid;
3512 DEBUG(3,("Forced group %s\n",gname));
3515 DEBUG(1,("Couldn't find group %s\n",gname));
3519 if (*lp_force_user(snum))
3521 struct passwd *pass2;
3523 fstrcpy(fuser,lp_force_user(snum));
3524 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3527 pcon->uid = pass2->pw_uid;
3528 string_set(&pcon->user,fuser);
3529 fstrcpy(user,fuser);
3530 pcon->force_user = True;
3531 DEBUG(3,("Forced user %s\n",fuser));
3534 DEBUG(1,("Couldn't find user %s\n",fuser));
3539 pstrcpy(s,lp_pathname(snum));
3540 standard_sub(cnum,s);
3541 string_set(&pcon->connectpath,s);
3542 DEBUG(3,("Connect path is %s\n",s));
3545 /* groups stuff added by ih */
3547 pcon->igroups = NULL;
3548 pcon->groups = NULL;
3553 /* Find all the groups this uid is in and store them. Used by become_user() */
3554 setup_groups(pcon->user,pcon->uid,pcon->gid,
3555 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3557 /* check number of connections */
3558 if (!claim_connection(cnum,
3559 lp_servicename(SNUM(cnum)),
3560 lp_max_connections(SNUM(cnum)),False))
3562 DEBUG(1,("too many connections - rejected\n"));
3566 if (lp_status(SNUM(cnum)))
3567 claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3572 /* execute any "root preexec = " line */
3573 if (*lp_rootpreexec(SNUM(cnum)))
3576 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3577 standard_sub(cnum,cmd);
3578 DEBUG(5,("cmd=%s\n",cmd));
3579 smbrun(cmd,NULL,False);
3582 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3584 DEBUG(0,("Can't become connected user!\n"));
3586 if (!IS_IPC(cnum)) {
3587 yield_connection(cnum,
3588 lp_servicename(SNUM(cnum)),
3589 lp_max_connections(SNUM(cnum)));
3590 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3595 if (ChDir(pcon->connectpath) != 0)
3597 DEBUG(0,("Can't change directory to %s (%s)\n",
3598 pcon->connectpath,strerror(errno)));
3601 if (!IS_IPC(cnum)) {
3602 yield_connection(cnum,
3603 lp_servicename(SNUM(cnum)),
3604 lp_max_connections(SNUM(cnum)));
3605 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3610 string_set(&pcon->origpath,pcon->connectpath);
3612 #if SOFTLINK_OPTIMISATION
3613 /* resolve any soft links early */
3616 pstrcpy(s,pcon->connectpath);
3618 string_set(&pcon->connectpath,s);
3619 ChDir(pcon->connectpath);
3623 num_connections_open++;
3624 add_session_user(user);
3626 /* execute any "preexec = " line */
3627 if (*lp_preexec(SNUM(cnum)))
3630 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3631 standard_sub(cnum,cmd);
3632 smbrun(cmd,NULL,False);
3635 /* we've finished with the sensitive stuff */
3638 /* Add veto/hide lists */
3639 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3641 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3642 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3643 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3648 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3651 client_addr(Client),
3652 lp_servicename(SNUM(cnum)),user,
3661 /****************************************************************************
3662 Attempt to break an oplock on a file (if oplocked).
3663 Returns True if the file was closed as a result of
3664 the oplock break, False otherwise.
3665 Used as a last ditch attempt to free a space in the
3666 file table when we have run out.
3667 ****************************************************************************/
3669 static BOOL attempt_close_oplocked_file(files_struct *fp)
3672 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3674 if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3676 /* Try and break the oplock. */
3677 file_fd_struct *fsp = fp->fd_ptr;
3678 if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3679 if(!fp->open) /* Did the oplock break close the file ? */
3687 /****************************************************************************
3688 find first available file slot
3689 ****************************************************************************/
3690 int find_free_file(void )
3693 static int first_file;
3695 /* we want to give out file handles differently on each new
3696 connection because of a common bug in MS clients where they try to
3697 reuse a file descriptor from an earlier smb connection. This code
3698 increases the chance that the errant client will get an error rather
3699 than causing corruption */
3700 if (first_file == 0) {
3701 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3702 if (first_file == 0) first_file = 1;
3705 if (first_file >= MAX_OPEN_FILES)
3708 for (i=first_file;i<MAX_OPEN_FILES;i++)
3709 if (!Files[i].open && !Files[i].reserved) {
3710 memset(&Files[i], 0, sizeof(Files[i]));
3712 Files[i].reserved = True;
3716 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3717 for (i=1;i<first_file;i++)
3718 if (!Files[i].open && !Files[i].reserved) {
3719 memset(&Files[i], 0, sizeof(Files[i]));
3721 Files[i].reserved = True;
3726 * Before we give up, go through the open files
3727 * and see if there are any files opened with a
3728 * batch oplock. If so break the oplock and then
3729 * re-use that entry (if it becomes closed).
3730 * This may help as NT/95 clients tend to keep
3731 * files batch oplocked for quite a long time
3732 * after they have finished with them.
3734 for (i=first_file;i<MAX_OPEN_FILES;i++) {
3735 if(attempt_close_oplocked_file( &Files[i])) {
3736 memset(&Files[i], 0, sizeof(Files[i]));
3738 Files[i].reserved = True;
3743 for (i=1;i<MAX_OPEN_FILES;i++) {
3744 if(attempt_close_oplocked_file( &Files[i])) {
3745 memset(&Files[i], 0, sizeof(Files[i]));
3747 Files[i].reserved = True;
3752 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3756 /****************************************************************************
3757 find first available connection slot, starting from a random position.
3758 The randomisation stops problems with the server dieing and clients
3759 thinking the server is still available.
3760 ****************************************************************************/
3761 static int find_free_connection(int hash )
3765 hash = (hash % (MAX_CONNECTIONS-2))+1;
3769 for (i=hash+1;i!=hash;)
3771 if (!Connections[i].open && Connections[i].used == used)
3773 DEBUG(3,("found free connection number %d\n",i));
3777 if (i == MAX_CONNECTIONS)
3787 DEBUG(1,("ERROR! Out of connection structures\n"));
3792 /****************************************************************************
3793 reply for the core protocol
3794 ****************************************************************************/
3795 int reply_corep(char *outbuf)
3797 int outsize = set_message(outbuf,1,0,True);
3799 Protocol = PROTOCOL_CORE;
3805 /****************************************************************************
3806 reply for the coreplus protocol
3807 ****************************************************************************/
3808 int reply_coreplus(char *outbuf)
3810 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3811 int outsize = set_message(outbuf,13,0,True);
3812 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3813 readbraw and writebraw (possibly) */
3814 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3815 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3817 Protocol = PROTOCOL_COREPLUS;
3823 /****************************************************************************
3824 reply for the lanman 1.0 protocol
3825 ****************************************************************************/
3826 int reply_lanman1(char *outbuf)
3828 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3830 BOOL doencrypt = SMBENCRYPT();
3831 time_t t = time(NULL);
3833 if (lp_security()>=SEC_USER) secword |= 1;
3834 if (doencrypt) secword |= 2;
3836 set_message(outbuf,13,doencrypt?8:0,True);
3837 SSVAL(outbuf,smb_vwv1,secword);
3838 /* Create a token value and add it to the outgoing packet. */
3840 generate_next_challenge(smb_buf(outbuf));
3842 Protocol = PROTOCOL_LANMAN1;
3844 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3845 SSVAL(outbuf,smb_vwv2,max_recv);
3846 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3847 SSVAL(outbuf,smb_vwv4,1);
3848 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3849 readbraw writebraw (possibly) */
3850 SIVAL(outbuf,smb_vwv6,getpid());
3851 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3853 put_dos_date(outbuf,smb_vwv8,t);
3855 return (smb_len(outbuf)+4);
3859 /****************************************************************************
3860 reply for the lanman 2.0 protocol
3861 ****************************************************************************/
3862 int reply_lanman2(char *outbuf)
3864 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3866 BOOL doencrypt = SMBENCRYPT();
3867 time_t t = time(NULL);
3868 struct cli_state *cli = NULL;
3872 if (lp_security() == SEC_SERVER) {
3873 cli = server_cryptkey();
3877 DEBUG(3,("using password server validation\n"));
3878 doencrypt = ((cli->sec_mode & 2) != 0);
3881 if (lp_security()>=SEC_USER) secword |= 1;
3882 if (doencrypt) secword |= 2;
3887 generate_next_challenge(cryptkey);
3889 memcpy(cryptkey, cli->cryptkey, 8);
3890 set_challenge(cli->cryptkey);
3894 set_message(outbuf,13,crypt_len,True);
3895 SSVAL(outbuf,smb_vwv1,secword);
3896 SIVAL(outbuf,smb_vwv6,getpid());
3898 memcpy(smb_buf(outbuf), cryptkey, 8);
3900 Protocol = PROTOCOL_LANMAN2;
3902 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3903 SSVAL(outbuf,smb_vwv2,max_recv);
3904 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3905 SSVAL(outbuf,smb_vwv4,1);
3906 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3907 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3908 put_dos_date(outbuf,smb_vwv8,t);
3910 return (smb_len(outbuf)+4);
3914 /****************************************************************************
3915 reply for the nt protocol
3916 ****************************************************************************/
3917 int reply_nt1(char *outbuf)
3919 /* dual names + lock_and_read + nt SMBs + remote API calls */
3920 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
3922 other valid capabilities which we may support at some time...
3923 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3924 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3928 BOOL doencrypt = SMBENCRYPT();
3929 time_t t = time(NULL);
3931 struct cli_state *cli = NULL;
3935 if (lp_security() == SEC_SERVER) {
3936 cli = server_cryptkey();
3940 DEBUG(3,("using password server validation\n"));
3941 doencrypt = ((cli->sec_mode & 2) != 0);
3947 generate_next_challenge(cryptkey);
3949 memcpy(cryptkey, cli->cryptkey, 8);
3950 set_challenge(cli->cryptkey);
3954 if (lp_readraw() && lp_writeraw()) {
3955 capabilities |= CAP_RAW_MODE;
3958 if (lp_security() >= SEC_USER) secword |= 1;
3959 if (doencrypt) secword |= 2;
3961 /* decide where (if) to put the encryption challenge, and
3962 follow it with the OEM'd domain name
3964 data_len = crypt_len + strlen(global_myworkgroup) + 1;
3966 set_message(outbuf,17,data_len,True);
3967 strcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
3969 CVAL(outbuf,smb_vwv1) = secword;
3970 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3972 memcpy(smb_buf(outbuf), cryptkey, 8);
3974 Protocol = PROTOCOL_NT1;
3976 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3977 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3978 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3979 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
3980 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3981 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3982 put_long_date(outbuf+smb_vwv11+1,t);
3983 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3984 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3986 return (smb_len(outbuf)+4);
3989 /* these are the protocol lists used for auto architecture detection:
3992 protocol [PC NETWORK PROGRAM 1.0]
3993 protocol [XENIX CORE]
3994 protocol [MICROSOFT NETWORKS 1.03]
3995 protocol [LANMAN1.0]
3996 protocol [Windows for Workgroups 3.1a]
3997 protocol [LM1.2X002]
3998 protocol [LANMAN2.1]
3999 protocol [NT LM 0.12]
4002 protocol [PC NETWORK PROGRAM 1.0]
4003 protocol [XENIX CORE]
4004 protocol [MICROSOFT NETWORKS 1.03]
4005 protocol [LANMAN1.0]
4006 protocol [Windows for Workgroups 3.1a]
4007 protocol [LM1.2X002]
4008 protocol [LANMAN2.1]
4009 protocol [NT LM 0.12]
4012 protocol [PC NETWORK PROGRAM 1.0]
4013 protocol [XENIX CORE]
4014 protocol [LANMAN1.0]
4015 protocol [LM1.2X002]
4016 protocol [LANMAN2.1]
4020 * Modified to recognize the architecture of the remote machine better.
4022 * This appears to be the matrix of which protocol is used by which
4024 Protocol WfWg Win95 WinNT OS/2
4025 PC NETWORK PROGRAM 1.0 1 1 1 1
4027 MICROSOFT NETWORKS 3.0 2 2
4029 MICROSOFT NETWORKS 1.03 3
4032 Windows for Workgroups 3.1a 5 5 5
4037 * tim@fsg.com 09/29/95
4040 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4041 #define ARCH_WIN95 0x2
4042 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4043 #define ARCH_WINNT 0x8
4044 #define ARCH_SAMBA 0x10
4046 #define ARCH_ALL 0x1F
4048 /* List of supported protocols, most desired first */
4052 int (*proto_reply_fn)(char *);
4054 } supported_protocols[] = {
4055 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4056 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4057 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4058 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4059 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4060 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4061 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4062 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4063 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4068 /****************************************************************************
4070 ****************************************************************************/
4071 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4073 int outsize = set_message(outbuf,1,0,True);
4078 int bcc = SVAL(smb_buf(inbuf),-2);
4079 int arch = ARCH_ALL;
4081 p = smb_buf(inbuf)+1;
4082 while (p < (smb_buf(inbuf) + bcc))
4085 DEBUG(3,("Requested protocol [%s]\n",p));
4086 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4087 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4088 else if (strcsequal(p,"DOS LM1.2X002"))
4089 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4090 else if (strcsequal(p,"DOS LANMAN2.1"))
4091 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4092 else if (strcsequal(p,"NT LM 0.12"))
4093 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4094 else if (strcsequal(p,"LANMAN2.1"))
4095 arch &= ( ARCH_WINNT | ARCH_OS2 );
4096 else if (strcsequal(p,"LM1.2X002"))
4097 arch &= ( ARCH_WINNT | ARCH_OS2 );
4098 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4100 else if (strcsequal(p,"XENIX CORE"))
4101 arch &= ( ARCH_WINNT | ARCH_OS2 );
4102 else if (strcsequal(p,"Samba")) {
4112 set_remote_arch(RA_SAMBA);
4115 set_remote_arch(RA_WFWG);
4118 set_remote_arch(RA_WIN95);
4121 set_remote_arch(RA_WINNT);
4124 set_remote_arch(RA_OS2);
4127 set_remote_arch(RA_UNKNOWN);
4131 /* possibly reload - change of architecture */
4132 reload_services(True);
4134 /* a special case to stop password server loops */
4135 if (Index == 1 && strequal(remote_machine,myhostname) &&
4136 (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4137 exit_server("Password server loop!");
4139 /* Check for protocols, most desirable first */
4140 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4142 p = smb_buf(inbuf)+1;
4144 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4145 while (p < (smb_buf(inbuf) + bcc))
4147 if (strequal(p,supported_protocols[protocol].proto_name))
4156 SSVAL(outbuf,smb_vwv0,choice);
4158 extern fstring remote_proto;
4159 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4160 reload_services(True);
4161 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4162 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4165 DEBUG(0,("No protocol supported !\n"));
4167 SSVAL(outbuf,smb_vwv0,choice);
4169 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4175 /****************************************************************************
4176 close all open files for a connection
4177 ****************************************************************************/
4178 static void close_open_files(int cnum)
4181 for (i=0;i<MAX_OPEN_FILES;i++)
4182 if( Files[i].cnum == cnum && Files[i].open) {
4183 close_file(i,False);
4189 /****************************************************************************
4191 ****************************************************************************/
4192 void close_cnum(int cnum, uint16 vuid)
4195 DirCacheFlush(SNUM(cnum));
4199 if (!OPEN_CNUM(cnum))
4201 DEBUG(0,("Can't close cnum %d\n",cnum));
4205 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4207 remote_machine,client_addr(Client),
4208 lp_servicename(SNUM(cnum))));
4210 yield_connection(cnum,
4211 lp_servicename(SNUM(cnum)),
4212 lp_max_connections(SNUM(cnum)));
4214 if (lp_status(SNUM(cnum)))
4215 yield_connection(cnum,"STATUS.",MAXSTATUS);
4217 close_open_files(cnum);
4218 dptr_closecnum(cnum);
4220 /* execute any "postexec = " line */
4221 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4224 strcpy(cmd,lp_postexec(SNUM(cnum)));
4225 standard_sub(cnum,cmd);
4226 smbrun(cmd,NULL,False);
4231 /* execute any "root postexec = " line */
4232 if (*lp_rootpostexec(SNUM(cnum)))
4235 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4236 standard_sub(cnum,cmd);
4237 smbrun(cmd,NULL,False);
4240 Connections[cnum].open = False;
4241 num_connections_open--;
4242 if (Connections[cnum].ngroups && Connections[cnum].groups)
4244 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4245 free(Connections[cnum].groups);
4246 free(Connections[cnum].igroups);
4247 Connections[cnum].groups = NULL;
4248 Connections[cnum].igroups = NULL;
4249 Connections[cnum].ngroups = 0;
4252 free_namearray(Connections[cnum].veto_list);
4253 free_namearray(Connections[cnum].hide_list);
4254 free_namearray(Connections[cnum].veto_oplock_list);
4256 string_set(&Connections[cnum].user,"");
4257 string_set(&Connections[cnum].dirpath,"");
4258 string_set(&Connections[cnum].connectpath,"");
4264 /*******************************************************************
4265 prepare to dump a core file - carefully!
4266 ********************************************************************/
4267 static BOOL dump_core(void)
4271 pstrcpy(dname,debugf);
4272 if ((p=strrchr(dname,'/'))) *p=0;
4273 strcat(dname,"/corefiles");
4275 sys_chown(dname,getuid(),getgid());
4277 if (chdir(dname)) return(False);
4280 #ifndef NO_GETRLIMIT
4284 getrlimit(RLIMIT_CORE, &rlp);
4285 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4286 setrlimit(RLIMIT_CORE, &rlp);
4287 getrlimit(RLIMIT_CORE, &rlp);
4288 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4294 DEBUG(0,("Dumping core in %s\n",dname));
4299 /****************************************************************************
4301 ****************************************************************************/
4302 void exit_server(char *reason)
4304 static int firsttime=1;
4307 if (!firsttime) exit(0);
4311 DEBUG(2,("Closing connections\n"));
4312 for (i=0;i<MAX_CONNECTIONS;i++)
4313 if (Connections[i].open)
4314 close_cnum(i,(uint16)-1);
4316 if (dcelogin_atmost_once)
4320 int oldlevel = DEBUGLEVEL;
4322 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4324 show_msg(last_inbuf);
4325 DEBUGLEVEL = oldlevel;
4326 DEBUG(0,("===============================================================\n"));
4328 if (dump_core()) return;
4334 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4338 /****************************************************************************
4339 do some standard substitutions in a string
4340 ****************************************************************************/
4341 void standard_sub(int cnum,char *str)
4343 if (VALID_CNUM(cnum)) {
4346 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4348 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4349 string_sub(p,"%H",home);
4353 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4354 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4355 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4356 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4358 * Patch from jkf@soton.ac.uk
4359 * Left the %N (NIS server name) in standard_sub_basic as it
4360 * is a feature for logon servers, hence uses the username.
4361 * The %p (NIS server path) code is here as it is used
4362 * instead of the default "path =" string in [homes] and so
4363 * needs the service name, not the username.
4365 case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4366 case '\0' : p++; break; /* don't run off the end of the string */
4367 default : p+=2; break;
4371 standard_sub_basic(str);
4375 These flags determine some of the permissions required to do an operation
4377 Note that I don't set NEED_WRITE on some write operations because they
4378 are used by some brain-dead clients when printing, and I don't want to
4379 force write permissions on print services.
4381 #define AS_USER (1<<0)
4382 #define NEED_WRITE (1<<1)
4383 #define TIME_INIT (1<<2)
4384 #define CAN_IPC (1<<3)
4385 #define AS_GUEST (1<<5)
4386 #define QUEUE_IN_OPLOCK (1<<6)
4389 define a list of possible SMB messages and their corresponding
4390 functions. Any message that has a NULL function is unimplemented -
4391 please feel free to contribute implementations!
4393 struct smb_message_struct
4397 int (*fn)(char *, char *, int, int);
4407 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4408 {SMBtcon,"SMBtcon",reply_tcon,0},
4409 {SMBtdis,"SMBtdis",reply_tdis,0},
4410 {SMBexit,"SMBexit",reply_exit,0},
4411 {SMBioctl,"SMBioctl",reply_ioctl,0},
4412 {SMBecho,"SMBecho",reply_echo,0},
4413 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4414 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4415 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4416 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4417 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4418 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4419 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4420 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4422 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4423 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4424 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4426 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4427 {SMBread,"SMBread",reply_read,AS_USER},
4428 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4429 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4430 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4431 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4432 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4433 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4435 /* this is a Pathworks specific call, allowing the
4436 changing of the root path */
4437 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4439 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4440 {SMBflush,"SMBflush",reply_flush,AS_USER},
4441 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4442 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4443 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4444 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4445 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4446 {SMBlock,"SMBlock",reply_lock,AS_USER},
4447 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4449 /* CORE+ PROTOCOL FOLLOWS */
4451 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4452 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4453 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4454 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4455 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4457 /* LANMAN1.0 PROTOCOL FOLLOWS */
4459 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4460 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4461 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4462 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4463 {SMBwritec,"SMBwritec",NULL,AS_USER},
4464 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4465 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4466 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4467 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4468 {SMBioctls,"SMBioctls",NULL,AS_USER},
4469 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4470 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4472 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4473 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4474 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4475 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4477 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4478 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4479 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4481 /* LANMAN2.0 PROTOCOL FOLLOWS */
4482 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4483 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4484 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4485 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4487 /* messaging routines */
4488 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4489 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4490 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4491 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4493 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4495 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4496 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4497 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4498 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4501 /****************************************************************************
4502 return a string containing the function name of a SMB command
4503 ****************************************************************************/
4504 char *smb_fn_name(int type)
4506 static char *unknown_name = "SMBunknown";
4507 static int num_smb_messages =
4508 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4511 for (match=0;match<num_smb_messages;match++)
4512 if (smb_messages[match].code == type)
4515 if (match == num_smb_messages)
4516 return(unknown_name);
4518 return(smb_messages[match].name);
4522 /****************************************************************************
4523 do a switch on the message type, and return the response size
4524 ****************************************************************************/
4525 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4529 static int num_smb_messages =
4530 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4534 struct timeval msg_start_time;
4535 struct timeval msg_end_time;
4536 static unsigned long total_time = 0;
4538 GetTimeOfDay(&msg_start_time);
4545 last_message = type;
4547 /* make sure this is an SMB packet */
4548 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4550 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4554 for (match=0;match<num_smb_messages;match++)
4555 if (smb_messages[match].code == type)
4558 if (match == num_smb_messages)
4560 DEBUG(0,("Unknown message type %d!\n",type));
4561 outsize = reply_unknown(inbuf,outbuf);
4565 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4567 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4570 * Queue this message as we are the process of an oplock break.
4573 DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4576 push_smb_message( inbuf, size);
4580 if (smb_messages[match].fn)
4582 int cnum = SVAL(inbuf,smb_tid);
4583 int flags = smb_messages[match].flags;
4584 static uint16 last_session_tag = UID_FIELD_INVALID;
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);
4591 * Ensure the correct username is in sesssetup_user.
4592 * This is a really ugly bugfix for problems with
4593 * multiple session_setup_and_X's being done and
4594 * allowing %U and %G substitutions to work correctly.
4595 * There is a reason this code is done here, don't
4596 * move it unless you know what you're doing... :-).
4599 if(session_tag != last_session_tag ) {
4600 user_struct *vuser = NULL;
4602 last_session_tag = session_tag;
4603 if(session_tag != UID_FIELD_INVALID)
4604 vuser = get_valid_user_struct(session_tag);
4606 pstrcpy( sesssetup_user, vuser->requested_name);
4609 /* does this protocol need to be run as root? */
4610 if (!(flags & AS_USER))
4613 /* does this protocol need to be run as the connected user? */
4614 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4615 if (flags & AS_GUEST)
4618 return(ERROR(ERRSRV,ERRinvnid));
4620 /* this code is to work around a bug is MS client 3 without
4621 introducing a security hole - it needs to be able to do
4622 print queue checks as guest if it isn't logged in properly */
4623 if (flags & AS_USER)
4626 /* does it need write permission? */
4627 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4628 return(ERROR(ERRSRV,ERRaccess));
4630 /* ipc services are limited */
4631 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4632 return(ERROR(ERRSRV,ERRaccess));
4634 /* load service specific parameters */
4635 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4636 return(ERROR(ERRSRV,ERRaccess));
4638 /* does this protocol need to be run as guest? */
4639 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4640 return(ERROR(ERRSRV,ERRaccess));
4644 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4648 outsize = reply_unknown(inbuf,outbuf);
4653 GetTimeOfDay(&msg_end_time);
4654 if (!(smb_messages[match].flags & TIME_INIT))
4656 smb_messages[match].time = 0;
4657 smb_messages[match].flags |= TIME_INIT;
4660 unsigned long this_time =
4661 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4662 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4663 smb_messages[match].time += this_time;
4664 total_time += this_time;
4666 DEBUG(2,("TIME %s %d usecs %g pct\n",
4667 smb_fn_name(type),smb_messages[match].time,
4668 (100.0*smb_messages[match].time) / total_time));
4675 /****************************************************************************
4676 construct a chained reply and add it to the already made reply
4677 **************************************************************************/
4678 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4680 static char *orig_inbuf;
4681 static char *orig_outbuf;
4682 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4683 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4684 char *inbuf2, *outbuf2;
4686 char inbuf_saved[smb_wct];
4687 char outbuf_saved[smb_wct];
4688 extern int chain_size;
4689 int wct = CVAL(outbuf,smb_wct);
4690 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4692 /* maybe its not chained */
4693 if (smb_com2 == 0xFF) {
4694 CVAL(outbuf,smb_vwv0) = 0xFF;
4698 if (chain_size == 0) {
4699 /* this is the first part of the chain */
4701 orig_outbuf = outbuf;
4704 /* we need to tell the client where the next part of the reply will be */
4705 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4706 CVAL(outbuf,smb_vwv0) = smb_com2;
4708 /* remember how much the caller added to the chain, only counting stuff
4709 after the parameter words */
4710 chain_size += outsize - smb_wct;
4712 /* work out pointers into the original packets. The
4713 headers on these need to be filled in */
4714 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4715 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4717 /* remember the original command type */
4718 smb_com1 = CVAL(orig_inbuf,smb_com);
4720 /* save the data which will be overwritten by the new headers */
4721 memcpy(inbuf_saved,inbuf2,smb_wct);
4722 memcpy(outbuf_saved,outbuf2,smb_wct);
4724 /* give the new packet the same header as the last part of the SMB */
4725 memmove(inbuf2,inbuf,smb_wct);
4727 /* create the in buffer */
4728 CVAL(inbuf2,smb_com) = smb_com2;
4730 /* create the out buffer */
4731 bzero(outbuf2,smb_size);
4732 set_message(outbuf2,0,0,True);
4733 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4735 memcpy(outbuf2+4,inbuf2+4,4);
4736 CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4737 CVAL(outbuf2,smb_reh) = 0;
4738 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4740 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4741 SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4742 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4743 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4744 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4745 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4747 DEBUG(3,("Chained message\n"));
4750 /* process the request */
4751 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4752 bufsize-chain_size);
4754 /* copy the new reply and request headers over the old ones, but
4755 preserve the smb_com field */
4756 memmove(orig_outbuf,outbuf2,smb_wct);
4757 CVAL(orig_outbuf,smb_com) = smb_com1;
4759 /* restore the saved data, being careful not to overwrite any
4760 data from the reply header */
4761 memcpy(inbuf2,inbuf_saved,smb_wct);
4763 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4764 if (ofs < 0) ofs = 0;
4765 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4773 /****************************************************************************
4774 construct a reply to the incoming packet
4775 ****************************************************************************/
4776 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4778 int type = CVAL(inbuf,smb_com);
4780 int msg_type = CVAL(inbuf,0);
4781 extern int chain_size;
4783 smb_last_time = time(NULL);
4789 bzero(outbuf,smb_size);
4792 return(reply_special(inbuf,outbuf));
4794 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4795 set_message(outbuf,0,0,True);
4797 memcpy(outbuf+4,inbuf+4,4);
4798 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4799 CVAL(outbuf,smb_reh) = 0;
4800 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4802 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4803 SSVAL(outbuf,smb_err,SMB_SUCCESS);
4804 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4805 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4806 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4807 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4809 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4811 outsize += chain_size;
4814 smb_setlen(outbuf,outsize - 4);
4818 /****************************************************************************
4819 process commands from the client
4820 ****************************************************************************/
4821 static void process(void)
4825 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4826 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4827 if ((InBuffer == NULL) || (OutBuffer == NULL))
4830 InBuffer += SMB_ALIGNMENT;
4831 OutBuffer += SMB_ALIGNMENT;
4834 DEBUG(3,("priming nmbd\n"));
4837 ip = *interpret_addr2("localhost");
4838 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4840 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4844 /* re-initialise the timezone */
4849 int deadtime = lp_deadtime()*60;
4851 int last_keepalive=0;
4852 int service_load_counter = 0;
4853 BOOL got_smb = False;
4856 deadtime = DEFAULT_SMBD_TIMEOUT;
4858 #if USE_READ_PREDICTION
4859 if (lp_readprediction())
4860 do_read_prediction();
4865 for (counter=SMBD_SELECT_LOOP;
4866 !receive_message_or_smb(Client,oplock_sock,
4867 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4868 counter += SMBD_SELECT_LOOP)
4872 BOOL allidle = True;
4873 extern int keepalive;
4875 if (counter > 365 * 3600) /* big number of seconds. */
4878 service_load_counter = 0;
4881 if (smb_read_error == READ_EOF)
4883 DEBUG(3,("end of file from client\n"));
4887 if (smb_read_error == READ_ERROR)
4889 DEBUG(3,("receive_smb error (%s) exiting\n",
4896 /* become root again if waiting */
4899 /* check for smb.conf reload */
4900 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4902 service_load_counter = counter;
4904 /* reload services, if files have changed. */
4905 reload_services(True);
4908 /* automatic timeout if all connections are closed */
4909 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4911 DEBUG(2,("%s Closing idle connection\n",timestring()));
4915 if (keepalive && (counter-last_keepalive)>keepalive)
4917 struct cli_state *cli = server_client();
4918 if (!send_keepalive(Client)) {
4919 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4922 /* also send a keepalive to the password server if its still
4924 if (cli && cli->initialised)
4925 send_keepalive(cli->fd);
4926 last_keepalive = counter;
4929 /* check for connection timeouts */
4930 for (i=0;i<MAX_CONNECTIONS;i++)
4931 if (Connections[i].open)
4933 /* close dirptrs on connections that are idle */
4934 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4937 if (Connections[i].num_files_open > 0 ||
4938 (t-Connections[i].lastused)<deadtime)
4942 if (allidle && num_connections_open>0)
4944 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4950 process_smb(InBuffer, OutBuffer);
4952 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4957 /****************************************************************************
4958 initialise connect, service and file structs
4959 ****************************************************************************/
4960 static void init_structs(void )
4963 get_myname(myhostname,NULL);
4966 * Set the machine NETBIOS name if not already
4967 * set from the config file.
4970 if (!*global_myname)
4973 fstrcpy( global_myname, myhostname );
4974 p = strchr( global_myname, '.' );
4978 strupper( global_myname );
4980 for (i=0;i<MAX_CONNECTIONS;i++)
4982 Connections[i].open = False;
4983 Connections[i].num_files_open=0;
4984 Connections[i].lastused=0;
4985 Connections[i].used=False;
4986 string_init(&Connections[i].user,"");
4987 string_init(&Connections[i].dirpath,"");
4988 string_init(&Connections[i].connectpath,"");
4989 string_init(&Connections[i].origpath,"");
4992 for (i=0;i<MAX_OPEN_FILES;i++)
4994 Files[i].open = False;
4995 string_init(&Files[i].name,"");
4998 for (i=0;i<MAX_OPEN_FILES;i++)
5000 file_fd_struct *fd_ptr = &FileFd[i];
5001 fd_ptr->ref_count = 0;
5002 fd_ptr->dev = (int32)-1;
5003 fd_ptr->inode = (int32)-1;
5005 fd_ptr->fd_readonly = -1;
5006 fd_ptr->fd_writeonly = -1;
5007 fd_ptr->real_open_flags = -1;
5011 init_rpc_pipe_hnd();
5013 /* for LSA handles */
5014 init_lsa_policy_hnd();
5019 /****************************************************************************
5020 usage on the program
5021 ****************************************************************************/
5022 static void usage(char *pname)
5024 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5026 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5027 printf("Version %s\n",VERSION);
5028 printf("\t-D become a daemon\n");
5029 printf("\t-p port listen on the specified port\n");
5030 printf("\t-d debuglevel set the debuglevel\n");
5031 printf("\t-l log basename. Basename for log/debug files\n");
5032 printf("\t-s services file. Filename of services file\n");
5033 printf("\t-P passive only\n");
5034 printf("\t-a overwrite log file, don't append\n");
5039 /****************************************************************************
5041 ****************************************************************************/
5042 int main(int argc,char *argv[])
5044 extern BOOL append_log;
5045 /* shall I run as a daemon */
5046 BOOL is_daemon = False;
5047 int port = SMB_PORT;
5049 extern char *optarg;
5051 #ifdef NEED_AUTH_PARAMETERS
5052 set_auth_parameters(argc,argv);
5063 strcpy(debugf,SMBLOGFILE);
5065 strcpy(remote_machine, "smb");
5067 setup_logging(argv[0],False);
5069 charset_initialise();
5071 /* make absolutely sure we run as root - to handle cases where people
5072 are crazy enough to have it setuid */
5082 fault_setup((void (*)(void *))exit_server);
5083 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5085 /* we want total control over the permissions on created files,
5086 so set our umask to 0 */
5093 /* this is for people who can't start the program correctly */
5094 while (argc > 1 && (*argv[1] != '-'))
5100 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5104 strcpy(user_socket_options,optarg);
5107 strcpy(scope,optarg);
5111 extern BOOL passive;
5116 strcpy(servicesf,optarg);
5119 strcpy(debugf,optarg);
5123 extern BOOL append_log;
5124 append_log = !append_log;
5134 DEBUGLEVEL = atoi(optarg);
5137 port = atoi(optarg);
5150 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5151 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5153 #ifndef NO_GETRLIMIT
5154 #ifdef RLIMIT_NOFILE
5157 getrlimit(RLIMIT_NOFILE, &rlp);
5159 * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5160 * extra fd we need to read directories, as well as the log files
5161 * and standard handles etc.
5163 rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5164 setrlimit(RLIMIT_NOFILE, &rlp);
5165 getrlimit(RLIMIT_NOFILE, &rlp);
5166 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5172 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5173 getuid(),getgid(),geteuid(),getegid()));
5175 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5177 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5183 if (!reload_services(False))
5186 codepage_initialise(lp_client_code_page());
5188 strcpy(global_myworkgroup, lp_workgroup());
5190 #ifndef NO_SIGNAL_TEST
5191 signal(SIGHUP,SIGNAL_CAST sig_hup);
5194 /* Setup the signals that allow the debug log level
5195 to by dynamically changed. */
5197 /* If we are using the malloc debug code we can't use
5198 SIGUSR1 and SIGUSR2 to do debug level changes. */
5201 #if defined(SIGUSR1)
5202 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5203 #endif /* SIGUSR1 */
5205 #if defined(SIGUSR2)
5206 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5207 #endif /* SIGUSR2 */
5208 #endif /* MEM_MAN */
5210 DEBUG(3,("%s loaded services\n",timestring()));
5212 if (!is_daemon && !is_a_socket(0))
5214 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5220 DEBUG(3,("%s becoming a daemon\n",timestring()));
5224 if (!directory_exist(lp_lockdir(), NULL)) {
5225 mkdir(lp_lockdir(), 0755);
5229 pidfile_create("smbd");
5232 if (!open_sockets(is_daemon,port))
5235 if (!locking_init(0))
5238 /* possibly reload the services file. */
5239 reload_services(True);
5241 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5245 if (sys_chroot(lp_rootdir()) == 0)
5246 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5249 /* Setup the oplock IPC socket. */
5250 if(!open_oplock_ipc())
5256 exit_server("normal exit");