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 myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 time_t smb_last_time=(time_t)0;
53 extern int smb_read_error;
55 extern pstring user_socket_options;
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
70 * Size of data we can send to client. Set
71 * by the client for all protocols above CORE.
72 * Set by us for CORE protocol.
74 int max_send = BUFFER_SIZE;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv = BUFFER_SIZE;
81 /* a fnum to use when chaining */
84 /* number of open connections */
85 static int num_connections_open = 0;
87 /* Oplock ipc UDP socket. */
89 uint16 oplock_port = 0;
90 /* Current number of oplocks we have outstanding. */
91 int32 global_oplocks_open = 0;
93 BOOL global_oplock_break = False;
95 extern fstring remote_machine;
97 extern pstring OriginalDir;
99 /* these can be set by some functions to override the error codes */
100 int unix_ERR_class=SUCCESS;
104 extern int extra_time_offset;
106 extern pstring myhostname;
108 static int find_free_connection(int hash);
110 /* for readability... */
111 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
112 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
113 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
114 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
115 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
117 /****************************************************************************
118 when exiting, take the whole family
119 ****************************************************************************/
122 exit_server("caught signal");
123 return 0; /* Keep -Wall happy :-) */
125 /****************************************************************************
126 Send a SIGTERM to our process group.
127 *****************************************************************************/
130 if(am_parent) kill(0,SIGTERM);
133 /****************************************************************************
134 change a dos mode to a unix mode
135 base permission for files:
136 everybody gets read bit set
137 dos readonly is represented in unix by removing everyone's write bit
138 dos archive is represented in unix by the user's execute bit
139 dos system is represented in unix by the group's execute bit
140 dos hidden is represented in unix by the other's execute bit
141 Then apply create mask,
143 base permission for directories:
144 dos directory is represented in unix by unix's dir bit and the exec bit
145 Then apply create mask,
147 ****************************************************************************/
148 mode_t unix_mode(int cnum,int dosmode)
150 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
152 if ( !IS_DOS_READONLY(dosmode) )
153 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
155 if (IS_DOS_DIR(dosmode)) {
156 /* We never make directories read only for the owner as under DOS a user
157 can always create a file in a read-only directory. */
158 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
159 /* Apply directory mask */
160 result &= lp_dir_mode(SNUM(cnum));
161 /* Add in force bits */
162 result |= lp_force_dir_mode(SNUM(cnum));
164 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
167 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
170 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
173 /* Apply mode mask */
174 result &= lp_create_mode(SNUM(cnum));
175 /* Add in force bits */
176 result |= lp_force_create_mode(SNUM(cnum));
182 /****************************************************************************
183 change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
188 extern struct current_user current_user;
190 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
192 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
193 if (!((sbuf->st_mode & S_IWOTH) ||
194 Connections[cnum].admin_user ||
195 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
196 ((sbuf->st_mode & S_IWGRP) &&
197 in_group(sbuf->st_gid,current_user.gid,
198 current_user.ngroups,current_user.igroups))))
201 if ((sbuf->st_mode & S_IWUSR) == 0)
205 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
208 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
211 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
214 if (S_ISDIR(sbuf->st_mode))
215 result = aDIR | (result & aRONLY);
219 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
224 /* hide files with a name starting with a . */
225 if (lp_hide_dot_files(SNUM(cnum)))
227 char *p = strrchr(path,'/');
233 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
237 /* Optimization : Only call is_hidden_path if it's not already
239 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
244 DEBUG(8,("dos_mode returning "));
246 if (result & aHIDDEN) DEBUG(8, ("h"));
247 if (result & aRONLY ) DEBUG(8, ("r"));
248 if (result & aSYSTEM) DEBUG(8, ("s"));
249 if (result & aDIR ) DEBUG(8, ("d"));
250 if (result & aARCH ) DEBUG(8, ("a"));
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
269 if (sys_stat(fname,st)) return(-1);
272 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
274 if (dos_mode(cnum,fname,st) == dosmode) return(0);
276 unixmode = unix_mode(cnum,dosmode);
278 /* preserve the s bits */
279 mask |= (S_ISUID | S_ISGID);
281 /* preserve the t bit */
286 /* possibly preserve the x bits */
287 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
288 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
289 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
291 unixmode |= (st->st_mode & mask);
293 /* if we previously had any r bits set then leave them alone */
294 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
295 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
299 /* if we previously had any w bits set then leave them alone
300 if the new mode is not rdonly */
301 if (!IS_DOS_READONLY(dosmode) &&
302 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
303 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
307 return(sys_chmod(fname,unixmode));
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
313 *******************************************************************/
315 int file_utime(int cnum, char *fname, struct utimbuf *times)
317 extern struct current_user current_user;
323 if(sys_utime(fname, times) == 0)
326 if((errno != EPERM) && (errno != EACCES))
329 if(!lp_dos_filetimes(SNUM(cnum)))
332 /* We have permission (given by the Samba admin) to
333 break POSIX semantics and allow a user to change
334 the time on a file they don't own but can write to
338 if(sys_stat(fname,&sb) != 0)
341 /* Check if we have write access. */
342 if (CAN_WRITE(cnum)) {
343 if (((sb.st_mode & S_IWOTH) ||
344 Connections[cnum].admin_user ||
345 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
346 ((sb.st_mode & S_IWGRP) &&
347 in_group(sb.st_gid,current_user.gid,
348 current_user.ngroups,current_user.igroups)))) {
349 /* We are allowed to become root and change the filetime. */
351 ret = sys_utime(fname, times);
352 unbecome_root(False);
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
363 BOOL set_filetime(int cnum, char *fname, time_t mtime)
365 struct utimbuf times;
367 if (null_mtime(mtime)) return(True);
369 times.modtime = times.actime = mtime;
371 if (file_utime(cnum, fname, ×)) {
372 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
378 /****************************************************************************
379 check if two filenames are equal
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL fname_equal(char *name1, char *name2)
385 int l1 = strlen(name1);
386 int l2 = strlen(name2);
388 /* handle filenames ending in a single dot */
389 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
393 ret = fname_equal(name1,name2);
398 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
402 ret = fname_equal(name1,name2);
407 /* now normal filename handling */
409 return(strcmp(name1,name2) == 0);
411 return(strequal(name1,name2));
415 /****************************************************************************
416 mangle the 2nd name and check if it is then equal to the first name
417 ****************************************************************************/
418 static BOOL mangled_equal(char *name1, char *name2)
422 if (is_8_3(name2, True))
425 strcpy(tmpname,name2);
426 mangle_name_83(tmpname);
428 return(strequal(name1,tmpname));
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
435 If the name looks like a mangled name then try via the mangling functions
436 ****************************************************************************/
437 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
444 mangled = is_mangled(name);
446 /* handle null paths */
450 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
457 * This code I believe is incorrect - and commenting it out
458 * is the correct fix for the bug mentioned below in the
459 * comment 'name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra)'.
460 * The incoming name can be mangled, and if we de-mangle it
461 * here it will not compare correctly against the filename (name2)
462 * read from the directory and then mangled by the name_map_mangle()
463 * call. We need to mangle both names or neither.
467 check_mangled_stack(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)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
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_stack(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()
1067 file_fd_struct *fd_ptr;
1069 for(i = 0; i < MAX_OPEN_FILES; i++) {
1070 fd_ptr = &FileFd[i];
1071 if(fd_ptr->ref_count == 0) {
1072 fd_ptr->dev = (uint32)-1;
1073 fd_ptr->inode = (uint32)-1;
1075 fd_ptr->fd_readonly = -1;
1076 fd_ptr->fd_writeonly = -1;
1077 fd_ptr->real_open_flags = -1;
1078 fd_ptr->ref_count++;
1079 /* Increment max used counter if neccessary, cuts down
1080 on search time when re-using */
1081 if(i > max_file_fd_used)
1082 max_file_fd_used = i;
1083 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1084 i, fd_ptr->dev, fd_ptr->inode));
1088 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1093 /****************************************************************************
1094 fd support routines - attempt to re-open an already open fd as O_RDWR.
1095 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1096 ****************************************************************************/
1097 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1099 int fd = sys_open( fname, O_RDWR, mode);
1104 if(fd_ptr->real_open_flags == O_RDONLY)
1105 fd_ptr->fd_readonly = fd_ptr->fd;
1106 if(fd_ptr->real_open_flags == O_WRONLY)
1107 fd_ptr->fd_writeonly = fd_ptr->fd;
1110 fd_ptr->real_open_flags = O_RDWR;
1113 /****************************************************************************
1114 fd support routines - attempt to close the file referenced by this fd.
1115 Decrements the ref_count and returns it.
1116 ****************************************************************************/
1117 static int fd_attempt_close(file_fd_struct *fd_ptr)
1119 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1120 fd_ptr - &FileFd[0],
1121 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1122 fd_ptr->real_open_flags,
1123 fd_ptr->ref_count));
1124 if(fd_ptr->ref_count > 0) {
1125 fd_ptr->ref_count--;
1126 if(fd_ptr->ref_count == 0) {
1127 if(fd_ptr->fd != -1)
1129 if(fd_ptr->fd_readonly != -1)
1130 close(fd_ptr->fd_readonly);
1131 if(fd_ptr->fd_writeonly != -1)
1132 close(fd_ptr->fd_writeonly);
1134 fd_ptr->fd_readonly = -1;
1135 fd_ptr->fd_writeonly = -1;
1136 fd_ptr->real_open_flags = -1;
1137 fd_ptr->dev = (uint32)-1;
1138 fd_ptr->inode = (uint32)-1;
1141 return fd_ptr->ref_count;
1144 /****************************************************************************
1146 ****************************************************************************/
1147 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1149 extern struct current_user current_user;
1151 struct stat statbuf;
1152 file_fd_struct *fd_ptr;
1153 files_struct *fsp = &Files[fnum];
1154 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1158 fsp->granted_oplock = False;
1161 pstrcpy(fname,fname1);
1163 /* check permissions */
1166 * This code was changed after seeing a client open request
1167 * containing the open mode of (DENY_WRITE/read-only) with
1168 * the 'create if not exist' bit set. The previous code
1169 * would fail to open the file read only on a read-only share
1170 * as it was checking the flags parameter directly against O_RDONLY,
1171 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1175 if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1176 /* It's a read-only share - fail if we wanted to write. */
1177 if(accmode != O_RDONLY) {
1178 DEBUG(3,("Permission denied opening %s\n",fname));
1179 check_for_pipe(fname);
1182 else if(flags & O_CREAT) {
1183 /* We don't want to write - but we must make sure that O_CREAT
1184 doesn't create the file if we have write access into the
1191 /* this handles a bug in Win95 - it doesn't say to create the file when it
1193 if (Connections[cnum].printer)
1197 if (flags == O_WRONLY)
1198 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1202 * Ensure we have a valid struct stat so we can search the
1206 if(stat(fname, &statbuf) < 0) {
1207 if(errno != ENOENT) {
1208 DEBUG(3,("Error doing stat on file %s (%s)\n",
1209 fname,strerror(errno)));
1211 check_for_pipe(fname);
1221 * Check to see if we have this file already
1222 * open. If we do, just use the already open fd and increment the
1223 * reference count (fd_get_already_open increments the ref_count).
1225 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1227 /* File was already open. */
1228 if((flags & O_CREAT) && (flags & O_EXCL)) {
1229 fd_ptr->ref_count--;
1235 * If not opened O_RDWR try
1236 * and do that here - a chmod may have been done
1237 * between the last open and now.
1239 if(fd_ptr->real_open_flags != O_RDWR)
1240 fd_attempt_reopen(fname, mode, fd_ptr);
1243 * Ensure that if we wanted write access
1244 * it has been opened for write, and if we wanted read it
1245 * was open for read.
1247 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1248 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1249 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1250 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1251 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1252 check_for_pipe(fname);
1253 fd_ptr->ref_count--;
1259 /* We need to allocate a new file_fd_struct (this increments the
1261 if((fd_ptr = fd_get_new()) == 0)
1264 * Whatever the requested flags, attempt read/write access,
1265 * as we don't know what flags future file opens may require.
1266 * If this fails, try again with the required flags.
1267 * Even if we open read/write when only read access was
1268 * requested the setting of the can_write flag in
1269 * the file_struct will protect us from errant
1270 * write requests. We never need to worry about O_APPEND
1271 * as this is not set anywhere in Samba.
1273 fd_ptr->real_open_flags = O_RDWR;
1274 /* Set the flags as needed without the read/write modes. */
1275 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1276 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1278 * On some systems opening a file for R/W access on a read only
1279 * filesystems sets errno to EROFS.
1282 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1283 #else /* No EROFS */
1284 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1286 if(flags & O_WRONLY) {
1287 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1288 fd_ptr->real_open_flags = O_WRONLY;
1290 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1291 fd_ptr->real_open_flags = O_RDONLY;
1296 if ((fd_ptr->fd >=0) &&
1297 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1301 pstrcpy(dname,fname);
1302 p = strrchr(dname,'/');
1304 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1305 lp_minprintspace(SNUM(cnum))) {
1306 fd_attempt_close(fd_ptr);
1308 if(fd_ptr->ref_count == 0)
1317 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1318 fname,strerror(errno),flags));
1319 /* Ensure the ref_count is decremented. */
1320 fd_attempt_close(fd_ptr);
1321 check_for_pipe(fname);
1325 if (fd_ptr->fd >= 0)
1329 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1330 /* Error - backout !! */
1331 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1332 fd_ptr->fd, fname,strerror(errno)));
1333 /* Ensure the ref_count is decremented. */
1334 fd_attempt_close(fd_ptr);
1339 /* Set the correct entries in fd_ptr. */
1340 fd_ptr->dev = (uint32)sbuf->st_dev;
1341 fd_ptr->inode = (uint32)sbuf->st_ino;
1343 fsp->fd_ptr = fd_ptr;
1344 Connections[cnum].num_files_open++;
1345 fsp->mode = sbuf->st_mode;
1346 GetTimeOfDay(&fsp->open_time);
1347 fsp->uid = current_user.id;
1351 fsp->mmap_ptr = NULL;
1353 fsp->can_lock = True;
1354 fsp->can_read = ((flags & O_WRONLY)==0);
1355 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1356 fsp->share_mode = 0;
1357 fsp->print_file = Connections[cnum].printer;
1358 fsp->modified = False;
1359 fsp->granted_oplock = False;
1360 fsp->sent_oplock_break = False;
1362 string_set(&fsp->name,dos_to_unix(fname,False));
1363 fsp->wbmpx_ptr = NULL;
1366 * If the printer is marked as postscript output a leading
1367 * file identifier to ensure the file is treated as a raw
1369 * This has a similar effect as CtrlD=0 in WIN.INI file.
1370 * tim@fsg.com 09/06/94
1372 if (fsp->print_file && POSTSCRIPT(cnum) &&
1375 DEBUG(3,("Writing postscript line\n"));
1376 write_file(fnum,"%!\n",3);
1379 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1380 timestring(),Connections[cnum].user,fname,
1381 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1382 Connections[cnum].num_files_open,fnum));
1387 /* mmap it if read-only */
1388 if (!fsp->can_write)
1390 fsp->mmap_size = file_size(fname);
1391 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1392 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1394 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1396 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1397 fsp->mmap_ptr = NULL;
1403 /*******************************************************************
1405 ********************************************************************/
1406 void sync_file(int fnum)
1409 fsync(Files[fnum].fd_ptr->fd);
1413 /****************************************************************************
1414 run a file if it is a magic script
1415 ****************************************************************************/
1416 static void check_magic(int fnum,int cnum)
1418 if (!*lp_magicscript(SNUM(cnum)))
1421 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1425 if (!(p = strrchr(Files[fnum].name,'/')))
1426 p = Files[fnum].name;
1430 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1436 pstring magic_output;
1438 pstrcpy(fname,Files[fnum].name);
1440 if (*lp_magicoutput(SNUM(cnum)))
1441 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1443 sprintf(magic_output,"%s.out",fname);
1446 ret = smbrun(fname,magic_output,False);
1447 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1453 /****************************************************************************
1454 close a file - possibly invalidating the read prediction
1456 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1457 operation otherwise it came as the result of some other operation such as
1458 the closing of the connection. In the latter case printing and
1459 magic scripts are not run
1460 ****************************************************************************/
1461 void close_file(int fnum, BOOL normal_close)
1463 files_struct *fs_p = &Files[fnum];
1464 int cnum = fs_p->cnum;
1465 uint32 dev = fs_p->fd_ptr->dev;
1466 uint32 inode = fs_p->fd_ptr->inode;
1469 Files[fnum].reserved = False;
1471 #if USE_READ_PREDICTION
1472 invalidate_read_prediction(fs_p->fd_ptr->fd);
1476 Connections[cnum].num_files_open--;
1479 free((char *)fs_p->wbmpx_ptr);
1480 fs_p->wbmpx_ptr = NULL;
1486 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1487 fs_p->mmap_ptr = NULL;
1491 if (lp_share_modes(SNUM(cnum)))
1493 lock_share_entry( cnum, dev, inode, &token);
1494 del_share_mode(token, fnum);
1497 fd_attempt_close(fs_p->fd_ptr);
1499 if (lp_share_modes(SNUM(cnum)))
1500 unlock_share_entry( cnum, dev, inode, token);
1502 /* NT uses smbclose to start a print - weird */
1503 if (normal_close && fs_p->print_file)
1506 /* check for magic scripts */
1508 check_magic(fnum,cnum);
1510 if(fs_p->granted_oplock == True)
1511 global_oplocks_open--;
1513 fs_p->sent_oplock_break = False;
1515 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1516 timestring(),Connections[cnum].user,fs_p->name,
1517 Connections[cnum].num_files_open));
1520 enum {AFAIL,AREAD,AWRITE,AALL};
1522 /*******************************************************************
1523 reproduce the share mode access table
1524 ********************************************************************/
1525 static int access_table(int new_deny,int old_deny,int old_mode,
1526 int share_pid,char *fname)
1528 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1530 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1532 if (old_deny == new_deny && share_pid == pid)
1535 if (old_mode == 0) return(AREAD);
1537 /* the new smbpub.zip spec says that if the file extension is
1538 .com, .dll, .exe or .sym then allow the open. I will force
1539 it to read-only as this seems sensible although the spec is
1540 a little unclear on this. */
1541 if ((fname = strrchr(fname,'.'))) {
1542 if (strequal(fname,".com") ||
1543 strequal(fname,".dll") ||
1544 strequal(fname,".exe") ||
1545 strequal(fname,".sym"))
1555 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1556 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1557 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1560 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1561 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1562 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1565 if (old_deny==DENY_WRITE) return(AREAD);
1566 if (old_deny==DENY_READ) return(AWRITE);
1567 if (old_deny==DENY_NONE) return(AALL);
1573 /*******************************************************************
1574 check if the share mode on a file allows it to be deleted or unlinked
1575 return True if sharing doesn't prevent the operation
1576 ********************************************************************/
1577 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1581 share_mode_entry *old_shares = 0;
1582 int num_share_modes;
1588 if(!lp_share_modes(SNUM(cnum)))
1591 if (stat(fname,&sbuf) == -1) return(True);
1593 dev = (uint32)sbuf.st_dev;
1594 inode = (uint32)sbuf.st_ino;
1596 lock_share_entry(cnum, dev, inode, &token);
1597 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1600 * Check if the share modes will give us access.
1603 if(num_share_modes != 0)
1610 broke_oplock = False;
1611 for(i = 0; i < num_share_modes; i++)
1613 share_mode_entry *share_entry = &old_shares[i];
1616 * Break oplocks before checking share modes. See comment in
1617 * open_file_shared for details.
1618 * Check if someone has an oplock on this file. If so we must
1619 * break it before continuing.
1621 if(share_entry->op_type & BATCH_OPLOCK)
1625 * It appears that the NT redirector may have a bug, in that
1626 * it tries to do an SMBmv on a file that it has open with a
1627 * batch oplock, and then fails to respond to the oplock break
1628 * request. This only seems to occur when the client is doing an
1629 * SMBmv to the smbd it is using - thus we try and detect this
1630 * condition by checking if the file being moved is open and oplocked by
1631 * this smbd process, and then not sending the oplock break in this
1632 * special case. If the file was open with a deny mode that
1633 * prevents the move the SMBmv will fail anyway with a share
1634 * violation error. JRA.
1636 if(rename_op && (share_entry->pid == pid))
1638 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1639 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1642 * This next line is a test that allows the deny-mode
1643 * processing to be skipped. JRA.
1650 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1651 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1653 /* Oplock break.... */
1654 unlock_share_entry(cnum, dev, inode, token);
1655 if(request_oplock_break(share_entry, dev, inode) == False)
1657 free((char *)old_shares);
1658 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1659 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1662 lock_share_entry(cnum, dev, inode, &token);
1663 broke_oplock = True;
1668 /* someone else has a share lock on it, check to see
1670 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1677 free((char *)old_shares);
1678 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1680 } while(broke_oplock);
1683 /* XXXX exactly what share mode combinations should be allowed for
1684 deleting/renaming? */
1685 /* If we got here then either there were no share modes or
1686 all share modes were DENY_DOS and the pid == getpid() */
1691 unlock_share_entry(cnum, dev, inode, token);
1692 if(old_shares != NULL)
1693 free((char *)old_shares);
1697 /****************************************************************************
1699 Helper for open_file_shared.
1700 Truncate a file after checking locking; close file if locked.
1701 **************************************************************************/
1702 static void truncate_unless_locked(int fnum, int cnum, int token,
1705 if (Files[fnum].can_write){
1706 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1707 /* If share modes are in force for this connection we
1708 have the share entry locked. Unlock it before closing. */
1709 if (*share_locked && lp_share_modes(SNUM(cnum)))
1710 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1711 Files[fnum].fd_ptr->inode, token);
1712 close_file(fnum,False);
1713 /* Share mode no longer locked. */
1714 *share_locked = False;
1716 unix_ERR_class = ERRDOS;
1717 unix_ERR_code = ERRlock;
1720 ftruncate(Files[fnum].fd_ptr->fd,0);
1724 /****************************************************************************
1725 check if we can open a file with a share mode
1726 ****************************************************************************/
1727 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1728 BOOL fcbopen, int *flags)
1730 int old_open_mode = share->share_mode &0xF;
1731 int old_deny_mode = (share->share_mode >>4)&7;
1733 if (old_deny_mode > 4 || old_open_mode > 2)
1735 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1736 deny_mode,old_deny_mode,old_open_mode,fname));
1741 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1744 if ((access_allowed == AFAIL) ||
1745 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1746 (access_allowed == AREAD && *flags == O_WRONLY) ||
1747 (access_allowed == AWRITE && *flags == O_RDONLY))
1749 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1750 deny_mode,old_deny_mode,old_open_mode,
1751 share->pid,fname, fcbopen, *flags, access_allowed));
1755 if (access_allowed == AREAD)
1758 if (access_allowed == AWRITE)
1765 /****************************************************************************
1766 open a file with a share mode
1767 ****************************************************************************/
1768 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1769 int mode,int oplock_request, int *Access,int *action)
1771 files_struct *fs_p = &Files[fnum];
1774 int deny_mode = (share_mode>>4)&7;
1776 BOOL file_existed = file_exist(fname,&sbuf);
1777 BOOL share_locked = False;
1778 BOOL fcbopen = False;
1782 int num_share_modes = 0;
1787 /* this is for OS/2 EAs - try and say we don't support them */
1788 if (strstr(fname,".+,;=[]."))
1790 unix_ERR_class = ERRDOS;
1791 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1793 unix_ERR_code = ERRcannotopen;
1794 #else /* OS2_WPS_FIX */
1795 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1796 #endif /* OS2_WPS_FIX */
1801 if ((ofun & 0x3) == 0 && file_existed)
1809 if ((ofun & 0x3) == 2)
1812 /* note that we ignore the append flag as
1813 append does not mean the same thing under dos and unix */
1815 switch (share_mode&0xF)
1832 if (flags != O_RDONLY && file_existed &&
1833 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1843 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1845 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1850 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1852 if (lp_share_modes(SNUM(cnum)))
1855 share_mode_entry *old_shares = 0;
1859 dev = (uint32)sbuf.st_dev;
1860 inode = (uint32)sbuf.st_ino;
1861 lock_share_entry(cnum, dev, inode, &token);
1862 share_locked = True;
1863 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1867 * Check if the share modes will give us access.
1870 if(share_locked && (num_share_modes != 0))
1877 broke_oplock = False;
1878 for(i = 0; i < num_share_modes; i++)
1880 share_mode_entry *share_entry = &old_shares[i];
1883 * By observation of NetBench, oplocks are broken *before* share
1884 * modes are checked. This allows a file to be closed by the client
1885 * if the share mode would deny access and the client has an oplock.
1886 * Check if someone has an oplock on this file. If so we must break
1887 * it before continuing.
1889 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1892 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1893 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1895 /* Oplock break.... */
1896 unlock_share_entry(cnum, dev, inode, token);
1897 if(request_oplock_break(share_entry, dev, inode) == False)
1899 free((char *)old_shares);
1900 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1901 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1903 unix_ERR_class = ERRDOS;
1904 unix_ERR_code = ERRbadshare;
1907 lock_share_entry(cnum, dev, inode, &token);
1908 broke_oplock = True;
1912 /* someone else has a share lock on it, check to see
1914 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1916 free((char *)old_shares);
1917 unlock_share_entry(cnum, dev, inode, token);
1919 unix_ERR_class = ERRDOS;
1920 unix_ERR_code = ERRbadshare;
1928 free((char *)old_shares);
1929 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1931 } while(broke_oplock);
1935 free((char *)old_shares);
1938 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1939 flags,flags2,mode));
1941 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1942 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1945 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1952 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1954 /* We created the file - thus we must now lock the share entry before creating it. */
1955 dev = fs_p->fd_ptr->dev;
1956 inode = fs_p->fd_ptr->inode;
1957 lock_share_entry(cnum, dev, inode, &token);
1958 share_locked = True;
1974 fs_p->share_mode = (deny_mode<<4) | open_mode;
1977 (*Access) = open_mode;
1981 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1982 if (!file_existed) *action = 2;
1983 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1985 /* We must create the share mode entry before truncate as
1986 truncate can fail due to locking and have to close the
1987 file (which expects the share_mode_entry to be there).
1989 if (lp_share_modes(SNUM(cnum)))
1992 /* JRA. Currently this only services Exlcusive and batch
1993 oplocks (no other opens on this file). This needs to
1994 be extended to level II oplocks (multiple reader
1997 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
1998 !IS_VETO_OPLOCK_PATH(cnum,fname))
2000 fs_p->granted_oplock = True;
2001 fs_p->sent_oplock_break = False;
2002 global_oplocks_open++;
2005 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2006 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2014 set_share_mode(token, fnum, port, oplock_request);
2017 if ((flags2&O_TRUNC) && file_existed)
2018 truncate_unless_locked(fnum,cnum,token,&share_locked);
2021 if (share_locked && lp_share_modes(SNUM(cnum)))
2022 unlock_share_entry( cnum, dev, inode, token);
2025 /****************************************************************************
2026 seek a file. Try to avoid the seek if possible
2027 ****************************************************************************/
2028 int seek_file(int fnum,uint32 pos)
2031 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2034 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2036 return(Files[fnum].pos);
2039 /****************************************************************************
2041 ****************************************************************************/
2042 int read_file(int fnum,char *data,uint32 pos,int n)
2046 #if USE_READ_PREDICTION
2047 if (!Files[fnum].can_write)
2049 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2058 if (Files[fnum].mmap_ptr)
2060 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
2063 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2075 if (seek_file(fnum,pos) != pos)
2077 DEBUG(3,("Failed to seek to %d\n",pos));
2082 readret = read(Files[fnum].fd_ptr->fd,data,n);
2083 if (readret > 0) ret += readret;
2090 /****************************************************************************
2092 ****************************************************************************/
2093 int write_file(int fnum,char *data,int n)
2095 if (!Files[fnum].can_write) {
2100 if (!Files[fnum].modified) {
2102 Files[fnum].modified = True;
2103 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2104 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2105 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2106 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2111 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2115 /****************************************************************************
2116 load parameters specific to a connection/service
2117 ****************************************************************************/
2118 BOOL become_service(int cnum,BOOL do_chdir)
2120 extern char magic_char;
2121 static int last_cnum = -1;
2124 if (!OPEN_CNUM(cnum))
2130 Connections[cnum].lastused = smb_last_time;
2135 ChDir(Connections[cnum].connectpath) != 0 &&
2136 ChDir(Connections[cnum].origpath) != 0)
2138 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2139 Connections[cnum].connectpath,cnum));
2143 if (cnum == last_cnum)
2148 case_default = lp_defaultcase(snum);
2149 case_preserve = lp_preservecase(snum);
2150 short_case_preserve = lp_shortpreservecase(snum);
2151 case_mangle = lp_casemangle(snum);
2152 case_sensitive = lp_casesensitive(snum);
2153 magic_char = lp_magicchar(snum);
2154 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2159 /****************************************************************************
2160 find a service entry
2161 ****************************************************************************/
2162 int find_service(char *service)
2166 string_sub(service,"\\","/");
2168 iService = lp_servicenumber(service);
2170 /* now handle the special case of a home directory */
2173 char *phome_dir = get_home_dir(service);
2174 DEBUG(3,("checking for home directory %s gave %s\n",service,
2175 phome_dir?phome_dir:"(NULL)"));
2179 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2181 lp_add_home(service,iHomeService,phome_dir);
2182 iService = lp_servicenumber(service);
2187 /* If we still don't have a service, attempt to add it as a printer. */
2190 int iPrinterService;
2192 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2196 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2198 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2200 DEBUG(3,("%s is a valid printer name\n", service));
2201 DEBUG(3,("adding %s as a printer service\n", service));
2202 lp_add_printer(service,iPrinterService);
2203 iService = lp_servicenumber(service);
2205 DEBUG(0,("failed to add %s as a printer service!\n", service));
2208 DEBUG(3,("%s is not a valid printer name\n", service));
2212 /* just possibly it's a default service? */
2215 char *defservice = lp_defaultservice();
2216 if (defservice && *defservice && !strequal(defservice,service)) {
2217 iService = find_service(defservice);
2218 if (iService >= 0) {
2219 string_sub(service,"_","/");
2220 iService = lp_add_service(service,iService);
2226 if (!VALID_SNUM(iService))
2228 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2233 DEBUG(3,("find_service() failed to find service %s\n", service));
2239 /****************************************************************************
2240 create an error packet from a cached error.
2241 ****************************************************************************/
2242 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2244 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2246 int32 eclass = wbmpx->wr_errclass;
2247 int32 err = wbmpx->wr_error;
2249 /* We can now delete the auxiliary struct */
2250 free((char *)wbmpx);
2251 Files[fnum].wbmpx_ptr = NULL;
2252 return error_packet(inbuf,outbuf,eclass,err,line);
2261 } unix_smb_errmap[] =
2263 {EPERM,ERRDOS,ERRnoaccess},
2264 {EACCES,ERRDOS,ERRnoaccess},
2265 {ENOENT,ERRDOS,ERRbadfile},
2266 {ENOTDIR,ERRDOS,ERRbadpath},
2267 {EIO,ERRHRD,ERRgeneral},
2268 {EBADF,ERRSRV,ERRsrverror},
2269 {EINVAL,ERRSRV,ERRsrverror},
2270 {EEXIST,ERRDOS,ERRfilexists},
2271 {ENFILE,ERRDOS,ERRnofids},
2272 {EMFILE,ERRDOS,ERRnofids},
2273 {ENOSPC,ERRHRD,ERRdiskfull},
2275 {EDQUOT,ERRHRD,ERRdiskfull},
2278 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2281 {EXDEV,ERRDOS,ERRdiffdevice},
2283 {EROFS,ERRHRD,ERRnowrite},
2287 /****************************************************************************
2288 create an error packet from errno
2289 ****************************************************************************/
2290 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2292 int eclass=def_class;
2296 if (unix_ERR_class != SUCCESS)
2298 eclass = unix_ERR_class;
2299 ecode = unix_ERR_code;
2300 unix_ERR_class = SUCCESS;
2305 while (unix_smb_errmap[i].smbclass != 0)
2307 if (unix_smb_errmap[i].unixerror == errno)
2309 eclass = unix_smb_errmap[i].smbclass;
2310 ecode = unix_smb_errmap[i].smbcode;
2317 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2321 /****************************************************************************
2322 create an error packet. Normally called using the ERROR() macro
2323 ****************************************************************************/
2324 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2326 int outsize = set_message(outbuf,0,0,True);
2328 cmd = CVAL(inbuf,smb_com);
2330 CVAL(outbuf,smb_rcls) = error_class;
2331 SSVAL(outbuf,smb_err,error_code);
2333 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2336 (int)CVAL(inbuf,smb_com),
2337 smb_fn_name(CVAL(inbuf,smb_com)),
2342 DEBUG(3,("error string = %s\n",strerror(errno)));
2348 #ifndef SIGCLD_IGNORE
2349 /****************************************************************************
2350 this prevents zombie child processes
2351 ****************************************************************************/
2352 static int sig_cld()
2354 static int depth = 0;
2357 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2363 BlockSignals(True,SIGCLD);
2364 DEBUG(5,("got SIGCLD\n"));
2367 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2371 /* Stevens, Adv. Unix Prog. says that on system V you must call
2372 wait before reinstalling the signal handler, because the kernel
2373 calls the handler from within the signal-call when there is a
2374 child that has exited. This would lead to an infinite recursion
2375 if done vice versa. */
2377 #ifndef DONT_REINSTALL_SIG
2378 #ifdef SIGCLD_IGNORE
2379 signal(SIGCLD, SIG_IGN);
2381 signal(SIGCLD, SIGNAL_CAST sig_cld);
2386 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2389 BlockSignals(False,SIGCLD);
2394 /****************************************************************************
2395 this is called when the client exits abruptly
2396 **************************************************************************/
2397 static int sig_pipe()
2399 struct cli_state *cli;
2400 BlockSignals(True,SIGPIPE);
2402 if ((cli = server_client()) && cli->initialised) {
2403 DEBUG(3,("lost connection to password server\n"));
2405 #ifndef DONT_REINSTALL_SIG
2406 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2408 BlockSignals(False,SIGPIPE);
2412 exit_server("Got sigpipe\n");
2416 /****************************************************************************
2417 open the socket communication
2418 ****************************************************************************/
2419 static BOOL open_sockets(BOOL is_daemon,int port)
2425 int num_interfaces = iface_count();
2426 int fd_listenset[FD_SETSIZE];
2432 #ifdef SIGCLD_IGNORE
2433 signal(SIGCLD, SIG_IGN);
2435 signal(SIGCLD, SIGNAL_CAST sig_cld);
2441 FD_ZERO(&listen_set);
2443 if(lp_interfaces() && lp_bind_interfaces_only())
2445 /* We have been given an interfaces line, and been
2446 told to only bind to those interfaces. Create a
2447 socket per interface and bind to only these.
2450 if(num_interfaces > FD_SETSIZE)
2452 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2453 max can be %d\n", num_interfaces, FD_SETSIZE));
2457 /* Now open a listen socket for each of the interfaces. */
2458 for(i = 0; i < num_interfaces; i++)
2460 struct in_addr *ifip = iface_n_ip(i);
2464 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2467 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2470 /* ready to listen */
2471 if (listen(s, 5) == -1)
2473 DEBUG(0,("listen: %s\n",strerror(errno)));
2477 FD_SET(s,&listen_set);
2482 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2485 /* open an incoming socket */
2486 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2490 /* ready to listen */
2491 if (listen(s, 5) == -1)
2493 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2498 fd_listenset[0] = s;
2499 FD_SET(s,&listen_set);
2502 /* now accept incoming connections - forking a new process
2503 for each incoming connection */
2504 DEBUG(2,("waiting for a connection\n"));
2510 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2512 num = sys_select(&lfds,NULL);
2514 if (num == -1 && errno == EINTR)
2517 /* Find the sockets that are read-ready - accept on these. */
2518 for( ; num > 0; num--)
2520 struct sockaddr addr;
2521 int in_addrlen = sizeof(addr);
2524 for(i = 0; i < num_interfaces; i++)
2526 if(FD_ISSET(fd_listenset[i],&lfds))
2528 s = fd_listenset[i];
2529 /* Clear this so we don't look at it again. */
2530 FD_CLR(fd_listenset[i],&lfds);
2535 Client = accept(s,&addr,&in_addrlen);
2537 if (Client == -1 && errno == EINTR)
2542 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2546 #ifdef NO_FORK_DEBUG
2547 #ifndef NO_SIGNAL_TEST
2548 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2549 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2550 #endif /* NO_SIGNAL_TEST */
2552 #else /* NO_FORK_DEBUG */
2553 if (Client != -1 && fork()==0)
2555 /* Child code ... */
2557 #ifndef NO_SIGNAL_TEST
2558 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2559 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2560 #endif /* NO_SIGNAL_TEST */
2561 /* close the listening socket(s) */
2562 for(i = 0; i < num_interfaces; i++)
2563 close(fd_listenset[i]);
2565 /* close our standard file descriptors */
2569 set_socket_options(Client,"SO_KEEPALIVE");
2570 set_socket_options(Client,user_socket_options);
2572 /* Reset global variables in util.c so that
2573 client substitutions will be done correctly
2576 reset_globals_after_fork();
2579 close(Client); /* The parent doesn't need this socket */
2580 #endif /* NO_FORK_DEBUG */
2583 } /* end if is_daemon */
2586 /* Started from inetd. fd 0 is the socket. */
2587 /* We will abort gracefully when the client or remote system
2589 #ifndef NO_SIGNAL_TEST
2590 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2594 /* close our standard file descriptors */
2597 set_socket_options(Client,"SO_KEEPALIVE");
2598 set_socket_options(Client,user_socket_options);
2604 /****************************************************************************
2605 process an smb from the client - split out from the process() code so
2606 it can be used by the oplock break code.
2607 ****************************************************************************/
2609 static void process_smb(char *inbuf, char *outbuf)
2612 static int trans_num;
2613 int msg_type = CVAL(inbuf,0);
2614 int32 len = smb_len(inbuf);
2615 int nread = len + 4;
2617 if (trans_num == 0) {
2618 /* on the first packet, check the global hosts allow/ hosts
2619 deny parameters before doing any parsing of the packet
2620 passed to us by the client. This prevents attacks on our
2621 parsing code from hosts not in the hosts allow list */
2622 if (!check_access(-1)) {
2623 /* send a negative session response "not listining on calling
2625 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2626 DEBUG(1,("%s Connection denied from %s\n",
2627 timestring(),client_addr()));
2628 send_smb(Client,(char *)buf);
2629 exit_server("connection denied");
2633 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2634 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2637 if(trans_num == 1 && VT_Check(inbuf))
2646 else if(msg_type == 0x85)
2647 return; /* Keepalive packet. */
2649 nread = construct_reply(inbuf,outbuf,nread,max_send);
2653 if (CVAL(outbuf,0) == 0)
2656 if (nread != smb_len(outbuf) + 4)
2658 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2659 nread, smb_len(outbuf)));
2662 send_smb(Client,outbuf);
2667 /****************************************************************************
2668 open the oplock IPC socket communication
2669 ****************************************************************************/
2670 static BOOL open_oplock_ipc()
2672 struct sockaddr_in sock_name;
2673 int len = sizeof(sock_name);
2675 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2677 /* Open a lookback UDP socket on a random port. */
2678 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2679 if (oplock_sock == -1)
2681 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2682 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2687 /* Find out the transient UDP port we have been allocated. */
2688 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2690 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2697 oplock_port = ntohs(sock_name.sin_port);
2699 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2700 getpid(), oplock_port));
2705 /****************************************************************************
2706 process an oplock break message.
2707 ****************************************************************************/
2708 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2714 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2715 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2717 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2719 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2720 msg_len, from_port));
2722 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2723 only valid request. */
2725 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2727 case OPLOCK_BREAK_CMD:
2728 /* Ensure that the msg length is correct. */
2729 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2731 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2732 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2736 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2737 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2738 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2739 struct timeval tval;
2740 struct sockaddr_in toaddr;
2742 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2743 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2745 DEBUG(5,("process_local_message: oplock break request from \
2746 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2749 * If we have no record of any currently open oplocks,
2750 * it's not an error, as a close command may have
2751 * just been issued on the file that was oplocked.
2752 * Just return success in this case.
2755 if(global_oplocks_open != 0)
2757 if(oplock_break(dev, inode, &tval) == False)
2759 DEBUG(0,("process_local_message: oplock break failed - \
2760 not returning udp message.\n"));
2766 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2767 oplocks. Returning success.\n"));
2770 /* Send the message back after OR'ing in the 'REPLY' bit. */
2771 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2773 bzero((char *)&toaddr,sizeof(toaddr));
2774 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2775 toaddr.sin_port = htons(from_port);
2776 toaddr.sin_family = AF_INET;
2778 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2779 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2781 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2782 remotepid, strerror(errno)));
2786 DEBUG(5,("process_local_message: oplock break reply sent to \
2787 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2788 from_port, dev, inode));
2793 * Keep this as a debug case - eventually we can remove it.
2796 DEBUG(0,("process_local_message: Received unsolicited break \
2797 reply - dumping info.\n"));
2799 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2801 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2802 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2807 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2808 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2809 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2811 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2812 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2818 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2819 (unsigned int)SVAL(msg_start,0)));
2825 /****************************************************************************
2826 Process an oplock break directly.
2827 ****************************************************************************/
2828 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2832 char *outbuf = NULL;
2833 files_struct *fsp = NULL;
2836 BOOL shutdown_server = False;
2838 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2839 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2841 /* We need to search the file open table for the
2842 entry containing this dev and inode, and ensure
2843 we have an oplock on it. */
2844 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2848 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2849 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2850 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2859 /* The file could have been closed in the meantime - return success. */
2860 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2861 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2865 /* Ensure we have an oplock on the file */
2867 /* There is a potential race condition in that an oplock could
2868 have been broken due to another udp request, and yet there are
2869 still oplock break messages being sent in the udp message
2870 queue for this file. So return true if we don't have an oplock,
2871 as we may have just freed it.
2874 if(!fsp->granted_oplock)
2876 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));
2880 /* mark the oplock break as sent - we don't want to send twice! */
2881 if (fsp->sent_oplock_break)
2883 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));
2885 /* We have to fail the open here as we cannot send another oplock break on this
2886 file whilst we are awaiting a response from the client - neither can we
2887 allow another open to succeed while we are waiting for the client. */
2891 /* Now comes the horrid part. We must send an oplock break to the client,
2892 and then process incoming messages until we get a close or oplock release.
2893 At this point we know we need a new inbuf/outbuf buffer pair.
2894 We cannot use these staticaly as we may recurse into here due to
2895 messages crossing on the wire.
2898 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2900 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2904 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2906 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2912 /* Prepare the SMBlockingX message. */
2913 bzero(outbuf,smb_size);
2914 set_message(outbuf,8,0,True);
2916 SCVAL(outbuf,smb_com,SMBlockingX);
2917 SSVAL(outbuf,smb_tid,fsp->cnum);
2918 SSVAL(outbuf,smb_pid,0xFFFF);
2919 SSVAL(outbuf,smb_uid,0);
2920 SSVAL(outbuf,smb_mid,0xFFFF);
2921 SCVAL(outbuf,smb_vwv0,0xFF);
2922 SSVAL(outbuf,smb_vwv2,fnum);
2923 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2924 /* Change this when we have level II oplocks. */
2925 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2927 send_smb(Client, outbuf);
2929 /* Remember we just sent an oplock break on this file. */
2930 fsp->sent_oplock_break = True;
2932 /* We need this in case a readraw crosses on the wire. */
2933 global_oplock_break = True;
2935 /* Process incoming messages. */
2937 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2938 seconds we should just die.... */
2940 start_time = time(NULL);
2942 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2944 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2947 * Die if we got an error.
2950 if (smb_read_error == READ_EOF)
2951 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2953 if (smb_read_error == READ_ERROR)
2954 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2955 timestring(), strerror(errno)));
2957 if (smb_read_error == READ_TIMEOUT)
2958 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2959 timestring(), OPLOCK_BREAK_TIMEOUT));
2961 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2962 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2963 shutdown_server = True;
2968 * There are certain SMB requests that we shouldn't allow
2969 * to recurse. opens, renames and deletes are the obvious
2970 * ones. This is handled in the switch_message() function.
2971 * If global_oplock_break is set they will push the packet onto
2972 * the pending smb queue and return -1 (no reply).
2976 process_smb(inbuf, outbuf);
2979 * Die if we go over the time limit.
2982 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2984 DEBUG(0,("%s oplock_break: no break received from client within \
2985 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2986 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2987 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2988 shutdown_server = True;
2993 /* Free the buffers we've been using to recurse. */
2997 /* We need this in case a readraw crossed on the wire. */
2998 if(global_oplock_break)
2999 global_oplock_break = False;
3002 * If the client did not respond we must die.
3007 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3011 exit_server("oplock break failure");
3016 /* The lockingX reply will have removed the oplock flag
3017 from the sharemode. */
3019 fsp->granted_oplock = False;
3020 fsp->sent_oplock_break = False;
3021 global_oplocks_open--;
3024 /* Santity check - remove this later. JRA */
3025 if(global_oplocks_open < 0)
3027 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3028 global_oplocks_open));
3029 exit_server("oplock_break: global_oplocks_open < 0");
3032 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3033 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3038 /****************************************************************************
3039 Send an oplock break message to another smbd process. If the oplock is held
3040 by the local smbd then call the oplock break function directly.
3041 ****************************************************************************/
3043 BOOL request_oplock_break(share_mode_entry *share_entry,
3044 uint32 dev, uint32 inode)
3046 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3047 struct sockaddr_in addr_out;
3052 if(pid == share_entry->pid)
3054 /* We are breaking our own oplock, make sure it's us. */
3055 if(share_entry->op_port != oplock_port)
3057 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3058 should be %d\n", pid, share_entry->op_port, oplock_port));
3062 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3064 /* Call oplock break direct. */
3065 return oplock_break(dev, inode, &share_entry->time);
3068 /* We need to send a OPLOCK_BREAK_CMD message to the
3069 port in the share mode entry. */
3071 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3072 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3073 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3074 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3075 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3076 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3078 /* set the address and port */
3079 bzero((char *)&addr_out,sizeof(addr_out));
3080 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3081 addr_out.sin_port = htons( share_entry->op_port );
3082 addr_out.sin_family = AF_INET;
3084 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3085 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3087 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3088 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3090 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3091 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3092 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3098 * Now we must await the oplock broken message coming back
3099 * from the target smbd process. Timeout if it fails to
3100 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3101 * While we get messages that aren't ours, loop.
3104 start_time = time(NULL);
3105 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3107 while(time_left >= 0)
3109 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3110 int32 reply_msg_len;
3111 uint16 reply_from_port;
3112 char *reply_msg_start;
3114 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3115 time_left ? time_left * 1000 : 1) == False)
3117 if(smb_read_error == READ_TIMEOUT)
3119 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3120 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3121 share_entry->op_port, dev, inode));
3123 * This is a hack to make handling of failing clients more robust.
3124 * If a oplock break response message is not received in the timeout
3125 * period we may assume that the smbd servicing that client holding
3126 * the oplock has died and the client changes were lost anyway, so
3127 * we should continue to try and open the file.
3132 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3133 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3134 share_entry->op_port, dev, inode, strerror(errno)));
3138 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3139 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3141 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3143 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3146 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3152 * Test to see if this is the reply we are awaiting.
3155 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3156 (reply_from_port == share_entry->op_port) &&
3157 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3158 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3159 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3162 * This is the reply we've been waiting for.
3169 * This is another message - probably a break request.
3170 * Process it to prevent potential deadlock.
3171 * Note that the code in switch_message() prevents
3172 * us from recursing into here as any SMB requests
3173 * we might process that would cause another oplock
3174 * break request to be made will be queued.
3178 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3181 time_left -= (time(NULL) - start_time);
3184 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3189 /****************************************************************************
3190 Get the next SMB packet, doing the local message processing automatically.
3191 ****************************************************************************/
3193 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3195 BOOL got_smb = False;
3200 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3205 /* Deal with oplock break requests from other smbd's. */
3206 process_local_message(oplock_sock, inbuf, bufsize);
3210 if(ret && (CVAL(inbuf,0) == 0x85))
3212 /* Keepalive packet. */
3217 while(ret && !got_smb);
3222 /****************************************************************************
3223 check if a snum is in use
3224 ****************************************************************************/
3225 BOOL snum_used(int snum)
3228 for (i=0;i<MAX_CONNECTIONS;i++)
3229 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3234 /****************************************************************************
3235 reload the services file
3236 **************************************************************************/
3237 BOOL reload_services(BOOL test)
3244 pstrcpy(fname,lp_configfile());
3245 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3247 pstrcpy(servicesf,fname);
3254 if (test && !lp_file_list_changed())
3257 lp_killunused(snum_used);
3259 ret = lp_load(servicesf,False);
3261 /* perhaps the config filename is now set */
3263 reload_services(True);
3272 set_socket_options(Client,"SO_KEEPALIVE");
3273 set_socket_options(Client,user_socket_options);
3277 reset_mangled_stack( lp_mangledstack() );
3279 /* this forces service parameters to be flushed */
3280 become_service(-1,True);
3287 /****************************************************************************
3288 this prevents zombie child processes
3289 ****************************************************************************/
3290 static int sig_hup()
3292 BlockSignals(True,SIGHUP);
3293 DEBUG(0,("Got SIGHUP\n"));
3294 reload_services(False);
3295 #ifndef DONT_REINSTALL_SIG
3296 signal(SIGHUP,SIGNAL_CAST sig_hup);
3298 BlockSignals(False,SIGHUP);
3302 /****************************************************************************
3303 Setup the groups a user belongs to.
3304 ****************************************************************************/
3305 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3306 int **p_igroups, gid_t **p_groups,
3309 if (-1 == initgroups(user,gid))
3313 DEBUG(0,("Unable to initgroups!\n"));
3314 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3315 DEBUG(0,("This is probably a problem with the account %s\n",user));
3324 ngroups = getgroups(0,&grp);
3327 igroups = (int *)malloc(sizeof(int)*ngroups);
3328 attrs = (int *)malloc(sizeof(int)*ngroups);
3329 for (i=0;i<ngroups;i++)
3331 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3332 igroups[i] = 0x42424242;
3334 ngroups = getgroups(ngroups,(gid_t *)igroups);
3336 if (igroups[0] == 0x42424242)
3339 *p_ngroups = ngroups;
3342 /* The following bit of code is very strange. It is due to the
3343 fact that some OSes use int* and some use gid_t* for
3344 getgroups, and some (like SunOS) use both, one in prototypes,
3345 and one in man pages and the actual code. Thus we detect it
3346 dynamically using some very ugly code */
3349 /* does getgroups return ints or gid_t ?? */
3350 static BOOL groups_use_ints = True;
3352 if (groups_use_ints &&
3354 SVAL(igroups,2) == 0x4242)
3355 groups_use_ints = False;
3357 for (i=0;groups_use_ints && i<ngroups;i++)
3358 if (igroups[i] == 0x42424242)
3359 groups_use_ints = False;
3361 if (groups_use_ints)
3363 *p_igroups = igroups;
3364 *p_groups = (gid_t *)igroups;
3368 gid_t *groups = (gid_t *)igroups;
3369 igroups = (int *)malloc(sizeof(int)*ngroups);
3370 for (i=0;i<ngroups;i++)
3372 igroups[i] = groups[i];
3374 *p_igroups = igroups;
3375 *p_groups = (gid_t *)groups;
3378 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3379 for (i=0;i<ngroups;i++)
3380 DEBUG(3,("%d ",igroups[i]));
3386 /****************************************************************************
3387 make a connection to a service
3388 ****************************************************************************/
3389 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3393 struct passwd *pass = NULL;
3394 connection_struct *pcon;
3397 static BOOL first_connection = True;
3401 snum = find_service(service);
3404 if (strequal(service,"IPC$"))
3406 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3410 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3414 if (strequal(service,HOMES_NAME))
3416 if (*user && Get_Pwnam(user,True))
3417 return(make_connection(user,user,password,pwlen,dev,vuid));
3419 if (validated_username(vuid))
3421 strcpy(user,validated_username(vuid));
3422 return(make_connection(user,user,password,pwlen,dev,vuid));
3426 if (!lp_snum_ok(snum) || !check_access(snum)) {
3430 /* you can only connect to the IPC$ service as an ipc device */
3431 if (strequal(service,"IPC$"))
3434 if (*dev == '?' || !*dev)
3436 if (lp_print_ok(snum))
3437 strcpy(dev,"LPT1:");
3442 /* if the request is as a printer and you can't print then refuse */
3444 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3445 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3449 /* lowercase the user name */
3452 /* add it as a possible user name */
3453 add_session_user(service);
3455 /* shall we let them in? */
3456 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3458 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3462 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3465 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3469 pcon = &Connections[cnum];
3470 bzero((char *)pcon,sizeof(*pcon));
3472 /* find out some info about the user */
3473 pass = Get_Pwnam(user,True);
3477 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3481 pcon->read_only = lp_readonly(snum);
3485 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3486 string_sub(list,"%S",service);
3488 if (user_in_list(user,list))
3489 pcon->read_only = True;
3491 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3492 string_sub(list,"%S",service);
3494 if (user_in_list(user,list))
3495 pcon->read_only = False;
3498 /* admin user check */
3500 /* JRA - original code denied admin user if the share was
3501 marked read_only. Changed as I don't think this is needed,
3502 but old code left in case there is a problem here.
3504 if (user_in_list(user,lp_admin_users(snum))
3506 && !pcon->read_only)
3511 pcon->admin_user = True;
3512 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3515 pcon->admin_user = False;
3517 pcon->force_user = force;
3519 pcon->uid = pass->pw_uid;
3520 pcon->gid = pass->pw_gid;
3521 pcon->num_files_open = 0;
3522 pcon->lastused = time(NULL);
3523 pcon->service = snum;
3525 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3526 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3527 pcon->dirptr = NULL;
3528 pcon->veto_list = NULL;
3529 pcon->hide_list = NULL;
3530 pcon->veto_oplock_list = NULL;
3531 string_set(&pcon->dirpath,"");
3532 string_set(&pcon->user,user);
3535 if (*lp_force_group(snum))
3540 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3541 /* default service may be a group name */
3542 string_sub(gname,"%S",service);
3543 gptr = (struct group *)getgrnam(gname);
3547 pcon->gid = gptr->gr_gid;
3548 DEBUG(3,("Forced group %s\n",gname));
3551 DEBUG(1,("Couldn't find group %s\n",gname));
3555 if (*lp_force_user(snum))
3557 struct passwd *pass2;
3559 fstrcpy(fuser,lp_force_user(snum));
3560 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3563 pcon->uid = pass2->pw_uid;
3564 string_set(&pcon->user,fuser);
3565 fstrcpy(user,fuser);
3566 pcon->force_user = True;
3567 DEBUG(3,("Forced user %s\n",fuser));
3570 DEBUG(1,("Couldn't find user %s\n",fuser));
3575 pstrcpy(s,lp_pathname(snum));
3576 standard_sub(cnum,s);
3577 string_set(&pcon->connectpath,s);
3578 DEBUG(3,("Connect path is %s\n",s));
3581 /* groups stuff added by ih */
3583 pcon->igroups = NULL;
3584 pcon->groups = NULL;
3589 /* Find all the groups this uid is in and store them. Used by become_user() */
3590 setup_groups(pcon->user,pcon->uid,pcon->gid,
3591 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3593 /* check number of connections */
3594 if (!claim_connection(cnum,
3595 lp_servicename(SNUM(cnum)),
3596 lp_max_connections(SNUM(cnum)),False))
3598 DEBUG(1,("too many connections - rejected\n"));
3602 if (lp_status(SNUM(cnum)))
3603 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3605 first_connection = False;
3610 /* execute any "root preexec = " line */
3611 if (*lp_rootpreexec(SNUM(cnum)))
3614 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3615 standard_sub(cnum,cmd);
3616 DEBUG(5,("cmd=%s\n",cmd));
3617 smbrun(cmd,NULL,False);
3620 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3622 DEBUG(0,("Can't become connected user!\n"));
3624 if (!IS_IPC(cnum)) {
3625 yield_connection(cnum,
3626 lp_servicename(SNUM(cnum)),
3627 lp_max_connections(SNUM(cnum)));
3628 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3633 if (ChDir(pcon->connectpath) != 0)
3635 DEBUG(0,("Can't change directory to %s (%s)\n",
3636 pcon->connectpath,strerror(errno)));
3639 if (!IS_IPC(cnum)) {
3640 yield_connection(cnum,
3641 lp_servicename(SNUM(cnum)),
3642 lp_max_connections(SNUM(cnum)));
3643 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3648 string_set(&pcon->origpath,pcon->connectpath);
3650 #if SOFTLINK_OPTIMISATION
3651 /* resolve any soft links early */
3654 pstrcpy(s,pcon->connectpath);
3656 string_set(&pcon->connectpath,s);
3657 ChDir(pcon->connectpath);
3661 num_connections_open++;
3662 add_session_user(user);
3664 /* execute any "preexec = " line */
3665 if (*lp_preexec(SNUM(cnum)))
3668 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3669 standard_sub(cnum,cmd);
3670 smbrun(cmd,NULL,False);
3673 /* we've finished with the sensitive stuff */
3676 /* Add veto/hide lists */
3677 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3679 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3680 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3681 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3685 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3689 lp_servicename(SNUM(cnum)),user,
3699 /****************************************************************************
3700 find first available file slot
3701 ****************************************************************************/
3702 int find_free_file(void )
3705 static int first_file;
3707 /* we want to give out file handles differently on each new
3708 connection because of a common bug in MS clients where they try to
3709 reuse a file descriptor from an earlier smb connection. This code
3710 increases the chance that the errant client will get an error rather
3711 than causing corruption */
3712 if (first_file == 0) {
3713 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3714 if (first_file == 0) first_file = 1;
3717 if (first_file >= MAX_OPEN_FILES)
3720 for (i=first_file;i<MAX_OPEN_FILES;i++)
3721 if (!Files[i].open && !Files[i].reserved) {
3722 memset(&Files[i], 0, sizeof(Files[i]));
3724 Files[i].reserved = True;
3728 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3729 for (i=1;i<first_file;i++)
3730 if (!Files[i].open && !Files[i].reserved) {
3731 memset(&Files[i], 0, sizeof(Files[i]));
3733 Files[i].reserved = True;
3738 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3742 /****************************************************************************
3743 find first available connection slot, starting from a random position.
3744 The randomisation stops problems with the server dieing and clients
3745 thinking the server is still available.
3746 ****************************************************************************/
3747 static int find_free_connection(int hash )
3751 hash = (hash % (MAX_CONNECTIONS-2))+1;
3755 for (i=hash+1;i!=hash;)
3757 if (!Connections[i].open && Connections[i].used == used)
3759 DEBUG(3,("found free connection number %d\n",i));
3763 if (i == MAX_CONNECTIONS)
3773 DEBUG(1,("ERROR! Out of connection structures\n"));
3778 /****************************************************************************
3779 reply for the core protocol
3780 ****************************************************************************/
3781 int reply_corep(char *outbuf)
3783 int outsize = set_message(outbuf,1,0,True);
3785 Protocol = PROTOCOL_CORE;
3791 /****************************************************************************
3792 reply for the coreplus protocol
3793 ****************************************************************************/
3794 int reply_coreplus(char *outbuf)
3796 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3797 int outsize = set_message(outbuf,13,0,True);
3798 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3799 readbraw and writebraw (possibly) */
3800 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3801 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3803 Protocol = PROTOCOL_COREPLUS;
3809 /****************************************************************************
3810 reply for the lanman 1.0 protocol
3811 ****************************************************************************/
3812 int reply_lanman1(char *outbuf)
3814 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3816 BOOL doencrypt = SMBENCRYPT();
3817 time_t t = time(NULL);
3819 if (lp_security()>=SEC_USER) secword |= 1;
3820 if (doencrypt) secword |= 2;
3822 set_message(outbuf,13,doencrypt?8:0,True);
3823 SSVAL(outbuf,smb_vwv1,secword);
3824 /* Create a token value and add it to the outgoing packet. */
3826 generate_next_challenge(smb_buf(outbuf));
3828 Protocol = PROTOCOL_LANMAN1;
3830 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3831 SSVAL(outbuf,smb_vwv2,max_recv);
3832 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3833 SSVAL(outbuf,smb_vwv4,1);
3834 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3835 readbraw writebraw (possibly) */
3836 SIVAL(outbuf,smb_vwv6,getpid());
3837 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3839 put_dos_date(outbuf,smb_vwv8,t);
3841 return (smb_len(outbuf)+4);
3845 /****************************************************************************
3846 reply for the lanman 2.0 protocol
3847 ****************************************************************************/
3848 int reply_lanman2(char *outbuf)
3850 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3852 BOOL doencrypt = SMBENCRYPT();
3853 time_t t = time(NULL);
3854 struct cli_state *cli = NULL;
3858 if (lp_security() == SEC_SERVER) {
3859 cli = server_cryptkey();
3863 DEBUG(3,("using password server validation\n"));
3864 doencrypt = ((cli->sec_mode & 2) != 0);
3867 if (lp_security()>=SEC_USER) secword |= 1;
3868 if (doencrypt) secword |= 2;
3873 generate_next_challenge(cryptkey);
3875 memcpy(cryptkey, cli->cryptkey, 8);
3876 set_challenge(cli->cryptkey);
3880 set_message(outbuf,13,crypt_len,True);
3881 SSVAL(outbuf,smb_vwv1,secword);
3882 SIVAL(outbuf,smb_vwv6,getpid());
3884 memcpy(smb_buf(outbuf), cryptkey, 8);
3886 Protocol = PROTOCOL_LANMAN2;
3888 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3889 SSVAL(outbuf,smb_vwv2,max_recv);
3890 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3891 SSVAL(outbuf,smb_vwv4,1);
3892 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3893 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3894 put_dos_date(outbuf,smb_vwv8,t);
3896 return (smb_len(outbuf)+4);
3900 /****************************************************************************
3901 reply for the nt protocol
3902 ****************************************************************************/
3903 int reply_nt1(char *outbuf)
3905 /* dual names + lock_and_read + nt SMBs + remote API calls */
3906 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3908 other valid capabilities which we may support at some time...
3909 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3910 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3914 BOOL doencrypt = SMBENCRYPT();
3915 time_t t = time(NULL);
3917 struct cli_state *cli = NULL;
3921 if (lp_security() == SEC_SERVER) {
3922 cli = server_cryptkey();
3926 DEBUG(3,("using password server validation\n"));
3927 doencrypt = ((cli->sec_mode & 2) != 0);
3933 generate_next_challenge(cryptkey);
3935 memcpy(cryptkey, cli->cryptkey, 8);
3936 set_challenge(cli->cryptkey);
3940 if (lp_readraw() && lp_writeraw()) {
3941 capabilities |= CAP_RAW_MODE;
3944 if (lp_security() >= SEC_USER) secword |= 1;
3945 if (doencrypt) secword |= 2;
3947 /* decide where (if) to put the encryption challenge, and
3948 follow it with the OEM'd domain name
3950 data_len = crypt_len + strlen(myworkgroup) + 1;
3952 set_message(outbuf,17,data_len,True);
3953 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3955 CVAL(outbuf,smb_vwv1) = secword;
3956 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3958 memcpy(smb_buf(outbuf), cryptkey, 8);
3960 Protocol = PROTOCOL_NT1;
3962 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3963 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3964 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3965 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3966 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3967 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3968 put_long_date(outbuf+smb_vwv11+1,t);
3969 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3970 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3972 return (smb_len(outbuf)+4);
3975 /* these are the protocol lists used for auto architecture detection:
3978 protocol [PC NETWORK PROGRAM 1.0]
3979 protocol [XENIX CORE]
3980 protocol [MICROSOFT NETWORKS 1.03]
3981 protocol [LANMAN1.0]
3982 protocol [Windows for Workgroups 3.1a]
3983 protocol [LM1.2X002]
3984 protocol [LANMAN2.1]
3985 protocol [NT LM 0.12]
3988 protocol [PC NETWORK PROGRAM 1.0]
3989 protocol [XENIX CORE]
3990 protocol [MICROSOFT NETWORKS 1.03]
3991 protocol [LANMAN1.0]
3992 protocol [Windows for Workgroups 3.1a]
3993 protocol [LM1.2X002]
3994 protocol [LANMAN2.1]
3995 protocol [NT LM 0.12]
3998 protocol [PC NETWORK PROGRAM 1.0]
3999 protocol [XENIX CORE]
4000 protocol [LANMAN1.0]
4001 protocol [LM1.2X002]
4002 protocol [LANMAN2.1]
4006 * Modified to recognize the architecture of the remote machine better.
4008 * This appears to be the matrix of which protocol is used by which
4010 Protocol WfWg Win95 WinNT OS/2
4011 PC NETWORK PROGRAM 1.0 1 1 1 1
4013 MICROSOFT NETWORKS 3.0 2 2
4015 MICROSOFT NETWORKS 1.03 3
4018 Windows for Workgroups 3.1a 5 5 5
4023 * tim@fsg.com 09/29/95
4026 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4027 #define ARCH_WIN95 0x2
4028 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4029 #define ARCH_WINNT 0x8
4030 #define ARCH_SAMBA 0x10
4032 #define ARCH_ALL 0x1F
4034 /* List of supported protocols, most desired first */
4038 int (*proto_reply_fn)(char *);
4040 } supported_protocols[] = {
4041 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4042 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4043 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4044 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4045 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4046 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4047 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4048 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4049 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4054 /****************************************************************************
4056 ****************************************************************************/
4057 static int reply_negprot(char *inbuf,char *outbuf)
4059 int outsize = set_message(outbuf,1,0,True);
4064 int bcc = SVAL(smb_buf(inbuf),-2);
4065 int arch = ARCH_ALL;
4067 p = smb_buf(inbuf)+1;
4068 while (p < (smb_buf(inbuf) + bcc))
4071 DEBUG(3,("Requested protocol [%s]\n",p));
4072 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4073 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4074 else if (strcsequal(p,"DOS LM1.2X002"))
4075 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4076 else if (strcsequal(p,"DOS LANMAN2.1"))
4077 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4078 else if (strcsequal(p,"NT LM 0.12"))
4079 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4080 else if (strcsequal(p,"LANMAN2.1"))
4081 arch &= ( ARCH_WINNT | ARCH_OS2 );
4082 else if (strcsequal(p,"LM1.2X002"))
4083 arch &= ( ARCH_WINNT | ARCH_OS2 );
4084 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4086 else if (strcsequal(p,"XENIX CORE"))
4087 arch &= ( ARCH_WINNT | ARCH_OS2 );
4088 else if (strcsequal(p,"Samba")) {
4098 set_remote_arch(RA_SAMBA);
4101 set_remote_arch(RA_WFWG);
4104 set_remote_arch(RA_WIN95);
4107 set_remote_arch(RA_WINNT);
4110 set_remote_arch(RA_OS2);
4113 set_remote_arch(RA_UNKNOWN);
4117 /* possibly reload - change of architecture */
4118 reload_services(True);
4120 /* a special case to stop password server loops */
4121 if (Index == 1 && strequal(remote_machine,myhostname) &&
4122 lp_security()==SEC_SERVER)
4123 exit_server("Password server loop!");
4125 /* Check for protocols, most desirable first */
4126 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4128 p = smb_buf(inbuf)+1;
4130 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4131 while (p < (smb_buf(inbuf) + bcc))
4133 if (strequal(p,supported_protocols[protocol].proto_name))
4142 SSVAL(outbuf,smb_vwv0,choice);
4144 extern fstring remote_proto;
4145 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4146 reload_services(True);
4147 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4148 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4151 DEBUG(0,("No protocol supported !\n"));
4153 SSVAL(outbuf,smb_vwv0,choice);
4155 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4161 /****************************************************************************
4162 close all open files for a connection
4163 ****************************************************************************/
4164 static void close_open_files(int cnum)
4167 for (i=0;i<MAX_OPEN_FILES;i++)
4168 if( Files[i].cnum == cnum && Files[i].open) {
4169 close_file(i,False);
4175 /****************************************************************************
4177 ****************************************************************************/
4178 void close_cnum(int cnum, uint16 vuid)
4180 DirCacheFlush(SNUM(cnum));
4184 if (!OPEN_CNUM(cnum))
4186 DEBUG(0,("Can't close cnum %d\n",cnum));
4190 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4192 remote_machine,client_addr(),
4193 lp_servicename(SNUM(cnum))));
4195 yield_connection(cnum,
4196 lp_servicename(SNUM(cnum)),
4197 lp_max_connections(SNUM(cnum)));
4199 if (lp_status(SNUM(cnum)))
4200 yield_connection(cnum,"STATUS.",MAXSTATUS);
4202 close_open_files(cnum);
4203 dptr_closecnum(cnum);
4205 /* execute any "postexec = " line */
4206 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4209 strcpy(cmd,lp_postexec(SNUM(cnum)));
4210 standard_sub(cnum,cmd);
4211 smbrun(cmd,NULL,False);
4216 /* execute any "root postexec = " line */
4217 if (*lp_rootpostexec(SNUM(cnum)))
4220 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4221 standard_sub(cnum,cmd);
4222 smbrun(cmd,NULL,False);
4225 Connections[cnum].open = False;
4226 num_connections_open--;
4227 if (Connections[cnum].ngroups && Connections[cnum].groups)
4229 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4230 free(Connections[cnum].groups);
4231 free(Connections[cnum].igroups);
4232 Connections[cnum].groups = NULL;
4233 Connections[cnum].igroups = NULL;
4234 Connections[cnum].ngroups = 0;
4237 free_namearray(Connections[cnum].veto_list);
4238 free_namearray(Connections[cnum].hide_list);
4239 free_namearray(Connections[cnum].veto_oplock_list);
4241 string_set(&Connections[cnum].user,"");
4242 string_set(&Connections[cnum].dirpath,"");
4243 string_set(&Connections[cnum].connectpath,"");
4247 /****************************************************************************
4248 simple routines to do connection counting
4249 ****************************************************************************/
4250 BOOL yield_connection(int cnum,char *name,int max_connections)
4252 struct connect_record crec;
4255 int mypid = getpid();
4258 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4260 if (max_connections <= 0)
4263 bzero(&crec,sizeof(crec));
4265 pstrcpy(fname,lp_lockdir());
4266 standard_sub(cnum,fname);
4267 trim_string(fname,"","/");
4271 strcat(fname,".LCK");
4273 f = fopen(fname,"r+");
4276 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4280 fseek(f,0,SEEK_SET);
4282 /* find a free spot */
4283 for (i=0;i<max_connections;i++)
4285 if (fread(&crec,sizeof(crec),1,f) != 1)
4287 DEBUG(2,("Entry not found in lock file %s\n",fname));
4291 if (crec.pid == mypid && crec.cnum == cnum)
4295 if (crec.pid != mypid || crec.cnum != cnum)
4298 DEBUG(2,("Entry not found in lock file %s\n",fname));
4302 bzero((void *)&crec,sizeof(crec));
4304 /* remove our mark */
4305 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4306 fwrite(&crec,sizeof(crec),1,f) != 1)
4308 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4313 DEBUG(3,("Yield successful\n"));
4320 /****************************************************************************
4321 simple routines to do connection counting
4322 ****************************************************************************/
4323 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4325 struct connect_record crec;
4328 int snum = SNUM(cnum);
4332 if (max_connections <= 0)
4335 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4337 pstrcpy(fname,lp_lockdir());
4338 standard_sub(cnum,fname);
4339 trim_string(fname,"","/");
4341 if (!directory_exist(fname,NULL))
4346 strcat(fname,".LCK");
4348 if (!file_exist(fname,NULL))
4350 int oldmask = umask(022);
4351 f = fopen(fname,"w");
4356 total_recs = file_size(fname) / sizeof(crec);
4358 f = fopen(fname,"r+");
4362 DEBUG(1,("couldn't open lock file %s\n",fname));
4366 /* find a free spot */
4367 for (i=0;i<max_connections;i++)
4370 if (i>=total_recs ||
4371 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4372 fread(&crec,sizeof(crec),1,f) != 1)
4374 if (foundi < 0) foundi = i;
4378 if (Clear && crec.pid && !process_exists(crec.pid))
4380 fseek(f,i*sizeof(crec),SEEK_SET);
4381 bzero((void *)&crec,sizeof(crec));
4382 fwrite(&crec,sizeof(crec),1,f);
4383 if (foundi < 0) foundi = i;
4386 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4395 DEBUG(3,("no free locks in %s\n",fname));
4400 /* fill in the crec */
4401 bzero((void *)&crec,sizeof(crec));
4402 crec.magic = 0x280267;
4403 crec.pid = getpid();
4405 crec.uid = Connections[cnum].uid;
4406 crec.gid = Connections[cnum].gid;
4407 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4408 crec.start = time(NULL);
4410 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4411 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4414 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4415 fwrite(&crec,sizeof(crec),1,f) != 1)
4426 /*******************************************************************
4427 prepare to dump a core file - carefully!
4428 ********************************************************************/
4429 static BOOL dump_core(void)
4433 pstrcpy(dname,debugf);
4434 if ((p=strrchr(dname,'/'))) *p=0;
4435 strcat(dname,"/corefiles");
4437 sys_chown(dname,getuid(),getgid());
4439 if (chdir(dname)) return(False);
4442 #ifndef NO_GETRLIMIT
4446 getrlimit(RLIMIT_CORE, &rlp);
4447 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4448 setrlimit(RLIMIT_CORE, &rlp);
4449 getrlimit(RLIMIT_CORE, &rlp);
4450 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4456 DEBUG(0,("Dumping core in %s\n",dname));
4461 /****************************************************************************
4463 ****************************************************************************/
4464 void exit_server(char *reason)
4466 static int firsttime=1;
4469 if (!firsttime) exit(0);
4473 DEBUG(2,("Closing connections\n"));
4474 for (i=0;i<MAX_CONNECTIONS;i++)
4475 if (Connections[i].open)
4476 close_cnum(i,(uint16)-1);
4478 if (dcelogin_atmost_once)
4482 int oldlevel = DEBUGLEVEL;
4484 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4486 show_msg(last_inbuf);
4487 DEBUGLEVEL = oldlevel;
4488 DEBUG(0,("===============================================================\n"));
4490 if (dump_core()) return;
4496 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4500 /****************************************************************************
4501 do some standard substitutions in a string
4502 ****************************************************************************/
4503 void standard_sub(int cnum,char *str)
4505 if (VALID_CNUM(cnum)) {
4508 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4510 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4511 string_sub(p,"%H",home);
4515 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4516 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4517 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4518 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4519 case '\0' : p++; break; /* don't run off the end of the string */
4520 default : p+=2; break;
4524 standard_sub_basic(str);
4528 These flags determine some of the permissions required to do an operation
4530 Note that I don't set NEED_WRITE on some write operations because they
4531 are used by some brain-dead clients when printing, and I don't want to
4532 force write permissions on print services.
4534 #define AS_USER (1<<0)
4535 #define NEED_WRITE (1<<1)
4536 #define TIME_INIT (1<<2)
4537 #define CAN_IPC (1<<3)
4538 #define AS_GUEST (1<<5)
4539 #define QUEUE_IN_OPLOCK (1<<6)
4542 define a list of possible SMB messages and their corresponding
4543 functions. Any message that has a NULL function is unimplemented -
4544 please feel free to contribute implementations!
4546 struct smb_message_struct
4560 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4561 {SMBtcon,"SMBtcon",reply_tcon,0},
4562 {SMBtdis,"SMBtdis",reply_tdis,0},
4563 {SMBexit,"SMBexit",reply_exit,0},
4564 {SMBioctl,"SMBioctl",reply_ioctl,0},
4565 {SMBecho,"SMBecho",reply_echo,0},
4566 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4567 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4568 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4569 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4570 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4571 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4572 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4573 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4575 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4576 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4577 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4579 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4580 {SMBread,"SMBread",reply_read,AS_USER},
4581 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4582 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4583 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4584 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4585 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4586 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4588 /* this is a Pathworks specific call, allowing the
4589 changing of the root path */
4590 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4592 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4593 {SMBflush,"SMBflush",reply_flush,AS_USER},
4594 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4595 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4596 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4597 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4598 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4599 {SMBlock,"SMBlock",reply_lock,AS_USER},
4600 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4602 /* CORE+ PROTOCOL FOLLOWS */
4604 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4605 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4606 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4607 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4608 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4610 /* LANMAN1.0 PROTOCOL FOLLOWS */
4612 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4613 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4614 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4615 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4616 {SMBwritec,"SMBwritec",NULL,AS_USER},
4617 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4618 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4619 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4620 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4621 {SMBioctls,"SMBioctls",NULL,AS_USER},
4622 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4623 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4625 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4626 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4627 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4628 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4630 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4631 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4632 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4634 /* LANMAN2.0 PROTOCOL FOLLOWS */
4635 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4636 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4637 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK },
4638 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4640 /* messaging routines */
4641 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4642 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4643 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4644 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4646 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4648 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4649 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4650 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4651 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4654 /****************************************************************************
4655 return a string containing the function name of a SMB command
4656 ****************************************************************************/
4657 char *smb_fn_name(int type)
4659 static char *unknown_name = "SMBunknown";
4660 static int num_smb_messages =
4661 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4664 for (match=0;match<num_smb_messages;match++)
4665 if (smb_messages[match].code == type)
4668 if (match == num_smb_messages)
4669 return(unknown_name);
4671 return(smb_messages[match].name);
4675 /****************************************************************************
4676 do a switch on the message type, and return the response size
4677 ****************************************************************************/
4678 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4682 static int num_smb_messages =
4683 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4687 struct timeval msg_start_time;
4688 struct timeval msg_end_time;
4689 static unsigned long total_time = 0;
4691 GetTimeOfDay(&msg_start_time);
4698 last_message = type;
4700 /* make sure this is an SMB packet */
4701 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4703 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4707 for (match=0;match<num_smb_messages;match++)
4708 if (smb_messages[match].code == type)
4711 if (match == num_smb_messages)
4713 DEBUG(0,("Unknown message type %d!\n",type));
4714 outsize = reply_unknown(inbuf,outbuf);
4718 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4720 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4723 * Queue this message as we are the process of an oplock break.
4726 DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4729 push_smb_message( inbuf, size);
4733 if (smb_messages[match].fn)
4735 int cnum = SVAL(inbuf,smb_tid);
4736 int flags = smb_messages[match].flags;
4737 /* In share mode security we must ignore the vuid. */
4738 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4739 /* Ensure this value is replaced in the incoming packet. */
4740 SSVAL(inbuf,smb_uid,session_tag);
4742 /* does this protocol need to be run as root? */
4743 if (!(flags & AS_USER))
4746 /* does this protocol need to be run as the connected user? */
4747 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4748 if (flags & AS_GUEST)
4751 return(ERROR(ERRSRV,ERRinvnid));
4753 /* this code is to work around a bug is MS client 3 without
4754 introducing a security hole - it needs to be able to do
4755 print queue checks as guest if it isn't logged in properly */
4756 if (flags & AS_USER)
4759 /* does it need write permission? */
4760 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4761 return(ERROR(ERRSRV,ERRaccess));
4763 /* ipc services are limited */
4764 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4765 return(ERROR(ERRSRV,ERRaccess));
4767 /* load service specific parameters */
4768 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4769 return(ERROR(ERRSRV,ERRaccess));
4771 /* does this protocol need to be run as guest? */
4772 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4773 return(ERROR(ERRSRV,ERRaccess));
4777 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4781 outsize = reply_unknown(inbuf,outbuf);
4786 GetTimeOfDay(&msg_end_time);
4787 if (!(smb_messages[match].flags & TIME_INIT))
4789 smb_messages[match].time = 0;
4790 smb_messages[match].flags |= TIME_INIT;
4793 unsigned long this_time =
4794 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4795 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4796 smb_messages[match].time += this_time;
4797 total_time += this_time;
4799 DEBUG(2,("TIME %s %d usecs %g pct\n",
4800 smb_fn_name(type),smb_messages[match].time,
4801 (100.0*smb_messages[match].time) / total_time));
4808 /****************************************************************************
4809 construct a chained reply and add it to the already made reply
4810 **************************************************************************/
4811 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4813 static char *orig_inbuf;
4814 static char *orig_outbuf;
4815 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4816 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4817 char *inbuf2, *outbuf2;
4819 char inbuf_saved[smb_wct];
4820 char outbuf_saved[smb_wct];
4821 extern int chain_size;
4822 int wct = CVAL(outbuf,smb_wct);
4823 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4825 /* maybe its not chained */
4826 if (smb_com2 == 0xFF) {
4827 CVAL(outbuf,smb_vwv0) = 0xFF;
4831 if (chain_size == 0) {
4832 /* this is the first part of the chain */
4834 orig_outbuf = outbuf;
4837 /* we need to tell the client where the next part of the reply will be */
4838 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4839 CVAL(outbuf,smb_vwv0) = smb_com2;
4841 /* remember how much the caller added to the chain, only counting stuff
4842 after the parameter words */
4843 chain_size += outsize - smb_wct;
4845 /* work out pointers into the original packets. The
4846 headers on these need to be filled in */
4847 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4848 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4850 /* remember the original command type */
4851 smb_com1 = CVAL(orig_inbuf,smb_com);
4853 /* save the data which will be overwritten by the new headers */
4854 memcpy(inbuf_saved,inbuf2,smb_wct);
4855 memcpy(outbuf_saved,outbuf2,smb_wct);
4857 /* give the new packet the same header as the last part of the SMB */
4858 memmove(inbuf2,inbuf,smb_wct);
4860 /* create the in buffer */
4861 CVAL(inbuf2,smb_com) = smb_com2;
4863 /* create the out buffer */
4864 bzero(outbuf2,smb_size);
4865 set_message(outbuf2,0,0,True);
4866 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4868 memcpy(outbuf2+4,inbuf2+4,4);
4869 CVAL(outbuf2,smb_rcls) = SUCCESS;
4870 CVAL(outbuf2,smb_reh) = 0;
4871 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4873 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4874 SSVAL(outbuf2,smb_err,SUCCESS);
4875 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4876 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4877 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4878 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4880 DEBUG(3,("Chained message\n"));
4883 /* process the request */
4884 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4885 bufsize-chain_size);
4887 /* copy the new reply and request headers over the old ones, but
4888 preserve the smb_com field */
4889 memmove(orig_outbuf,outbuf2,smb_wct);
4890 CVAL(orig_outbuf,smb_com) = smb_com1;
4892 /* restore the saved data, being careful not to overwrite any
4893 data from the reply header */
4894 memcpy(inbuf2,inbuf_saved,smb_wct);
4896 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4897 if (ofs < 0) ofs = 0;
4898 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4906 /****************************************************************************
4907 construct a reply to the incoming packet
4908 ****************************************************************************/
4909 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4911 int type = CVAL(inbuf,smb_com);
4913 int msg_type = CVAL(inbuf,0);
4914 extern int chain_size;
4916 smb_last_time = time(NULL);
4922 bzero(outbuf,smb_size);
4925 return(reply_special(inbuf,outbuf));
4927 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4928 set_message(outbuf,0,0,True);
4930 memcpy(outbuf+4,inbuf+4,4);
4931 CVAL(outbuf,smb_rcls) = SUCCESS;
4932 CVAL(outbuf,smb_reh) = 0;
4933 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4935 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4936 SSVAL(outbuf,smb_err,SUCCESS);
4937 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4938 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4939 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4940 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4942 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4944 outsize += chain_size;
4947 smb_setlen(outbuf,outsize - 4);
4951 /****************************************************************************
4952 process commands from the client
4953 ****************************************************************************/
4954 static void process(void)
4958 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4959 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4960 if ((InBuffer == NULL) || (OutBuffer == NULL))
4963 InBuffer += SMB_ALIGNMENT;
4964 OutBuffer += SMB_ALIGNMENT;
4967 DEBUG(3,("priming nmbd\n"));
4970 ip = *interpret_addr2("localhost");
4971 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4973 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4977 /* re-initialise the timezone */
4982 int deadtime = lp_deadtime()*60;
4984 int last_keepalive=0;
4985 int service_load_counter = 0;
4986 BOOL got_smb = False;
4989 deadtime = DEFAULT_SMBD_TIMEOUT;
4991 #if USE_READ_PREDICTION
4992 if (lp_readprediction())
4993 do_read_prediction();
4998 for (counter=SMBD_SELECT_LOOP;
4999 !receive_message_or_smb(Client,oplock_sock,
5000 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
5001 counter += SMBD_SELECT_LOOP)
5005 BOOL allidle = True;
5006 extern int keepalive;
5008 if (counter > 365 * 3600) /* big number of seconds. */
5011 service_load_counter = 0;
5014 if (smb_read_error == READ_EOF)
5016 DEBUG(3,("end of file from client\n"));
5020 if (smb_read_error == READ_ERROR)
5022 DEBUG(3,("receive_smb error (%s) exiting\n",
5029 /* become root again if waiting */
5032 /* check for smb.conf reload */
5033 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5035 service_load_counter = counter;
5037 /* reload services, if files have changed. */
5038 reload_services(True);
5041 /* automatic timeout if all connections are closed */
5042 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
5044 DEBUG(2,("%s Closing idle connection\n",timestring()));
5048 if (keepalive && (counter-last_keepalive)>keepalive)
5050 struct cli_state *cli = server_client();
5051 if (!send_keepalive(Client)) {
5052 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5055 /* also send a keepalive to the password server if its still
5057 if (cli && cli->initialised)
5058 send_keepalive(cli->fd);
5059 last_keepalive = counter;
5062 /* check for connection timeouts */
5063 for (i=0;i<MAX_CONNECTIONS;i++)
5064 if (Connections[i].open)
5066 /* close dirptrs on connections that are idle */
5067 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5070 if (Connections[i].num_files_open > 0 ||
5071 (t-Connections[i].lastused)<deadtime)
5075 if (allidle && num_connections_open>0)
5077 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5083 process_smb(InBuffer, OutBuffer);
5085 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5090 /****************************************************************************
5091 initialise connect, service and file structs
5092 ****************************************************************************/
5093 static void init_structs(void )
5096 get_myname(myhostname,NULL);
5098 for (i=0;i<MAX_CONNECTIONS;i++)
5100 Connections[i].open = False;
5101 Connections[i].num_files_open=0;
5102 Connections[i].lastused=0;
5103 Connections[i].used=False;
5104 string_init(&Connections[i].user,"");
5105 string_init(&Connections[i].dirpath,"");
5106 string_init(&Connections[i].connectpath,"");
5107 string_init(&Connections[i].origpath,"");
5110 for (i=0;i<MAX_OPEN_FILES;i++)
5112 Files[i].open = False;
5113 string_init(&Files[i].name,"");
5117 for (i=0;i<MAX_OPEN_FILES;i++)
5119 file_fd_struct *fd_ptr = &FileFd[i];
5120 fd_ptr->ref_count = 0;
5121 fd_ptr->dev = (int32)-1;
5122 fd_ptr->inode = (int32)-1;
5124 fd_ptr->fd_readonly = -1;
5125 fd_ptr->fd_writeonly = -1;
5126 fd_ptr->real_open_flags = -1;
5130 init_rpc_pipe_hnd();
5133 /* for LSA handles */
5134 init_lsa_policy_hnd();
5140 /****************************************************************************
5141 usage on the program
5142 ****************************************************************************/
5143 static void usage(char *pname)
5145 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5147 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5148 printf("Version %s\n",VERSION);
5149 printf("\t-D become a daemon\n");
5150 printf("\t-p port listen on the specified port\n");
5151 printf("\t-d debuglevel set the debuglevel\n");
5152 printf("\t-l log basename. Basename for log/debug files\n");
5153 printf("\t-s services file. Filename of services file\n");
5154 printf("\t-P passive only\n");
5155 printf("\t-a overwrite log file, don't append\n");
5160 /****************************************************************************
5162 ****************************************************************************/
5163 int main(int argc,char *argv[])
5165 extern BOOL append_log;
5166 /* shall I run as a daemon */
5167 BOOL is_daemon = False;
5168 int port = SMB_PORT;
5170 extern char *optarg;
5175 #ifdef NEED_AUTH_PARAMETERS
5176 set_auth_parameters(argc,argv);
5187 strcpy(debugf,SMBLOGFILE);
5189 setup_logging(argv[0],False);
5191 charset_initialise();
5193 /* make absolutely sure we run as root - to handle cases where people
5194 are crazy enough to have it setuid */
5204 fault_setup(exit_server);
5205 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5207 /* we want total control over the permissions on created files,
5208 so set our umask to 0 */
5215 /* this is for people who can't start the program correctly */
5216 while (argc > 1 && (*argv[1] != '-'))
5222 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5226 strncpy(pidFile, optarg, sizeof(pidFile));
5229 strcpy(user_socket_options,optarg);
5232 strcpy(scope,optarg);
5236 extern BOOL passive;
5241 strcpy(servicesf,optarg);
5244 strcpy(debugf,optarg);
5248 extern BOOL append_log;
5249 append_log = !append_log;
5259 DEBUGLEVEL = atoi(optarg);
5262 port = atoi(optarg);
5275 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5276 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5278 #ifndef NO_GETRLIMIT
5279 #ifdef RLIMIT_NOFILE
5282 getrlimit(RLIMIT_NOFILE, &rlp);
5283 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5284 setrlimit(RLIMIT_NOFILE, &rlp);
5285 getrlimit(RLIMIT_NOFILE, &rlp);
5286 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5292 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5293 getuid(),getgid(),geteuid(),getegid()));
5295 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5297 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5303 if (!reload_services(False))
5306 codepage_initialise(lp_client_code_page());
5308 strcpy(myworkgroup, lp_workgroup());
5310 #ifndef NO_SIGNAL_TEST
5311 signal(SIGHUP,SIGNAL_CAST sig_hup);
5314 /* Setup the signals that allow the debug log level
5315 to by dynamically changed. */
5317 #if defined(SIGUSR1)
5318 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5319 #endif /* SIGUSR1 */
5321 #if defined(SIGUSR2)
5322 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5323 #endif /* SIGUSR2 */
5325 DEBUG(3,("%s loaded services\n",timestring()));
5327 if (!is_daemon && !is_a_socket(0))
5329 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5335 DEBUG(3,("%s becoming a daemon\n",timestring()));
5339 if (!directory_exist(lp_lockdir(), NULL)) {
5340 mkdir(lp_lockdir(), 0755);
5348 if ((fd = open(pidFile,
5352 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5354 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5357 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5359 DEBUG(0,("ERROR: smbd is already running\n"));
5362 sprintf(buf, "%u\n", (unsigned int) getpid());
5363 if (write(fd, buf, strlen(buf)) < 0)
5365 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5368 /* Leave pid file open & locked for the duration... */
5371 if (!open_sockets(is_daemon,port))
5374 if (!locking_init(0))
5377 /* possibly reload the services file. */
5378 reload_services(True);
5380 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5384 if (sys_chroot(lp_rootdir()) == 0)
5385 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5388 /* Setup the oplock IPC socket. */
5389 if(!open_oplock_ipc())
5395 exit_server("normal exit");