2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 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 #if USE_READ_PREDICTION
1470 invalidate_read_prediction(fs_p->fd_ptr->fd);
1474 Connections[cnum].num_files_open--;
1477 free((char *)fs_p->wbmpx_ptr);
1478 fs_p->wbmpx_ptr = NULL;
1484 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1485 fs_p->mmap_ptr = NULL;
1489 if (lp_share_modes(SNUM(cnum)))
1491 lock_share_entry( cnum, dev, inode, &token);
1492 del_share_mode(token, fnum);
1495 fd_attempt_close(fs_p->fd_ptr);
1497 if (lp_share_modes(SNUM(cnum)))
1498 unlock_share_entry( cnum, dev, inode, token);
1500 /* NT uses smbclose to start a print - weird */
1501 if (normal_close && fs_p->print_file)
1504 /* check for magic scripts */
1506 check_magic(fnum,cnum);
1508 if(fs_p->granted_oplock == True)
1509 global_oplocks_open--;
1511 fs_p->sent_oplock_break = False;
1513 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1514 timestring(),Connections[cnum].user,fs_p->name,
1515 Connections[cnum].num_files_open));
1518 enum {AFAIL,AREAD,AWRITE,AALL};
1520 /*******************************************************************
1521 reproduce the share mode access table
1522 ********************************************************************/
1523 static int access_table(int new_deny,int old_deny,int old_mode,
1524 int share_pid,char *fname)
1526 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1528 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1530 if (old_deny == new_deny && share_pid == pid)
1533 if (old_mode == 0) return(AREAD);
1535 /* the new smbpub.zip spec says that if the file extension is
1536 .com, .dll, .exe or .sym then allow the open. I will force
1537 it to read-only as this seems sensible although the spec is
1538 a little unclear on this. */
1539 if ((fname = strrchr(fname,'.'))) {
1540 if (strequal(fname,".com") ||
1541 strequal(fname,".dll") ||
1542 strequal(fname,".exe") ||
1543 strequal(fname,".sym"))
1553 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1554 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1555 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1558 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1559 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1560 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1563 if (old_deny==DENY_WRITE) return(AREAD);
1564 if (old_deny==DENY_READ) return(AWRITE);
1565 if (old_deny==DENY_NONE) return(AALL);
1571 /*******************************************************************
1572 check if the share mode on a file allows it to be deleted or unlinked
1573 return True if sharing doesn't prevent the operation
1574 ********************************************************************/
1575 BOOL check_file_sharing(int cnum,char *fname)
1579 share_mode_entry *old_shares = 0;
1580 int num_share_modes;
1586 if(!lp_share_modes(SNUM(cnum)))
1589 if (stat(fname,&sbuf) == -1) return(True);
1591 dev = (uint32)sbuf.st_dev;
1592 inode = (uint32)sbuf.st_ino;
1594 lock_share_entry(cnum, dev, inode, &token);
1595 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1598 * Check if the share modes will give us access.
1601 if(num_share_modes != 0)
1608 broke_oplock = False;
1609 for(i = 0; i < num_share_modes; i++)
1611 share_mode_entry *share_entry = &old_shares[i];
1614 * Break oplocks before checking share modes. See comment in
1615 * open_file_shared for details.
1616 * Check if someone has an oplock on this file. If so we must
1617 * break it before continuing.
1619 if(share_entry->op_type & BATCH_OPLOCK)
1622 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1623 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1625 /* Oplock break.... */
1626 unlock_share_entry(cnum, dev, inode, token);
1627 if(request_oplock_break(share_entry, dev, inode) == False)
1629 free((char *)old_shares);
1630 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1631 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1634 lock_share_entry(cnum, dev, inode, &token);
1635 broke_oplock = True;
1639 /* someone else has a share lock on it, check to see
1641 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1648 free((char *)old_shares);
1649 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1651 } while(broke_oplock);
1654 /* XXXX exactly what share mode combinations should be allowed for
1655 deleting/renaming? */
1656 /* If we got here then either there were no share modes or
1657 all share modes were DENY_DOS and the pid == getpid() */
1662 unlock_share_entry(cnum, dev, inode, token);
1663 if(old_shares != NULL)
1664 free((char *)old_shares);
1668 /****************************************************************************
1670 Helper for open_file_shared.
1671 Truncate a file after checking locking; close file if locked.
1672 **************************************************************************/
1673 static void truncate_unless_locked(int fnum, int cnum, int token,
1676 if (Files[fnum].can_write){
1677 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1678 /* If share modes are in force for this connection we
1679 have the share entry locked. Unlock it before closing. */
1680 if (*share_locked && lp_share_modes(SNUM(cnum)))
1681 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1682 Files[fnum].fd_ptr->inode, token);
1683 close_file(fnum,False);
1684 /* Share mode no longer locked. */
1685 *share_locked = False;
1687 unix_ERR_class = ERRDOS;
1688 unix_ERR_code = ERRlock;
1691 ftruncate(Files[fnum].fd_ptr->fd,0);
1695 /****************************************************************************
1696 check if we can open a file with a share mode
1697 ****************************************************************************/
1698 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1699 BOOL fcbopen, int *flags)
1701 int old_open_mode = share->share_mode &0xF;
1702 int old_deny_mode = (share->share_mode >>4)&7;
1704 if (old_deny_mode > 4 || old_open_mode > 2)
1706 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1707 deny_mode,old_deny_mode,old_open_mode,fname));
1712 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1715 if ((access_allowed == AFAIL) ||
1716 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1717 (access_allowed == AREAD && *flags == O_WRONLY) ||
1718 (access_allowed == AWRITE && *flags == O_RDONLY))
1720 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1721 deny_mode,old_deny_mode,old_open_mode,
1722 share->pid,fname, fcbopen, *flags, access_allowed));
1726 if (access_allowed == AREAD)
1729 if (access_allowed == AWRITE)
1736 /****************************************************************************
1737 open a file with a share mode
1738 ****************************************************************************/
1739 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1740 int mode,int oplock_request, int *Access,int *action)
1742 files_struct *fs_p = &Files[fnum];
1745 int deny_mode = (share_mode>>4)&7;
1747 BOOL file_existed = file_exist(fname,&sbuf);
1748 BOOL share_locked = False;
1749 BOOL fcbopen = False;
1753 int num_share_modes = 0;
1758 /* this is for OS/2 EAs - try and say we don't support them */
1759 if (strstr(fname,".+,;=[]."))
1761 unix_ERR_class = ERRDOS;
1762 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1764 unix_ERR_code = ERRcannotopen;
1765 #else /* OS2_WPS_FIX */
1766 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1767 #endif /* OS2_WPS_FIX */
1772 if ((ofun & 0x3) == 0 && file_existed)
1780 if ((ofun & 0x3) == 2)
1783 /* note that we ignore the append flag as
1784 append does not mean the same thing under dos and unix */
1786 switch (share_mode&0xF)
1803 if (flags != O_RDONLY && file_existed &&
1804 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1814 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1816 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1821 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1823 if (lp_share_modes(SNUM(cnum)))
1826 share_mode_entry *old_shares = 0;
1830 dev = (uint32)sbuf.st_dev;
1831 inode = (uint32)sbuf.st_ino;
1832 lock_share_entry(cnum, dev, inode, &token);
1833 share_locked = True;
1834 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1838 * Check if the share modes will give us access.
1841 if(share_locked && (num_share_modes != 0))
1848 broke_oplock = False;
1849 for(i = 0; i < num_share_modes; i++)
1851 share_mode_entry *share_entry = &old_shares[i];
1854 * By observation of NetBench, oplocks are broken *before* share
1855 * modes are checked. This allows a file to be closed by the client
1856 * if the share mode would deny access and the client has an oplock.
1857 * Check if someone has an oplock on this file. If so we must break
1858 * it before continuing.
1860 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1863 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1864 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1866 /* Oplock break.... */
1867 unlock_share_entry(cnum, dev, inode, token);
1868 if(request_oplock_break(share_entry, dev, inode) == False)
1870 free((char *)old_shares);
1871 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1872 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1874 unix_ERR_class = ERRDOS;
1875 unix_ERR_code = ERRbadshare;
1878 lock_share_entry(cnum, dev, inode, &token);
1879 broke_oplock = True;
1883 /* someone else has a share lock on it, check to see
1885 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1887 free((char *)old_shares);
1888 unlock_share_entry(cnum, dev, inode, token);
1890 unix_ERR_class = ERRDOS;
1891 unix_ERR_code = ERRbadshare;
1899 free((char *)old_shares);
1900 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1902 } while(broke_oplock);
1906 free((char *)old_shares);
1909 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1910 flags,flags2,mode));
1912 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1913 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1916 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1923 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1925 /* We created the file - thus we must now lock the share entry before creating it. */
1926 dev = fs_p->fd_ptr->dev;
1927 inode = fs_p->fd_ptr->inode;
1928 lock_share_entry(cnum, dev, inode, &token);
1929 share_locked = True;
1945 fs_p->share_mode = (deny_mode<<4) | open_mode;
1948 (*Access) = open_mode;
1952 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1953 if (!file_existed) *action = 2;
1954 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1956 /* We must create the share mode entry before truncate as
1957 truncate can fail due to locking and have to close the
1958 file (which expects the share_mode_entry to be there).
1960 if (lp_share_modes(SNUM(cnum)))
1963 /* JRA. Currently this only services Exlcusive and batch
1964 oplocks (no other opens on this file). This needs to
1965 be extended to level II oplocks (multiple reader
1968 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
1969 !IS_VETO_OPLOCK_PATH(cnum,fname))
1971 fs_p->granted_oplock = True;
1972 fs_p->sent_oplock_break = False;
1973 global_oplocks_open++;
1976 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1977 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1985 set_share_mode(token, fnum, port, oplock_request);
1988 if ((flags2&O_TRUNC) && file_existed)
1989 truncate_unless_locked(fnum,cnum,token,&share_locked);
1992 if (share_locked && lp_share_modes(SNUM(cnum)))
1993 unlock_share_entry( cnum, dev, inode, token);
1996 /****************************************************************************
1997 seek a file. Try to avoid the seek if possible
1998 ****************************************************************************/
1999 int seek_file(int fnum,uint32 pos)
2002 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2005 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2007 return(Files[fnum].pos);
2010 /****************************************************************************
2012 ****************************************************************************/
2013 int read_file(int fnum,char *data,uint32 pos,int n)
2017 #if USE_READ_PREDICTION
2018 if (!Files[fnum].can_write)
2020 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2029 if (Files[fnum].mmap_ptr)
2031 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
2034 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2046 if (seek_file(fnum,pos) != pos)
2048 DEBUG(3,("Failed to seek to %d\n",pos));
2053 readret = read(Files[fnum].fd_ptr->fd,data,n);
2054 if (readret > 0) ret += readret;
2061 /****************************************************************************
2063 ****************************************************************************/
2064 int write_file(int fnum,char *data,int n)
2066 if (!Files[fnum].can_write) {
2071 if (!Files[fnum].modified) {
2073 Files[fnum].modified = True;
2074 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2075 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2076 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2077 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2082 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2086 /****************************************************************************
2087 load parameters specific to a connection/service
2088 ****************************************************************************/
2089 BOOL become_service(int cnum,BOOL do_chdir)
2091 extern char magic_char;
2092 static int last_cnum = -1;
2095 if (!OPEN_CNUM(cnum))
2101 Connections[cnum].lastused = smb_last_time;
2106 ChDir(Connections[cnum].connectpath) != 0 &&
2107 ChDir(Connections[cnum].origpath) != 0)
2109 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2110 Connections[cnum].connectpath,cnum));
2114 if (cnum == last_cnum)
2119 case_default = lp_defaultcase(snum);
2120 case_preserve = lp_preservecase(snum);
2121 short_case_preserve = lp_shortpreservecase(snum);
2122 case_mangle = lp_casemangle(snum);
2123 case_sensitive = lp_casesensitive(snum);
2124 magic_char = lp_magicchar(snum);
2125 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2130 /****************************************************************************
2131 find a service entry
2132 ****************************************************************************/
2133 int find_service(char *service)
2137 string_sub(service,"\\","/");
2139 iService = lp_servicenumber(service);
2141 /* now handle the special case of a home directory */
2144 char *phome_dir = get_home_dir(service);
2145 DEBUG(3,("checking for home directory %s gave %s\n",service,
2146 phome_dir?phome_dir:"(NULL)"));
2150 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2152 lp_add_home(service,iHomeService,phome_dir);
2153 iService = lp_servicenumber(service);
2158 /* If we still don't have a service, attempt to add it as a printer. */
2161 int iPrinterService;
2163 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2167 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2169 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2171 DEBUG(3,("%s is a valid printer name\n", service));
2172 DEBUG(3,("adding %s as a printer service\n", service));
2173 lp_add_printer(service,iPrinterService);
2174 iService = lp_servicenumber(service);
2176 DEBUG(0,("failed to add %s as a printer service!\n", service));
2179 DEBUG(3,("%s is not a valid printer name\n", service));
2183 /* just possibly it's a default service? */
2186 char *defservice = lp_defaultservice();
2187 if (defservice && *defservice && !strequal(defservice,service)) {
2188 iService = find_service(defservice);
2189 if (iService >= 0) {
2190 string_sub(service,"_","/");
2191 iService = lp_add_service(service,iService);
2197 if (!VALID_SNUM(iService))
2199 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2204 DEBUG(3,("find_service() failed to find service %s\n", service));
2210 /****************************************************************************
2211 create an error packet from a cached error.
2212 ****************************************************************************/
2213 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2215 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2217 int32 eclass = wbmpx->wr_errclass;
2218 int32 err = wbmpx->wr_error;
2220 /* We can now delete the auxiliary struct */
2221 free((char *)wbmpx);
2222 Files[fnum].wbmpx_ptr = NULL;
2223 return error_packet(inbuf,outbuf,eclass,err,line);
2232 } unix_smb_errmap[] =
2234 {EPERM,ERRDOS,ERRnoaccess},
2235 {EACCES,ERRDOS,ERRnoaccess},
2236 {ENOENT,ERRDOS,ERRbadfile},
2237 {ENOTDIR,ERRDOS,ERRbadpath},
2238 {EIO,ERRHRD,ERRgeneral},
2239 {EBADF,ERRSRV,ERRsrverror},
2240 {EINVAL,ERRSRV,ERRsrverror},
2241 {EEXIST,ERRDOS,ERRfilexists},
2242 {ENFILE,ERRDOS,ERRnofids},
2243 {EMFILE,ERRDOS,ERRnofids},
2244 {ENOSPC,ERRHRD,ERRdiskfull},
2246 {EDQUOT,ERRHRD,ERRdiskfull},
2249 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2252 {EXDEV,ERRDOS,ERRdiffdevice},
2254 {EROFS,ERRHRD,ERRnowrite},
2258 /****************************************************************************
2259 create an error packet from errno
2260 ****************************************************************************/
2261 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2263 int eclass=def_class;
2267 if (unix_ERR_class != SUCCESS)
2269 eclass = unix_ERR_class;
2270 ecode = unix_ERR_code;
2271 unix_ERR_class = SUCCESS;
2276 while (unix_smb_errmap[i].smbclass != 0)
2278 if (unix_smb_errmap[i].unixerror == errno)
2280 eclass = unix_smb_errmap[i].smbclass;
2281 ecode = unix_smb_errmap[i].smbcode;
2288 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2292 /****************************************************************************
2293 create an error packet. Normally called using the ERROR() macro
2294 ****************************************************************************/
2295 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2297 int outsize = set_message(outbuf,0,0,True);
2299 cmd = CVAL(inbuf,smb_com);
2301 CVAL(outbuf,smb_rcls) = error_class;
2302 SSVAL(outbuf,smb_err,error_code);
2304 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2307 (int)CVAL(inbuf,smb_com),
2308 smb_fn_name(CVAL(inbuf,smb_com)),
2313 DEBUG(3,("error string = %s\n",strerror(errno)));
2319 #ifndef SIGCLD_IGNORE
2320 /****************************************************************************
2321 this prevents zombie child processes
2322 ****************************************************************************/
2323 static int sig_cld()
2325 static int depth = 0;
2328 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2334 BlockSignals(True,SIGCLD);
2335 DEBUG(5,("got SIGCLD\n"));
2338 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2342 /* Stevens, Adv. Unix Prog. says that on system V you must call
2343 wait before reinstalling the signal handler, because the kernel
2344 calls the handler from within the signal-call when there is a
2345 child that has exited. This would lead to an infinite recursion
2346 if done vice versa. */
2348 #ifndef DONT_REINSTALL_SIG
2349 #ifdef SIGCLD_IGNORE
2350 signal(SIGCLD, SIG_IGN);
2352 signal(SIGCLD, SIGNAL_CAST sig_cld);
2357 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2360 BlockSignals(False,SIGCLD);
2365 /****************************************************************************
2366 this is called when the client exits abruptly
2367 **************************************************************************/
2368 static int sig_pipe()
2370 struct cli_state *cli;
2371 BlockSignals(True,SIGPIPE);
2373 if ((cli = server_client()) && cli->initialised) {
2374 DEBUG(3,("lost connection to password server\n"));
2376 #ifndef DONT_REINSTALL_SIG
2377 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2379 BlockSignals(False,SIGPIPE);
2383 exit_server("Got sigpipe\n");
2387 /****************************************************************************
2388 open the socket communication
2389 ****************************************************************************/
2390 static BOOL open_sockets(BOOL is_daemon,int port)
2396 int num_interfaces = iface_count();
2397 int fd_listenset[FD_SETSIZE];
2403 #ifdef SIGCLD_IGNORE
2404 signal(SIGCLD, SIG_IGN);
2406 signal(SIGCLD, SIGNAL_CAST sig_cld);
2412 FD_ZERO(&listen_set);
2414 if(lp_interfaces() && lp_bind_interfaces_only())
2416 /* We have been given an interfaces line, and been
2417 told to only bind to those interfaces. Create a
2418 socket per interface and bind to only these.
2421 if(num_interfaces > FD_SETSIZE)
2423 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2424 max can be %d\n", num_interfaces, FD_SETSIZE));
2428 /* Now open a listen socket for each of the interfaces. */
2429 for(i = 0; i < num_interfaces; i++)
2431 struct in_addr *ifip = iface_n_ip(i);
2435 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2438 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2441 /* ready to listen */
2442 if (listen(s, 5) == -1)
2444 DEBUG(0,("listen: %s\n",strerror(errno)));
2448 FD_SET(s,&listen_set);
2453 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2456 /* open an incoming socket */
2457 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2461 /* ready to listen */
2462 if (listen(s, 5) == -1)
2464 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2469 fd_listenset[0] = s;
2470 FD_SET(s,&listen_set);
2473 /* now accept incoming connections - forking a new process
2474 for each incoming connection */
2475 DEBUG(2,("waiting for a connection\n"));
2481 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2483 num = sys_select(&lfds,NULL);
2485 if (num == -1 && errno == EINTR)
2488 /* Find the sockets that are read-ready - accept on these. */
2489 for( ; num > 0; num--)
2491 struct sockaddr addr;
2492 int in_addrlen = sizeof(addr);
2495 for(i = 0; i < num_interfaces; i++)
2497 if(FD_ISSET(fd_listenset[i],&lfds))
2499 s = fd_listenset[i];
2500 /* Clear this so we don't look at it again. */
2501 FD_CLR(fd_listenset[i],&lfds);
2506 Client = accept(s,&addr,&in_addrlen);
2508 if (Client == -1 && errno == EINTR)
2513 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2517 #ifdef NO_FORK_DEBUG
2518 #ifndef NO_SIGNAL_TEST
2519 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2520 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2521 #endif /* NO_SIGNAL_TEST */
2523 #else /* NO_FORK_DEBUG */
2524 if (Client != -1 && fork()==0)
2526 /* Child code ... */
2528 #ifndef NO_SIGNAL_TEST
2529 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2530 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2531 #endif /* NO_SIGNAL_TEST */
2532 /* close the listening socket(s) */
2533 for(i = 0; i < num_interfaces; i++)
2534 close(fd_listenset[i]);
2536 /* close our standard file descriptors */
2540 set_socket_options(Client,"SO_KEEPALIVE");
2541 set_socket_options(Client,user_socket_options);
2543 /* Reset global variables in util.c so that
2544 client substitutions will be done correctly
2547 reset_globals_after_fork();
2550 close(Client); /* The parent doesn't need this socket */
2551 #endif /* NO_FORK_DEBUG */
2554 } /* end if is_daemon */
2557 /* Started from inetd. fd 0 is the socket. */
2558 /* We will abort gracefully when the client or remote system
2560 #ifndef NO_SIGNAL_TEST
2561 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2565 /* close our standard file descriptors */
2568 set_socket_options(Client,"SO_KEEPALIVE");
2569 set_socket_options(Client,user_socket_options);
2575 /****************************************************************************
2576 process an smb from the client - split out from the process() code so
2577 it can be used by the oplock break code.
2578 ****************************************************************************/
2580 static void process_smb(char *inbuf, char *outbuf)
2583 static int trans_num;
2584 int msg_type = CVAL(inbuf,0);
2585 int32 len = smb_len(inbuf);
2586 int nread = len + 4;
2588 if (trans_num == 0) {
2589 /* on the first packet, check the global hosts allow/ hosts
2590 deny parameters before doing any parsing of the packet
2591 passed to us by the client. This prevents attacks on our
2592 parsing code from hosts not in the hosts allow list */
2593 if (!check_access(-1)) {
2594 /* send a negative session response "not listining on calling
2596 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2597 DEBUG(1,("%s Connection denied from %s\n",
2598 timestring(),client_addr()));
2599 send_smb(Client,(char *)buf);
2600 exit_server("connection denied");
2604 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2605 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2608 if(trans_num == 1 && VT_Check(inbuf))
2617 else if(msg_type == 0x85)
2618 return; /* Keepalive packet. */
2620 nread = construct_reply(inbuf,outbuf,nread,max_send);
2624 if (CVAL(outbuf,0) == 0)
2627 if (nread != smb_len(outbuf) + 4)
2629 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2630 nread, smb_len(outbuf)));
2633 send_smb(Client,outbuf);
2638 /****************************************************************************
2639 open the oplock IPC socket communication
2640 ****************************************************************************/
2641 static BOOL open_oplock_ipc()
2643 struct sockaddr_in sock_name;
2644 int len = sizeof(sock_name);
2646 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2648 /* Open a lookback UDP socket on a random port. */
2649 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2650 if (oplock_sock == -1)
2652 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2653 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2658 /* Find out the transient UDP port we have been allocated. */
2659 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2661 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2668 oplock_port = ntohs(sock_name.sin_port);
2670 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2671 getpid(), oplock_port));
2676 /****************************************************************************
2677 process an oplock break message.
2678 ****************************************************************************/
2679 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2685 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2686 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2688 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2690 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2691 msg_len, from_port));
2693 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2694 only valid request. */
2696 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2698 case OPLOCK_BREAK_CMD:
2699 /* Ensure that the msg length is correct. */
2700 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2702 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2703 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2707 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2708 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2709 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2710 struct timeval tval;
2711 struct sockaddr_in toaddr;
2713 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2714 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2716 DEBUG(5,("process_local_message: oplock break request from \
2717 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2720 * If we have no record of any currently open oplocks,
2721 * it's not an error, as a close command may have
2722 * just been issued on the file that was oplocked.
2723 * Just return success in this case.
2726 if(global_oplocks_open != 0)
2728 if(oplock_break(dev, inode, &tval) == False)
2730 DEBUG(0,("process_local_message: oplock break failed - \
2731 not returning udp message.\n"));
2737 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2738 oplocks. Returning success.\n"));
2741 /* Send the message back after OR'ing in the 'REPLY' bit. */
2742 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2744 bzero((char *)&toaddr,sizeof(toaddr));
2745 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2746 toaddr.sin_port = htons(from_port);
2747 toaddr.sin_family = AF_INET;
2749 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2750 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2752 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2753 remotepid, strerror(errno)));
2757 DEBUG(5,("process_local_message: oplock break reply sent to \
2758 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2759 from_port, dev, inode));
2764 * Keep this as a debug case - eventually we can remove it.
2767 DEBUG(0,("process_local_message: Received unsolicited break \
2768 reply - dumping info.\n"));
2770 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2772 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2773 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2778 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2779 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2780 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2782 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2783 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2789 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2790 (unsigned int)SVAL(msg_start,0)));
2796 /****************************************************************************
2797 Process an oplock break directly.
2798 ****************************************************************************/
2799 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2803 char *outbuf = NULL;
2804 files_struct *fsp = NULL;
2807 BOOL shutdown_server = False;
2809 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2810 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2812 /* We need to search the file open table for the
2813 entry containing this dev and inode, and ensure
2814 we have an oplock on it. */
2815 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2819 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2820 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2821 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2830 /* The file could have been closed in the meantime - return success. */
2831 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2832 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2836 /* Ensure we have an oplock on the file */
2838 /* There is a potential race condition in that an oplock could
2839 have been broken due to another udp request, and yet there are
2840 still oplock break messages being sent in the udp message
2841 queue for this file. So return true if we don't have an oplock,
2842 as we may have just freed it.
2845 if(!fsp->granted_oplock)
2847 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));
2851 /* mark the oplock break as sent - we don't want to send twice! */
2852 if (fsp->sent_oplock_break)
2854 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));
2856 /* We have to fail the open here as we cannot send another oplock break on this
2857 file whilst we are awaiting a response from the client - neither can we
2858 allow another open to succeed while we are waiting for the client. */
2862 /* Now comes the horrid part. We must send an oplock break to the client,
2863 and then process incoming messages until we get a close or oplock release.
2864 At this point we know we need a new inbuf/outbuf buffer pair.
2865 We cannot use these staticaly as we may recurse into here due to
2866 messages crossing on the wire.
2869 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2871 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2875 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2877 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2883 /* Prepare the SMBlockingX message. */
2884 bzero(outbuf,smb_size);
2885 set_message(outbuf,8,0,True);
2887 SCVAL(outbuf,smb_com,SMBlockingX);
2888 SSVAL(outbuf,smb_tid,fsp->cnum);
2889 SSVAL(outbuf,smb_pid,0xFFFF);
2890 SSVAL(outbuf,smb_uid,0);
2891 SSVAL(outbuf,smb_mid,0xFFFF);
2892 SCVAL(outbuf,smb_vwv0,0xFF);
2893 SSVAL(outbuf,smb_vwv2,fnum);
2894 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2895 /* Change this when we have level II oplocks. */
2896 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2898 send_smb(Client, outbuf);
2900 /* Remember we just sent an oplock break on this file. */
2901 fsp->sent_oplock_break = True;
2903 /* We need this in case a readraw crosses on the wire. */
2904 global_oplock_break = True;
2906 /* Process incoming messages. */
2908 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2909 seconds we should just die.... */
2911 start_time = time(NULL);
2913 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2915 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2918 * Die if we got an error.
2921 if (smb_read_error == READ_EOF)
2922 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2924 if (smb_read_error == READ_ERROR)
2925 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2926 timestring(), strerror(errno)));
2928 if (smb_read_error == READ_TIMEOUT)
2929 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2930 timestring(), OPLOCK_BREAK_TIMEOUT));
2932 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2933 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2934 shutdown_server = True;
2937 process_smb(inbuf, outbuf);
2940 * Die if we go over the time limit.
2943 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2945 DEBUG(0,("%s oplock_break: no break received from client within \
2946 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2947 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2948 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2949 shutdown_server = True;
2954 /* Free the buffers we've been using to recurse. */
2958 /* We need this in case a readraw crossed on the wire. */
2959 if(global_oplock_break)
2960 global_oplock_break = False;
2963 * If the client did not respond we must die.
2968 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2972 exit_server("oplock break failure");
2977 /* The lockingX reply will have removed the oplock flag
2978 from the sharemode. */
2980 fsp->granted_oplock = False;
2981 fsp->sent_oplock_break = False;
2982 global_oplocks_open--;
2985 /* Santity check - remove this later. JRA */
2986 if(global_oplocks_open < 0)
2988 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2989 global_oplocks_open));
2990 exit_server("oplock_break: global_oplocks_open < 0");
2993 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2994 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2999 /****************************************************************************
3000 Send an oplock break message to another smbd process. If the oplock is held
3001 by the local smbd then call the oplock break function directly.
3002 ****************************************************************************/
3004 BOOL request_oplock_break(share_mode_entry *share_entry,
3005 uint32 dev, uint32 inode)
3007 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3008 struct sockaddr_in addr_out;
3011 if(pid == share_entry->pid)
3013 /* We are breaking our own oplock, make sure it's us. */
3014 if(share_entry->op_port != oplock_port)
3016 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3017 should be %d\n", pid, share_entry->op_port, oplock_port));
3021 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3023 /* Call oplock break direct. */
3024 return oplock_break(dev, inode, &share_entry->time);
3027 /* We need to send a OPLOCK_BREAK_CMD message to the
3028 port in the share mode entry. */
3030 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3031 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3032 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3033 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3034 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3035 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3037 /* set the address and port */
3038 bzero((char *)&addr_out,sizeof(addr_out));
3039 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3040 addr_out.sin_port = htons( share_entry->op_port );
3041 addr_out.sin_family = AF_INET;
3043 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3044 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3046 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3047 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3049 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3050 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3051 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3057 * Now we must await the oplock broken message coming back
3058 * from the target smbd process. Timeout if it fails to
3059 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3060 * While we get messages that aren't ours, loop.
3065 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3066 int32 reply_msg_len;
3067 uint16 reply_from_port;
3068 char *reply_msg_start;
3070 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3071 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3073 if(smb_read_error == READ_TIMEOUT)
3075 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3076 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3077 share_entry->op_port, dev, inode));
3079 * This is a hack to make handling of failing clients more robust.
3080 * If a oplock break response message is not received in the timeout
3081 * period we may assume that the smbd servicing that client holding
3082 * the oplock has died and the client changes were lost anyway, so
3083 * we should continue to try and open the file.
3088 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3089 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3090 share_entry->op_port, dev, inode, strerror(errno)));
3095 * If the response we got was not an answer to our message, but
3096 * was a completely different request, push it onto the pending
3097 * udp message stack so that we can deal with it in the main loop.
3098 * It may be another oplock break request to us.
3102 * Local note from JRA. There exists the possibility of a denial
3103 * of service attack here by allowing non-root processes running
3104 * on a local machine sending many of these pending messages to
3105 * a smbd port. Currently I'm not sure how to restrict the messages
3106 * I will queue (although I could add a limit to the queue) to
3107 * those received by root processes only. There should be a
3108 * way to make this bulletproof....
3111 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3112 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3114 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3116 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3119 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3124 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3125 (reply_from_port != share_entry->op_port) ||
3126 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3127 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3128 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3130 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3131 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3132 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3133 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3141 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3146 /****************************************************************************
3147 Get the next SMB packet, doing the local message processing automatically.
3148 ****************************************************************************/
3150 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3152 BOOL got_smb = False;
3157 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3162 /* Deal with oplock break requests from other smbd's. */
3163 process_local_message(oplock_sock, inbuf, bufsize);
3167 if(ret && (CVAL(inbuf,0) == 0x85))
3169 /* Keepalive packet. */
3174 while(ret && !got_smb);
3179 /****************************************************************************
3180 check if a snum is in use
3181 ****************************************************************************/
3182 BOOL snum_used(int snum)
3185 for (i=0;i<MAX_CONNECTIONS;i++)
3186 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3191 /****************************************************************************
3192 reload the services file
3193 **************************************************************************/
3194 BOOL reload_services(BOOL test)
3201 pstrcpy(fname,lp_configfile());
3202 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3204 pstrcpy(servicesf,fname);
3211 if (test && !lp_file_list_changed())
3214 lp_killunused(snum_used);
3216 ret = lp_load(servicesf,False);
3218 /* perhaps the config filename is now set */
3220 reload_services(True);
3229 set_socket_options(Client,"SO_KEEPALIVE");
3230 set_socket_options(Client,user_socket_options);
3234 reset_mangled_stack( lp_mangledstack() );
3236 /* this forces service parameters to be flushed */
3237 become_service(-1,True);
3244 /****************************************************************************
3245 this prevents zombie child processes
3246 ****************************************************************************/
3247 static int sig_hup()
3249 BlockSignals(True,SIGHUP);
3250 DEBUG(0,("Got SIGHUP\n"));
3251 reload_services(False);
3252 #ifndef DONT_REINSTALL_SIG
3253 signal(SIGHUP,SIGNAL_CAST sig_hup);
3255 BlockSignals(False,SIGHUP);
3259 /****************************************************************************
3260 Setup the groups a user belongs to.
3261 ****************************************************************************/
3262 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3263 int **p_igroups, gid_t **p_groups,
3266 if (-1 == initgroups(user,gid))
3270 DEBUG(0,("Unable to initgroups!\n"));
3271 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3272 DEBUG(0,("This is probably a problem with the account %s\n",user));
3281 ngroups = getgroups(0,&grp);
3284 igroups = (int *)malloc(sizeof(int)*ngroups);
3285 attrs = (int *)malloc(sizeof(int)*ngroups);
3286 for (i=0;i<ngroups;i++)
3288 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3289 igroups[i] = 0x42424242;
3291 ngroups = getgroups(ngroups,(gid_t *)igroups);
3293 if (igroups[0] == 0x42424242)
3296 *p_ngroups = ngroups;
3299 /* The following bit of code is very strange. It is due to the
3300 fact that some OSes use int* and some use gid_t* for
3301 getgroups, and some (like SunOS) use both, one in prototypes,
3302 and one in man pages and the actual code. Thus we detect it
3303 dynamically using some very ugly code */
3306 /* does getgroups return ints or gid_t ?? */
3307 static BOOL groups_use_ints = True;
3309 if (groups_use_ints &&
3311 SVAL(igroups,2) == 0x4242)
3312 groups_use_ints = False;
3314 for (i=0;groups_use_ints && i<ngroups;i++)
3315 if (igroups[i] == 0x42424242)
3316 groups_use_ints = False;
3318 if (groups_use_ints)
3320 *p_igroups = igroups;
3321 *p_groups = (gid_t *)igroups;
3325 gid_t *groups = (gid_t *)igroups;
3326 igroups = (int *)malloc(sizeof(int)*ngroups);
3327 for (i=0;i<ngroups;i++)
3329 igroups[i] = groups[i];
3331 *p_igroups = igroups;
3332 *p_groups = (gid_t *)groups;
3335 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3336 for (i=0;i<ngroups;i++)
3337 DEBUG(3,("%d ",igroups[i]));
3343 /****************************************************************************
3344 make a connection to a service
3345 ****************************************************************************/
3346 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3350 struct passwd *pass = NULL;
3351 connection_struct *pcon;
3354 static BOOL first_connection = True;
3358 snum = find_service(service);
3361 if (strequal(service,"IPC$"))
3363 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3367 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3371 if (strequal(service,HOMES_NAME))
3373 if (*user && Get_Pwnam(user,True))
3374 return(make_connection(user,user,password,pwlen,dev,vuid));
3376 if (validated_username(vuid))
3378 strcpy(user,validated_username(vuid));
3379 return(make_connection(user,user,password,pwlen,dev,vuid));
3383 if (!lp_snum_ok(snum) || !check_access(snum)) {
3387 /* you can only connect to the IPC$ service as an ipc device */
3388 if (strequal(service,"IPC$"))
3391 if (*dev == '?' || !*dev)
3393 if (lp_print_ok(snum))
3394 strcpy(dev,"LPT1:");
3399 /* if the request is as a printer and you can't print then refuse */
3401 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3402 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3406 /* lowercase the user name */
3409 /* add it as a possible user name */
3410 add_session_user(service);
3412 /* shall we let them in? */
3413 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3415 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3419 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3422 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3426 pcon = &Connections[cnum];
3427 bzero((char *)pcon,sizeof(*pcon));
3429 /* find out some info about the user */
3430 pass = Get_Pwnam(user,True);
3434 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3438 pcon->read_only = lp_readonly(snum);
3442 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3443 string_sub(list,"%S",service);
3445 if (user_in_list(user,list))
3446 pcon->read_only = True;
3448 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3449 string_sub(list,"%S",service);
3451 if (user_in_list(user,list))
3452 pcon->read_only = False;
3455 /* admin user check */
3457 /* JRA - original code denied admin user if the share was
3458 marked read_only. Changed as I don't think this is needed,
3459 but old code left in case there is a problem here.
3461 if (user_in_list(user,lp_admin_users(snum))
3463 && !pcon->read_only)
3468 pcon->admin_user = True;
3469 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3472 pcon->admin_user = False;
3474 pcon->force_user = force;
3476 pcon->uid = pass->pw_uid;
3477 pcon->gid = pass->pw_gid;
3478 pcon->num_files_open = 0;
3479 pcon->lastused = time(NULL);
3480 pcon->service = snum;
3482 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3483 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3484 pcon->dirptr = NULL;
3485 pcon->veto_list = NULL;
3486 pcon->hide_list = NULL;
3487 pcon->veto_oplock_list = NULL;
3488 string_set(&pcon->dirpath,"");
3489 string_set(&pcon->user,user);
3492 if (*lp_force_group(snum))
3497 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3498 /* default service may be a group name */
3499 string_sub(gname,"%S",service);
3500 gptr = (struct group *)getgrnam(gname);
3504 pcon->gid = gptr->gr_gid;
3505 DEBUG(3,("Forced group %s\n",gname));
3508 DEBUG(1,("Couldn't find group %s\n",gname));
3512 if (*lp_force_user(snum))
3514 struct passwd *pass2;
3516 fstrcpy(fuser,lp_force_user(snum));
3517 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3520 pcon->uid = pass2->pw_uid;
3521 string_set(&pcon->user,fuser);
3522 fstrcpy(user,fuser);
3523 pcon->force_user = True;
3524 DEBUG(3,("Forced user %s\n",fuser));
3527 DEBUG(1,("Couldn't find user %s\n",fuser));
3532 pstrcpy(s,lp_pathname(snum));
3533 standard_sub(cnum,s);
3534 string_set(&pcon->connectpath,s);
3535 DEBUG(3,("Connect path is %s\n",s));
3538 /* groups stuff added by ih */
3540 pcon->igroups = NULL;
3541 pcon->groups = NULL;
3546 /* Find all the groups this uid is in and store them. Used by become_user() */
3547 setup_groups(pcon->user,pcon->uid,pcon->gid,
3548 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3550 /* check number of connections */
3551 if (!claim_connection(cnum,
3552 lp_servicename(SNUM(cnum)),
3553 lp_max_connections(SNUM(cnum)),False))
3555 DEBUG(1,("too many connections - rejected\n"));
3559 if (lp_status(SNUM(cnum)))
3560 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3562 first_connection = False;
3567 /* execute any "root preexec = " line */
3568 if (*lp_rootpreexec(SNUM(cnum)))
3571 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3572 standard_sub(cnum,cmd);
3573 DEBUG(5,("cmd=%s\n",cmd));
3574 smbrun(cmd,NULL,False);
3577 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3579 DEBUG(0,("Can't become connected user!\n"));
3581 if (!IS_IPC(cnum)) {
3582 yield_connection(cnum,
3583 lp_servicename(SNUM(cnum)),
3584 lp_max_connections(SNUM(cnum)));
3585 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3590 if (ChDir(pcon->connectpath) != 0)
3592 DEBUG(0,("Can't change directory to %s (%s)\n",
3593 pcon->connectpath,strerror(errno)));
3596 if (!IS_IPC(cnum)) {
3597 yield_connection(cnum,
3598 lp_servicename(SNUM(cnum)),
3599 lp_max_connections(SNUM(cnum)));
3600 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3605 string_set(&pcon->origpath,pcon->connectpath);
3607 #if SOFTLINK_OPTIMISATION
3608 /* resolve any soft links early */
3611 pstrcpy(s,pcon->connectpath);
3613 string_set(&pcon->connectpath,s);
3614 ChDir(pcon->connectpath);
3618 num_connections_open++;
3619 add_session_user(user);
3621 /* execute any "preexec = " line */
3622 if (*lp_preexec(SNUM(cnum)))
3625 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3626 standard_sub(cnum,cmd);
3627 smbrun(cmd,NULL,False);
3630 /* we've finished with the sensitive stuff */
3633 /* Add veto/hide lists */
3634 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3636 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3637 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3638 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3642 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3646 lp_servicename(SNUM(cnum)),user,
3656 /****************************************************************************
3657 find first available file slot
3658 ****************************************************************************/
3659 int find_free_file(void )
3662 static int first_file;
3664 /* we want to give out file handles differently on each new
3665 connection because of a common bug in MS clients where they try to
3666 reuse a file descriptor from an earlier smb connection. This code
3667 increases the chance that the errant client will get an error rather
3668 than causing corruption */
3669 if (first_file == 0) {
3670 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3671 if (first_file == 0) first_file = 1;
3674 for (i=first_file;i<MAX_OPEN_FILES;i++)
3675 if (!Files[i].open) {
3676 memset(&Files[i], 0, sizeof(Files[i]));
3680 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3681 for (i=1;i<first_file;i++)
3682 if (!Files[i].open) {
3683 memset(&Files[i], 0, sizeof(Files[i]));
3688 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3692 /****************************************************************************
3693 find first available connection slot, starting from a random position.
3694 The randomisation stops problems with the server dieing and clients
3695 thinking the server is still available.
3696 ****************************************************************************/
3697 static int find_free_connection(int hash )
3701 hash = (hash % (MAX_CONNECTIONS-2))+1;
3705 for (i=hash+1;i!=hash;)
3707 if (!Connections[i].open && Connections[i].used == used)
3709 DEBUG(3,("found free connection number %d\n",i));
3713 if (i == MAX_CONNECTIONS)
3723 DEBUG(1,("ERROR! Out of connection structures\n"));
3728 /****************************************************************************
3729 reply for the core protocol
3730 ****************************************************************************/
3731 int reply_corep(char *outbuf)
3733 int outsize = set_message(outbuf,1,0,True);
3735 Protocol = PROTOCOL_CORE;
3741 /****************************************************************************
3742 reply for the coreplus protocol
3743 ****************************************************************************/
3744 int reply_coreplus(char *outbuf)
3746 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3747 int outsize = set_message(outbuf,13,0,True);
3748 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3749 readbraw and writebraw (possibly) */
3750 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3751 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3753 Protocol = PROTOCOL_COREPLUS;
3759 /****************************************************************************
3760 reply for the lanman 1.0 protocol
3761 ****************************************************************************/
3762 int reply_lanman1(char *outbuf)
3764 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3766 BOOL doencrypt = SMBENCRYPT();
3767 time_t t = time(NULL);
3769 if (lp_security()>=SEC_USER) secword |= 1;
3770 if (doencrypt) secword |= 2;
3772 set_message(outbuf,13,doencrypt?8:0,True);
3773 SSVAL(outbuf,smb_vwv1,secword);
3774 /* Create a token value and add it to the outgoing packet. */
3776 generate_next_challenge(smb_buf(outbuf));
3778 Protocol = PROTOCOL_LANMAN1;
3780 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3781 SSVAL(outbuf,smb_vwv2,max_recv);
3782 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3783 SSVAL(outbuf,smb_vwv4,1);
3784 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3785 readbraw writebraw (possibly) */
3786 SIVAL(outbuf,smb_vwv6,getpid());
3787 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3789 put_dos_date(outbuf,smb_vwv8,t);
3791 return (smb_len(outbuf)+4);
3795 /****************************************************************************
3796 reply for the lanman 2.0 protocol
3797 ****************************************************************************/
3798 int reply_lanman2(char *outbuf)
3800 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3802 BOOL doencrypt = SMBENCRYPT();
3803 time_t t = time(NULL);
3804 struct cli_state *cli = NULL;
3808 if (lp_security() == SEC_SERVER) {
3809 cli = server_cryptkey();
3813 DEBUG(3,("using password server validation\n"));
3814 doencrypt = ((cli->sec_mode & 2) != 0);
3817 if (lp_security()>=SEC_USER) secword |= 1;
3818 if (doencrypt) secword |= 2;
3823 generate_next_challenge(cryptkey);
3825 memcpy(cryptkey, cli->cryptkey, 8);
3826 set_challenge(cli->cryptkey);
3830 set_message(outbuf,13,crypt_len,True);
3831 SSVAL(outbuf,smb_vwv1,secword);
3832 SIVAL(outbuf,smb_vwv6,getpid());
3834 memcpy(smb_buf(outbuf), cryptkey, 8);
3836 Protocol = PROTOCOL_LANMAN2;
3838 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3839 SSVAL(outbuf,smb_vwv2,max_recv);
3840 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3841 SSVAL(outbuf,smb_vwv4,1);
3842 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3843 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3844 put_dos_date(outbuf,smb_vwv8,t);
3846 return (smb_len(outbuf)+4);
3850 /****************************************************************************
3851 reply for the nt protocol
3852 ****************************************************************************/
3853 int reply_nt1(char *outbuf)
3855 /* dual names + lock_and_read + nt SMBs + remote API calls */
3856 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3858 other valid capabilities which we may support at some time...
3859 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3860 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3864 BOOL doencrypt = SMBENCRYPT();
3865 time_t t = time(NULL);
3867 struct cli_state *cli = NULL;
3871 if (lp_security() == SEC_SERVER) {
3872 cli = server_cryptkey();
3876 DEBUG(3,("using password server validation\n"));
3877 doencrypt = ((cli->sec_mode & 2) != 0);
3883 generate_next_challenge(cryptkey);
3885 memcpy(cryptkey, cli->cryptkey, 8);
3886 set_challenge(cli->cryptkey);
3890 if (lp_readraw() && lp_writeraw()) {
3891 capabilities |= CAP_RAW_MODE;
3894 if (lp_security() >= SEC_USER) secword |= 1;
3895 if (doencrypt) secword |= 2;
3897 /* decide where (if) to put the encryption challenge, and
3898 follow it with the OEM'd domain name
3900 data_len = crypt_len + strlen(myworkgroup) + 1;
3902 set_message(outbuf,17,data_len,True);
3903 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3905 CVAL(outbuf,smb_vwv1) = secword;
3906 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3908 memcpy(smb_buf(outbuf), cryptkey, 8);
3910 Protocol = PROTOCOL_NT1;
3912 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3913 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3914 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3915 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3916 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3917 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3918 put_long_date(outbuf+smb_vwv11+1,t);
3919 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3920 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3922 return (smb_len(outbuf)+4);
3925 /* these are the protocol lists used for auto architecture detection:
3928 protocol [PC NETWORK PROGRAM 1.0]
3929 protocol [XENIX CORE]
3930 protocol [MICROSOFT NETWORKS 1.03]
3931 protocol [LANMAN1.0]
3932 protocol [Windows for Workgroups 3.1a]
3933 protocol [LM1.2X002]
3934 protocol [LANMAN2.1]
3935 protocol [NT LM 0.12]
3938 protocol [PC NETWORK PROGRAM 1.0]
3939 protocol [XENIX CORE]
3940 protocol [MICROSOFT NETWORKS 1.03]
3941 protocol [LANMAN1.0]
3942 protocol [Windows for Workgroups 3.1a]
3943 protocol [LM1.2X002]
3944 protocol [LANMAN2.1]
3945 protocol [NT LM 0.12]
3948 protocol [PC NETWORK PROGRAM 1.0]
3949 protocol [XENIX CORE]
3950 protocol [LANMAN1.0]
3951 protocol [LM1.2X002]
3952 protocol [LANMAN2.1]
3956 * Modified to recognize the architecture of the remote machine better.
3958 * This appears to be the matrix of which protocol is used by which
3960 Protocol WfWg Win95 WinNT OS/2
3961 PC NETWORK PROGRAM 1.0 1 1 1 1
3963 MICROSOFT NETWORKS 3.0 2 2
3965 MICROSOFT NETWORKS 1.03 3
3968 Windows for Workgroups 3.1a 5 5 5
3973 * tim@fsg.com 09/29/95
3976 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3977 #define ARCH_WIN95 0x2
3978 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3979 #define ARCH_WINNT 0x8
3980 #define ARCH_SAMBA 0x10
3982 #define ARCH_ALL 0x1F
3984 /* List of supported protocols, most desired first */
3988 int (*proto_reply_fn)(char *);
3990 } supported_protocols[] = {
3991 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3992 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3993 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3994 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3995 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3996 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3997 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3998 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3999 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4004 /****************************************************************************
4006 ****************************************************************************/
4007 static int reply_negprot(char *inbuf,char *outbuf)
4009 int outsize = set_message(outbuf,1,0,True);
4014 int bcc = SVAL(smb_buf(inbuf),-2);
4015 int arch = ARCH_ALL;
4017 p = smb_buf(inbuf)+1;
4018 while (p < (smb_buf(inbuf) + bcc))
4021 DEBUG(3,("Requested protocol [%s]\n",p));
4022 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4023 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4024 else if (strcsequal(p,"DOS LM1.2X002"))
4025 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4026 else if (strcsequal(p,"DOS LANMAN2.1"))
4027 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4028 else if (strcsequal(p,"NT LM 0.12"))
4029 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4030 else if (strcsequal(p,"LANMAN2.1"))
4031 arch &= ( ARCH_WINNT | ARCH_OS2 );
4032 else if (strcsequal(p,"LM1.2X002"))
4033 arch &= ( ARCH_WINNT | ARCH_OS2 );
4034 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4036 else if (strcsequal(p,"XENIX CORE"))
4037 arch &= ( ARCH_WINNT | ARCH_OS2 );
4038 else if (strcsequal(p,"Samba")) {
4048 set_remote_arch(RA_SAMBA);
4051 set_remote_arch(RA_WFWG);
4054 set_remote_arch(RA_WIN95);
4057 set_remote_arch(RA_WINNT);
4060 set_remote_arch(RA_OS2);
4063 set_remote_arch(RA_UNKNOWN);
4067 /* possibly reload - change of architecture */
4068 reload_services(True);
4070 /* a special case to stop password server loops */
4071 if (Index == 1 && strequal(remote_machine,myhostname) &&
4072 lp_security()==SEC_SERVER)
4073 exit_server("Password server loop!");
4075 /* Check for protocols, most desirable first */
4076 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4078 p = smb_buf(inbuf)+1;
4080 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4081 while (p < (smb_buf(inbuf) + bcc))
4083 if (strequal(p,supported_protocols[protocol].proto_name))
4092 SSVAL(outbuf,smb_vwv0,choice);
4094 extern fstring remote_proto;
4095 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4096 reload_services(True);
4097 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4098 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4101 DEBUG(0,("No protocol supported !\n"));
4103 SSVAL(outbuf,smb_vwv0,choice);
4105 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4111 /****************************************************************************
4112 close all open files for a connection
4113 ****************************************************************************/
4114 static void close_open_files(int cnum)
4117 for (i=0;i<MAX_OPEN_FILES;i++)
4118 if( Files[i].cnum == cnum && Files[i].open) {
4119 close_file(i,False);
4125 /****************************************************************************
4127 ****************************************************************************/
4128 void close_cnum(int cnum, uint16 vuid)
4130 DirCacheFlush(SNUM(cnum));
4134 if (!OPEN_CNUM(cnum))
4136 DEBUG(0,("Can't close cnum %d\n",cnum));
4140 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4142 remote_machine,client_addr(),
4143 lp_servicename(SNUM(cnum))));
4145 yield_connection(cnum,
4146 lp_servicename(SNUM(cnum)),
4147 lp_max_connections(SNUM(cnum)));
4149 if (lp_status(SNUM(cnum)))
4150 yield_connection(cnum,"STATUS.",MAXSTATUS);
4152 close_open_files(cnum);
4153 dptr_closecnum(cnum);
4155 /* execute any "postexec = " line */
4156 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4159 strcpy(cmd,lp_postexec(SNUM(cnum)));
4160 standard_sub(cnum,cmd);
4161 smbrun(cmd,NULL,False);
4166 /* execute any "root postexec = " line */
4167 if (*lp_rootpostexec(SNUM(cnum)))
4170 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4171 standard_sub(cnum,cmd);
4172 smbrun(cmd,NULL,False);
4175 Connections[cnum].open = False;
4176 num_connections_open--;
4177 if (Connections[cnum].ngroups && Connections[cnum].groups)
4179 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4180 free(Connections[cnum].groups);
4181 free(Connections[cnum].igroups);
4182 Connections[cnum].groups = NULL;
4183 Connections[cnum].igroups = NULL;
4184 Connections[cnum].ngroups = 0;
4187 free_namearray(Connections[cnum].veto_list);
4188 free_namearray(Connections[cnum].hide_list);
4189 free_namearray(Connections[cnum].veto_oplock_list);
4191 string_set(&Connections[cnum].user,"");
4192 string_set(&Connections[cnum].dirpath,"");
4193 string_set(&Connections[cnum].connectpath,"");
4197 /****************************************************************************
4198 simple routines to do connection counting
4199 ****************************************************************************/
4200 BOOL yield_connection(int cnum,char *name,int max_connections)
4202 struct connect_record crec;
4205 int mypid = getpid();
4208 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4210 if (max_connections <= 0)
4213 bzero(&crec,sizeof(crec));
4215 pstrcpy(fname,lp_lockdir());
4216 standard_sub(cnum,fname);
4217 trim_string(fname,"","/");
4221 strcat(fname,".LCK");
4223 f = fopen(fname,"r+");
4226 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4230 fseek(f,0,SEEK_SET);
4232 /* find a free spot */
4233 for (i=0;i<max_connections;i++)
4235 if (fread(&crec,sizeof(crec),1,f) != 1)
4237 DEBUG(2,("Entry not found in lock file %s\n",fname));
4241 if (crec.pid == mypid && crec.cnum == cnum)
4245 if (crec.pid != mypid || crec.cnum != cnum)
4248 DEBUG(2,("Entry not found in lock file %s\n",fname));
4252 bzero((void *)&crec,sizeof(crec));
4254 /* remove our mark */
4255 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4256 fwrite(&crec,sizeof(crec),1,f) != 1)
4258 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4263 DEBUG(3,("Yield successful\n"));
4270 /****************************************************************************
4271 simple routines to do connection counting
4272 ****************************************************************************/
4273 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4275 struct connect_record crec;
4278 int snum = SNUM(cnum);
4282 if (max_connections <= 0)
4285 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4287 pstrcpy(fname,lp_lockdir());
4288 standard_sub(cnum,fname);
4289 trim_string(fname,"","/");
4291 if (!directory_exist(fname,NULL))
4296 strcat(fname,".LCK");
4298 if (!file_exist(fname,NULL))
4300 int oldmask = umask(022);
4301 f = fopen(fname,"w");
4306 total_recs = file_size(fname) / sizeof(crec);
4308 f = fopen(fname,"r+");
4312 DEBUG(1,("couldn't open lock file %s\n",fname));
4316 /* find a free spot */
4317 for (i=0;i<max_connections;i++)
4320 if (i>=total_recs ||
4321 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4322 fread(&crec,sizeof(crec),1,f) != 1)
4324 if (foundi < 0) foundi = i;
4328 if (Clear && crec.pid && !process_exists(crec.pid))
4330 fseek(f,i*sizeof(crec),SEEK_SET);
4331 bzero((void *)&crec,sizeof(crec));
4332 fwrite(&crec,sizeof(crec),1,f);
4333 if (foundi < 0) foundi = i;
4336 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4345 DEBUG(3,("no free locks in %s\n",fname));
4350 /* fill in the crec */
4351 bzero((void *)&crec,sizeof(crec));
4352 crec.magic = 0x280267;
4353 crec.pid = getpid();
4355 crec.uid = Connections[cnum].uid;
4356 crec.gid = Connections[cnum].gid;
4357 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4358 crec.start = time(NULL);
4360 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4361 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4364 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4365 fwrite(&crec,sizeof(crec),1,f) != 1)
4376 /*******************************************************************
4377 prepare to dump a core file - carefully!
4378 ********************************************************************/
4379 static BOOL dump_core(void)
4383 pstrcpy(dname,debugf);
4384 if ((p=strrchr(dname,'/'))) *p=0;
4385 strcat(dname,"/corefiles");
4387 sys_chown(dname,getuid(),getgid());
4389 if (chdir(dname)) return(False);
4392 #ifndef NO_GETRLIMIT
4396 getrlimit(RLIMIT_CORE, &rlp);
4397 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4398 setrlimit(RLIMIT_CORE, &rlp);
4399 getrlimit(RLIMIT_CORE, &rlp);
4400 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4406 DEBUG(0,("Dumping core in %s\n",dname));
4411 /****************************************************************************
4413 ****************************************************************************/
4414 void exit_server(char *reason)
4416 static int firsttime=1;
4419 if (!firsttime) exit(0);
4423 DEBUG(2,("Closing connections\n"));
4424 for (i=0;i<MAX_CONNECTIONS;i++)
4425 if (Connections[i].open)
4426 close_cnum(i,(uint16)-1);
4428 if (dcelogin_atmost_once)
4432 int oldlevel = DEBUGLEVEL;
4434 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4436 show_msg(last_inbuf);
4437 DEBUGLEVEL = oldlevel;
4438 DEBUG(0,("===============================================================\n"));
4440 if (dump_core()) return;
4446 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4450 /****************************************************************************
4451 do some standard substitutions in a string
4452 ****************************************************************************/
4453 void standard_sub(int cnum,char *str)
4455 if (VALID_CNUM(cnum)) {
4458 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4460 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4461 string_sub(p,"%H",home);
4465 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4466 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4467 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4468 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4469 case '\0' : p++; break; /* don't run off the end of the string */
4470 default : p+=2; break;
4474 standard_sub_basic(str);
4478 These flags determine some of the permissions required to do an operation
4480 Note that I don't set NEED_WRITE on some write operations because they
4481 are used by some brain-dead clients when printing, and I don't want to
4482 force write permissions on print services.
4484 #define AS_USER (1<<0)
4485 #define NEED_WRITE (1<<1)
4486 #define TIME_INIT (1<<2)
4487 #define CAN_IPC (1<<3)
4488 #define AS_GUEST (1<<5)
4492 define a list of possible SMB messages and their corresponding
4493 functions. Any message that has a NULL function is unimplemented -
4494 please feel free to contribute implementations!
4496 struct smb_message_struct
4510 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4511 {SMBtcon,"SMBtcon",reply_tcon,0},
4512 {SMBtdis,"SMBtdis",reply_tdis,0},
4513 {SMBexit,"SMBexit",reply_exit,0},
4514 {SMBioctl,"SMBioctl",reply_ioctl,0},
4515 {SMBecho,"SMBecho",reply_echo,0},
4516 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4517 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4518 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4519 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4520 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4521 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4522 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4523 {SMBopen,"SMBopen",reply_open,AS_USER},
4525 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4526 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4527 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4529 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4530 {SMBread,"SMBread",reply_read,AS_USER},
4531 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4532 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4533 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4534 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4535 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4536 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4538 /* this is a Pathworks specific call, allowing the
4539 changing of the root path */
4540 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4542 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4543 {SMBflush,"SMBflush",reply_flush,AS_USER},
4544 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4545 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4546 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4547 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4548 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4549 {SMBlock,"SMBlock",reply_lock,AS_USER},
4550 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4552 /* CORE+ PROTOCOL FOLLOWS */
4554 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4555 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4556 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4557 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4558 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4560 /* LANMAN1.0 PROTOCOL FOLLOWS */
4562 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4563 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4564 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4565 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4566 {SMBwritec,"SMBwritec",NULL,AS_USER},
4567 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4568 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4569 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4570 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4571 {SMBioctls,"SMBioctls",NULL,AS_USER},
4572 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4573 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4575 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4576 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4577 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4578 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4580 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4581 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4582 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4584 /* LANMAN2.0 PROTOCOL FOLLOWS */
4585 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4586 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4587 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4588 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4590 /* messaging routines */
4591 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4592 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4593 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4594 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4596 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4598 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4599 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4600 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4601 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4604 /****************************************************************************
4605 return a string containing the function name of a SMB command
4606 ****************************************************************************/
4607 char *smb_fn_name(int type)
4609 static char *unknown_name = "SMBunknown";
4610 static int num_smb_messages =
4611 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4614 for (match=0;match<num_smb_messages;match++)
4615 if (smb_messages[match].code == type)
4618 if (match == num_smb_messages)
4619 return(unknown_name);
4621 return(smb_messages[match].name);
4625 /****************************************************************************
4626 do a switch on the message type, and return the response size
4627 ****************************************************************************/
4628 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4632 static int num_smb_messages =
4633 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4637 struct timeval msg_start_time;
4638 struct timeval msg_end_time;
4639 static unsigned long total_time = 0;
4641 GetTimeOfDay(&msg_start_time);
4648 last_message = type;
4650 /* make sure this is an SMB packet */
4651 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4653 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4657 for (match=0;match<num_smb_messages;match++)
4658 if (smb_messages[match].code == type)
4661 if (match == num_smb_messages)
4663 DEBUG(0,("Unknown message type %d!\n",type));
4664 outsize = reply_unknown(inbuf,outbuf);
4668 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4669 if (smb_messages[match].fn)
4671 int cnum = SVAL(inbuf,smb_tid);
4672 int flags = smb_messages[match].flags;
4673 /* In share mode security we must ignore the vuid. */
4674 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4676 /* does this protocol need to be run as root? */
4677 if (!(flags & AS_USER))
4680 /* does this protocol need to be run as the connected user? */
4681 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4682 if (flags & AS_GUEST)
4685 return(ERROR(ERRSRV,ERRinvnid));
4687 /* this code is to work around a bug is MS client 3 without
4688 introducing a security hole - it needs to be able to do
4689 print queue checks as guest if it isn't logged in properly */
4690 if (flags & AS_USER)
4693 /* does it need write permission? */
4694 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4695 return(ERROR(ERRSRV,ERRaccess));
4697 /* ipc services are limited */
4698 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4699 return(ERROR(ERRSRV,ERRaccess));
4701 /* load service specific parameters */
4702 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4703 return(ERROR(ERRSRV,ERRaccess));
4705 /* does this protocol need to be run as guest? */
4706 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4707 return(ERROR(ERRSRV,ERRaccess));
4711 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4715 outsize = reply_unknown(inbuf,outbuf);
4720 GetTimeOfDay(&msg_end_time);
4721 if (!(smb_messages[match].flags & TIME_INIT))
4723 smb_messages[match].time = 0;
4724 smb_messages[match].flags |= TIME_INIT;
4727 unsigned long this_time =
4728 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4729 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4730 smb_messages[match].time += this_time;
4731 total_time += this_time;
4733 DEBUG(2,("TIME %s %d usecs %g pct\n",
4734 smb_fn_name(type),smb_messages[match].time,
4735 (100.0*smb_messages[match].time) / total_time));
4742 /****************************************************************************
4743 construct a chained reply and add it to the already made reply
4744 **************************************************************************/
4745 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4747 static char *orig_inbuf;
4748 static char *orig_outbuf;
4749 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4750 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4751 char *inbuf2, *outbuf2;
4753 char inbuf_saved[smb_wct];
4754 char outbuf_saved[smb_wct];
4755 extern int chain_size;
4756 int wct = CVAL(outbuf,smb_wct);
4757 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4759 /* maybe its not chained */
4760 if (smb_com2 == 0xFF) {
4761 CVAL(outbuf,smb_vwv0) = 0xFF;
4765 if (chain_size == 0) {
4766 /* this is the first part of the chain */
4768 orig_outbuf = outbuf;
4771 /* we need to tell the client where the next part of the reply will be */
4772 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4773 CVAL(outbuf,smb_vwv0) = smb_com2;
4775 /* remember how much the caller added to the chain, only counting stuff
4776 after the parameter words */
4777 chain_size += outsize - smb_wct;
4779 /* work out pointers into the original packets. The
4780 headers on these need to be filled in */
4781 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4782 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4784 /* remember the original command type */
4785 smb_com1 = CVAL(orig_inbuf,smb_com);
4787 /* save the data which will be overwritten by the new headers */
4788 memcpy(inbuf_saved,inbuf2,smb_wct);
4789 memcpy(outbuf_saved,outbuf2,smb_wct);
4791 /* give the new packet the same header as the last part of the SMB */
4792 memmove(inbuf2,inbuf,smb_wct);
4794 /* create the in buffer */
4795 CVAL(inbuf2,smb_com) = smb_com2;
4797 /* create the out buffer */
4798 bzero(outbuf2,smb_size);
4799 set_message(outbuf2,0,0,True);
4800 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4802 memcpy(outbuf2+4,inbuf2+4,4);
4803 CVAL(outbuf2,smb_rcls) = SUCCESS;
4804 CVAL(outbuf2,smb_reh) = 0;
4805 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4807 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4808 SSVAL(outbuf2,smb_err,SUCCESS);
4809 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4810 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4811 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4812 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4814 DEBUG(3,("Chained message\n"));
4817 /* process the request */
4818 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4819 bufsize-chain_size);
4821 /* copy the new reply and request headers over the old ones, but
4822 preserve the smb_com field */
4823 memmove(orig_outbuf,outbuf2,smb_wct);
4824 CVAL(orig_outbuf,smb_com) = smb_com1;
4826 /* restore the saved data, being careful not to overwrite any
4827 data from the reply header */
4828 memcpy(inbuf2,inbuf_saved,smb_wct);
4830 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4831 if (ofs < 0) ofs = 0;
4832 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4840 /****************************************************************************
4841 construct a reply to the incoming packet
4842 ****************************************************************************/
4843 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4845 int type = CVAL(inbuf,smb_com);
4847 int msg_type = CVAL(inbuf,0);
4848 extern int chain_size;
4850 smb_last_time = time(NULL);
4856 bzero(outbuf,smb_size);
4859 return(reply_special(inbuf,outbuf));
4861 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4862 set_message(outbuf,0,0,True);
4864 memcpy(outbuf+4,inbuf+4,4);
4865 CVAL(outbuf,smb_rcls) = SUCCESS;
4866 CVAL(outbuf,smb_reh) = 0;
4867 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4869 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4870 SSVAL(outbuf,smb_err,SUCCESS);
4871 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4872 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4873 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4874 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4876 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4878 outsize += chain_size;
4881 smb_setlen(outbuf,outsize - 4);
4885 /****************************************************************************
4886 process commands from the client
4887 ****************************************************************************/
4888 static void process(void)
4892 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4893 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4894 if ((InBuffer == NULL) || (OutBuffer == NULL))
4897 InBuffer += SMB_ALIGNMENT;
4898 OutBuffer += SMB_ALIGNMENT;
4901 DEBUG(3,("priming nmbd\n"));
4904 ip = *interpret_addr2("localhost");
4905 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4907 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4911 /* re-initialise the timezone */
4916 int deadtime = lp_deadtime()*60;
4918 int last_keepalive=0;
4919 int service_load_counter = 0;
4920 BOOL got_smb = False;
4923 deadtime = DEFAULT_SMBD_TIMEOUT;
4925 #if USE_READ_PREDICTION
4926 if (lp_readprediction())
4927 do_read_prediction();
4932 for (counter=SMBD_SELECT_LOOP;
4933 !receive_message_or_smb(Client,oplock_sock,
4934 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4935 counter += SMBD_SELECT_LOOP)
4939 BOOL allidle = True;
4940 extern int keepalive;
4942 if (counter > 365 * 3600) /* big number of seconds. */
4945 service_load_counter = 0;
4948 if (smb_read_error == READ_EOF)
4950 DEBUG(3,("end of file from client\n"));
4954 if (smb_read_error == READ_ERROR)
4956 DEBUG(3,("receive_smb error (%s) exiting\n",
4963 /* become root again if waiting */
4966 /* check for smb.conf reload */
4967 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4969 service_load_counter = counter;
4971 /* reload services, if files have changed. */
4972 reload_services(True);
4975 /* automatic timeout if all connections are closed */
4976 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4978 DEBUG(2,("%s Closing idle connection\n",timestring()));
4982 if (keepalive && (counter-last_keepalive)>keepalive)
4984 struct cli_state *cli = server_client();
4985 if (!send_keepalive(Client)) {
4986 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4989 /* also send a keepalive to the password server if its still
4991 if (cli && cli->initialised)
4992 send_keepalive(cli->fd);
4993 last_keepalive = counter;
4996 /* check for connection timeouts */
4997 for (i=0;i<MAX_CONNECTIONS;i++)
4998 if (Connections[i].open)
5000 /* close dirptrs on connections that are idle */
5001 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5004 if (Connections[i].num_files_open > 0 ||
5005 (t-Connections[i].lastused)<deadtime)
5009 if (allidle && num_connections_open>0)
5011 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5017 process_smb(InBuffer, OutBuffer);
5019 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5024 /****************************************************************************
5025 initialise connect, service and file structs
5026 ****************************************************************************/
5027 static void init_structs(void )
5030 get_myname(myhostname,NULL);
5032 for (i=0;i<MAX_CONNECTIONS;i++)
5034 Connections[i].open = False;
5035 Connections[i].num_files_open=0;
5036 Connections[i].lastused=0;
5037 Connections[i].used=False;
5038 string_init(&Connections[i].user,"");
5039 string_init(&Connections[i].dirpath,"");
5040 string_init(&Connections[i].connectpath,"");
5041 string_init(&Connections[i].origpath,"");
5044 for (i=0;i<MAX_OPEN_FILES;i++)
5046 Files[i].open = False;
5047 string_init(&Files[i].name,"");
5051 for (i=0;i<MAX_OPEN_FILES;i++)
5053 file_fd_struct *fd_ptr = &FileFd[i];
5054 fd_ptr->ref_count = 0;
5055 fd_ptr->dev = (int32)-1;
5056 fd_ptr->inode = (int32)-1;
5058 fd_ptr->fd_readonly = -1;
5059 fd_ptr->fd_writeonly = -1;
5060 fd_ptr->real_open_flags = -1;
5064 init_rpc_pipe_hnd();
5067 /* for LSA handles */
5068 init_lsa_policy_hnd();
5074 /****************************************************************************
5075 usage on the program
5076 ****************************************************************************/
5077 static void usage(char *pname)
5079 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5081 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5082 printf("Version %s\n",VERSION);
5083 printf("\t-D become a daemon\n");
5084 printf("\t-p port listen on the specified port\n");
5085 printf("\t-d debuglevel set the debuglevel\n");
5086 printf("\t-l log basename. Basename for log/debug files\n");
5087 printf("\t-s services file. Filename of services file\n");
5088 printf("\t-P passive only\n");
5089 printf("\t-a overwrite log file, don't append\n");
5094 /****************************************************************************
5096 ****************************************************************************/
5097 int main(int argc,char *argv[])
5099 extern BOOL append_log;
5100 /* shall I run as a daemon */
5101 BOOL is_daemon = False;
5102 int port = SMB_PORT;
5104 extern char *optarg;
5109 #ifdef NEED_AUTH_PARAMETERS
5110 set_auth_parameters(argc,argv);
5121 strcpy(debugf,SMBLOGFILE);
5123 setup_logging(argv[0],False);
5125 charset_initialise();
5127 /* make absolutely sure we run as root - to handle cases where people
5128 are crazy enough to have it setuid */
5138 fault_setup(exit_server);
5139 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5141 /* we want total control over the permissions on created files,
5142 so set our umask to 0 */
5149 /* this is for people who can't start the program correctly */
5150 while (argc > 1 && (*argv[1] != '-'))
5156 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5160 strncpy(pidFile, optarg, sizeof(pidFile));
5163 strcpy(user_socket_options,optarg);
5166 strcpy(scope,optarg);
5170 extern BOOL passive;
5175 strcpy(servicesf,optarg);
5178 strcpy(debugf,optarg);
5182 extern BOOL append_log;
5183 append_log = !append_log;
5193 DEBUGLEVEL = atoi(optarg);
5196 port = atoi(optarg);
5209 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5210 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5212 #ifndef NO_GETRLIMIT
5213 #ifdef RLIMIT_NOFILE
5216 getrlimit(RLIMIT_NOFILE, &rlp);
5217 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5218 setrlimit(RLIMIT_NOFILE, &rlp);
5219 getrlimit(RLIMIT_NOFILE, &rlp);
5220 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5226 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5227 getuid(),getgid(),geteuid(),getegid()));
5229 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5231 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5237 if (!reload_services(False))
5240 codepage_initialise(lp_client_code_page());
5242 strcpy(myworkgroup, lp_workgroup());
5244 #ifndef NO_SIGNAL_TEST
5245 signal(SIGHUP,SIGNAL_CAST sig_hup);
5248 /* Setup the signals that allow the debug log level
5249 to by dynamically changed. */
5251 #if defined(SIGUSR1)
5252 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5253 #endif /* SIGUSR1 */
5255 #if defined(SIGUSR2)
5256 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5257 #endif /* SIGUSR2 */
5259 DEBUG(3,("%s loaded services\n",timestring()));
5261 if (!is_daemon && !is_a_socket(0))
5263 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5269 DEBUG(3,("%s becoming a daemon\n",timestring()));
5273 if (!directory_exist(lp_lockdir(), NULL)) {
5274 mkdir(lp_lockdir(), 0755);
5282 if ((fd = open(pidFile,
5286 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5288 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5291 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5293 DEBUG(0,("ERROR: smbd is already running\n"));
5296 sprintf(buf, "%u\n", (unsigned int) getpid());
5297 if (write(fd, buf, strlen(buf)) < 0)
5299 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5302 /* Leave pid file open & locked for the duration... */
5305 if (!open_sockets(is_daemon,port))
5308 if (!locking_init(0))
5311 /* possibly reload the services file. */
5312 reload_services(True);
5314 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5318 if (sys_chroot(lp_rootdir()) == 0)
5319 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5322 /* Setup the oplock IPC socket. */
5323 if(!open_oplock_ipc())
5329 exit_server("normal exit");