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 Files[fnum].reserved = False;
1471 #if USE_READ_PREDICTION
1472 invalidate_read_prediction(fs_p->fd_ptr->fd);
1476 Connections[cnum].num_files_open--;
1479 free((char *)fs_p->wbmpx_ptr);
1480 fs_p->wbmpx_ptr = NULL;
1486 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1487 fs_p->mmap_ptr = NULL;
1491 if (lp_share_modes(SNUM(cnum)))
1493 lock_share_entry( cnum, dev, inode, &token);
1494 del_share_mode(token, fnum);
1497 fd_attempt_close(fs_p->fd_ptr);
1499 if (lp_share_modes(SNUM(cnum)))
1500 unlock_share_entry( cnum, dev, inode, token);
1502 /* NT uses smbclose to start a print - weird */
1503 if (normal_close && fs_p->print_file)
1506 /* check for magic scripts */
1508 check_magic(fnum,cnum);
1510 if(fs_p->granted_oplock == True)
1511 global_oplocks_open--;
1513 fs_p->sent_oplock_break = False;
1515 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1516 timestring(),Connections[cnum].user,fs_p->name,
1517 Connections[cnum].num_files_open));
1520 enum {AFAIL,AREAD,AWRITE,AALL};
1522 /*******************************************************************
1523 reproduce the share mode access table
1524 ********************************************************************/
1525 static int access_table(int new_deny,int old_deny,int old_mode,
1526 int share_pid,char *fname)
1528 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1530 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1532 if (old_deny == new_deny && share_pid == pid)
1535 if (old_mode == 0) return(AREAD);
1537 /* the new smbpub.zip spec says that if the file extension is
1538 .com, .dll, .exe or .sym then allow the open. I will force
1539 it to read-only as this seems sensible although the spec is
1540 a little unclear on this. */
1541 if ((fname = strrchr(fname,'.'))) {
1542 if (strequal(fname,".com") ||
1543 strequal(fname,".dll") ||
1544 strequal(fname,".exe") ||
1545 strequal(fname,".sym"))
1555 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1556 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1557 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1560 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1561 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1562 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1565 if (old_deny==DENY_WRITE) return(AREAD);
1566 if (old_deny==DENY_READ) return(AWRITE);
1567 if (old_deny==DENY_NONE) return(AALL);
1573 /*******************************************************************
1574 check if the share mode on a file allows it to be deleted or unlinked
1575 return True if sharing doesn't prevent the operation
1576 ********************************************************************/
1577 BOOL check_file_sharing(int cnum,char *fname)
1581 share_mode_entry *old_shares = 0;
1582 int num_share_modes;
1588 if(!lp_share_modes(SNUM(cnum)))
1591 if (stat(fname,&sbuf) == -1) return(True);
1593 dev = (uint32)sbuf.st_dev;
1594 inode = (uint32)sbuf.st_ino;
1596 lock_share_entry(cnum, dev, inode, &token);
1597 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1600 * Check if the share modes will give us access.
1603 if(num_share_modes != 0)
1610 broke_oplock = False;
1611 for(i = 0; i < num_share_modes; i++)
1613 share_mode_entry *share_entry = &old_shares[i];
1616 * Break oplocks before checking share modes. See comment in
1617 * open_file_shared for details.
1618 * Check if someone has an oplock on this file. If so we must
1619 * break it before continuing.
1621 if(share_entry->op_type & BATCH_OPLOCK)
1624 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1625 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1627 /* Oplock break.... */
1628 unlock_share_entry(cnum, dev, inode, token);
1629 if(request_oplock_break(share_entry, dev, inode) == False)
1631 free((char *)old_shares);
1632 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1633 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1636 lock_share_entry(cnum, dev, inode, &token);
1637 broke_oplock = True;
1641 /* someone else has a share lock on it, check to see
1643 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1650 free((char *)old_shares);
1651 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1653 } while(broke_oplock);
1656 /* XXXX exactly what share mode combinations should be allowed for
1657 deleting/renaming? */
1658 /* If we got here then either there were no share modes or
1659 all share modes were DENY_DOS and the pid == getpid() */
1664 unlock_share_entry(cnum, dev, inode, token);
1665 if(old_shares != NULL)
1666 free((char *)old_shares);
1670 /****************************************************************************
1672 Helper for open_file_shared.
1673 Truncate a file after checking locking; close file if locked.
1674 **************************************************************************/
1675 static void truncate_unless_locked(int fnum, int cnum, int token,
1678 if (Files[fnum].can_write){
1679 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1680 /* If share modes are in force for this connection we
1681 have the share entry locked. Unlock it before closing. */
1682 if (*share_locked && lp_share_modes(SNUM(cnum)))
1683 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1684 Files[fnum].fd_ptr->inode, token);
1685 close_file(fnum,False);
1686 /* Share mode no longer locked. */
1687 *share_locked = False;
1689 unix_ERR_class = ERRDOS;
1690 unix_ERR_code = ERRlock;
1693 ftruncate(Files[fnum].fd_ptr->fd,0);
1697 /****************************************************************************
1698 check if we can open a file with a share mode
1699 ****************************************************************************/
1700 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1701 BOOL fcbopen, int *flags)
1703 int old_open_mode = share->share_mode &0xF;
1704 int old_deny_mode = (share->share_mode >>4)&7;
1706 if (old_deny_mode > 4 || old_open_mode > 2)
1708 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1709 deny_mode,old_deny_mode,old_open_mode,fname));
1714 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1717 if ((access_allowed == AFAIL) ||
1718 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1719 (access_allowed == AREAD && *flags == O_WRONLY) ||
1720 (access_allowed == AWRITE && *flags == O_RDONLY))
1722 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1723 deny_mode,old_deny_mode,old_open_mode,
1724 share->pid,fname, fcbopen, *flags, access_allowed));
1728 if (access_allowed == AREAD)
1731 if (access_allowed == AWRITE)
1738 /****************************************************************************
1739 open a file with a share mode
1740 ****************************************************************************/
1741 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1742 int mode,int oplock_request, int *Access,int *action)
1744 files_struct *fs_p = &Files[fnum];
1747 int deny_mode = (share_mode>>4)&7;
1749 BOOL file_existed = file_exist(fname,&sbuf);
1750 BOOL share_locked = False;
1751 BOOL fcbopen = False;
1755 int num_share_modes = 0;
1760 /* this is for OS/2 EAs - try and say we don't support them */
1761 if (strstr(fname,".+,;=[]."))
1763 unix_ERR_class = ERRDOS;
1764 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1766 unix_ERR_code = ERRcannotopen;
1767 #else /* OS2_WPS_FIX */
1768 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1769 #endif /* OS2_WPS_FIX */
1774 if ((ofun & 0x3) == 0 && file_existed)
1782 if ((ofun & 0x3) == 2)
1785 /* note that we ignore the append flag as
1786 append does not mean the same thing under dos and unix */
1788 switch (share_mode&0xF)
1805 if (flags != O_RDONLY && file_existed &&
1806 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1816 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1818 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1823 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1825 if (lp_share_modes(SNUM(cnum)))
1828 share_mode_entry *old_shares = 0;
1832 dev = (uint32)sbuf.st_dev;
1833 inode = (uint32)sbuf.st_ino;
1834 lock_share_entry(cnum, dev, inode, &token);
1835 share_locked = True;
1836 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1840 * Check if the share modes will give us access.
1843 if(share_locked && (num_share_modes != 0))
1850 broke_oplock = False;
1851 for(i = 0; i < num_share_modes; i++)
1853 share_mode_entry *share_entry = &old_shares[i];
1856 * By observation of NetBench, oplocks are broken *before* share
1857 * modes are checked. This allows a file to be closed by the client
1858 * if the share mode would deny access and the client has an oplock.
1859 * Check if someone has an oplock on this file. If so we must break
1860 * it before continuing.
1862 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1865 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1866 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1868 /* Oplock break.... */
1869 unlock_share_entry(cnum, dev, inode, token);
1870 if(request_oplock_break(share_entry, dev, inode) == False)
1872 free((char *)old_shares);
1873 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1874 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1876 unix_ERR_class = ERRDOS;
1877 unix_ERR_code = ERRbadshare;
1880 lock_share_entry(cnum, dev, inode, &token);
1881 broke_oplock = True;
1885 /* someone else has a share lock on it, check to see
1887 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1889 free((char *)old_shares);
1890 unlock_share_entry(cnum, dev, inode, token);
1892 unix_ERR_class = ERRDOS;
1893 unix_ERR_code = ERRbadshare;
1901 free((char *)old_shares);
1902 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1904 } while(broke_oplock);
1908 free((char *)old_shares);
1911 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1912 flags,flags2,mode));
1914 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1915 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1918 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1925 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1927 /* We created the file - thus we must now lock the share entry before creating it. */
1928 dev = fs_p->fd_ptr->dev;
1929 inode = fs_p->fd_ptr->inode;
1930 lock_share_entry(cnum, dev, inode, &token);
1931 share_locked = True;
1947 fs_p->share_mode = (deny_mode<<4) | open_mode;
1950 (*Access) = open_mode;
1954 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1955 if (!file_existed) *action = 2;
1956 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1958 /* We must create the share mode entry before truncate as
1959 truncate can fail due to locking and have to close the
1960 file (which expects the share_mode_entry to be there).
1962 if (lp_share_modes(SNUM(cnum)))
1965 /* JRA. Currently this only services Exlcusive and batch
1966 oplocks (no other opens on this file). This needs to
1967 be extended to level II oplocks (multiple reader
1970 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
1971 !IS_VETO_OPLOCK_PATH(cnum,fname))
1973 fs_p->granted_oplock = True;
1974 fs_p->sent_oplock_break = False;
1975 global_oplocks_open++;
1978 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1979 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1987 set_share_mode(token, fnum, port, oplock_request);
1990 if ((flags2&O_TRUNC) && file_existed)
1991 truncate_unless_locked(fnum,cnum,token,&share_locked);
1994 if (share_locked && lp_share_modes(SNUM(cnum)))
1995 unlock_share_entry( cnum, dev, inode, token);
1998 /****************************************************************************
1999 seek a file. Try to avoid the seek if possible
2000 ****************************************************************************/
2001 int seek_file(int fnum,uint32 pos)
2004 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2007 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2009 return(Files[fnum].pos);
2012 /****************************************************************************
2014 ****************************************************************************/
2015 int read_file(int fnum,char *data,uint32 pos,int n)
2019 #if USE_READ_PREDICTION
2020 if (!Files[fnum].can_write)
2022 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2031 if (Files[fnum].mmap_ptr)
2033 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
2036 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2048 if (seek_file(fnum,pos) != pos)
2050 DEBUG(3,("Failed to seek to %d\n",pos));
2055 readret = read(Files[fnum].fd_ptr->fd,data,n);
2056 if (readret > 0) ret += readret;
2063 /****************************************************************************
2065 ****************************************************************************/
2066 int write_file(int fnum,char *data,int n)
2068 if (!Files[fnum].can_write) {
2073 if (!Files[fnum].modified) {
2075 Files[fnum].modified = True;
2076 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2077 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2078 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2079 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2084 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2088 /****************************************************************************
2089 load parameters specific to a connection/service
2090 ****************************************************************************/
2091 BOOL become_service(int cnum,BOOL do_chdir)
2093 extern char magic_char;
2094 static int last_cnum = -1;
2097 if (!OPEN_CNUM(cnum))
2103 Connections[cnum].lastused = smb_last_time;
2108 ChDir(Connections[cnum].connectpath) != 0 &&
2109 ChDir(Connections[cnum].origpath) != 0)
2111 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2112 Connections[cnum].connectpath,cnum));
2116 if (cnum == last_cnum)
2121 case_default = lp_defaultcase(snum);
2122 case_preserve = lp_preservecase(snum);
2123 short_case_preserve = lp_shortpreservecase(snum);
2124 case_mangle = lp_casemangle(snum);
2125 case_sensitive = lp_casesensitive(snum);
2126 magic_char = lp_magicchar(snum);
2127 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2132 /****************************************************************************
2133 find a service entry
2134 ****************************************************************************/
2135 int find_service(char *service)
2139 string_sub(service,"\\","/");
2141 iService = lp_servicenumber(service);
2143 /* now handle the special case of a home directory */
2146 char *phome_dir = get_home_dir(service);
2147 DEBUG(3,("checking for home directory %s gave %s\n",service,
2148 phome_dir?phome_dir:"(NULL)"));
2152 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2154 lp_add_home(service,iHomeService,phome_dir);
2155 iService = lp_servicenumber(service);
2160 /* If we still don't have a service, attempt to add it as a printer. */
2163 int iPrinterService;
2165 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2169 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2171 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2173 DEBUG(3,("%s is a valid printer name\n", service));
2174 DEBUG(3,("adding %s as a printer service\n", service));
2175 lp_add_printer(service,iPrinterService);
2176 iService = lp_servicenumber(service);
2178 DEBUG(0,("failed to add %s as a printer service!\n", service));
2181 DEBUG(3,("%s is not a valid printer name\n", service));
2185 /* just possibly it's a default service? */
2188 char *defservice = lp_defaultservice();
2189 if (defservice && *defservice && !strequal(defservice,service)) {
2190 iService = find_service(defservice);
2191 if (iService >= 0) {
2192 string_sub(service,"_","/");
2193 iService = lp_add_service(service,iService);
2199 if (!VALID_SNUM(iService))
2201 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2206 DEBUG(3,("find_service() failed to find service %s\n", service));
2212 /****************************************************************************
2213 create an error packet from a cached error.
2214 ****************************************************************************/
2215 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2217 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2219 int32 eclass = wbmpx->wr_errclass;
2220 int32 err = wbmpx->wr_error;
2222 /* We can now delete the auxiliary struct */
2223 free((char *)wbmpx);
2224 Files[fnum].wbmpx_ptr = NULL;
2225 return error_packet(inbuf,outbuf,eclass,err,line);
2234 } unix_smb_errmap[] =
2236 {EPERM,ERRDOS,ERRnoaccess},
2237 {EACCES,ERRDOS,ERRnoaccess},
2238 {ENOENT,ERRDOS,ERRbadfile},
2239 {ENOTDIR,ERRDOS,ERRbadpath},
2240 {EIO,ERRHRD,ERRgeneral},
2241 {EBADF,ERRSRV,ERRsrverror},
2242 {EINVAL,ERRSRV,ERRsrverror},
2243 {EEXIST,ERRDOS,ERRfilexists},
2244 {ENFILE,ERRDOS,ERRnofids},
2245 {EMFILE,ERRDOS,ERRnofids},
2246 {ENOSPC,ERRHRD,ERRdiskfull},
2248 {EDQUOT,ERRHRD,ERRdiskfull},
2251 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2254 {EXDEV,ERRDOS,ERRdiffdevice},
2256 {EROFS,ERRHRD,ERRnowrite},
2260 /****************************************************************************
2261 create an error packet from errno
2262 ****************************************************************************/
2263 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2265 int eclass=def_class;
2269 if (unix_ERR_class != SUCCESS)
2271 eclass = unix_ERR_class;
2272 ecode = unix_ERR_code;
2273 unix_ERR_class = SUCCESS;
2278 while (unix_smb_errmap[i].smbclass != 0)
2280 if (unix_smb_errmap[i].unixerror == errno)
2282 eclass = unix_smb_errmap[i].smbclass;
2283 ecode = unix_smb_errmap[i].smbcode;
2290 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2294 /****************************************************************************
2295 create an error packet. Normally called using the ERROR() macro
2296 ****************************************************************************/
2297 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2299 int outsize = set_message(outbuf,0,0,True);
2301 cmd = CVAL(inbuf,smb_com);
2303 CVAL(outbuf,smb_rcls) = error_class;
2304 SSVAL(outbuf,smb_err,error_code);
2306 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2309 (int)CVAL(inbuf,smb_com),
2310 smb_fn_name(CVAL(inbuf,smb_com)),
2315 DEBUG(3,("error string = %s\n",strerror(errno)));
2321 #ifndef SIGCLD_IGNORE
2322 /****************************************************************************
2323 this prevents zombie child processes
2324 ****************************************************************************/
2325 static int sig_cld()
2327 static int depth = 0;
2330 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2336 BlockSignals(True,SIGCLD);
2337 DEBUG(5,("got SIGCLD\n"));
2340 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2344 /* Stevens, Adv. Unix Prog. says that on system V you must call
2345 wait before reinstalling the signal handler, because the kernel
2346 calls the handler from within the signal-call when there is a
2347 child that has exited. This would lead to an infinite recursion
2348 if done vice versa. */
2350 #ifndef DONT_REINSTALL_SIG
2351 #ifdef SIGCLD_IGNORE
2352 signal(SIGCLD, SIG_IGN);
2354 signal(SIGCLD, SIGNAL_CAST sig_cld);
2359 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2362 BlockSignals(False,SIGCLD);
2367 /****************************************************************************
2368 this is called when the client exits abruptly
2369 **************************************************************************/
2370 static int sig_pipe()
2372 struct cli_state *cli;
2373 BlockSignals(True,SIGPIPE);
2375 if ((cli = server_client()) && cli->initialised) {
2376 DEBUG(3,("lost connection to password server\n"));
2378 #ifndef DONT_REINSTALL_SIG
2379 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2381 BlockSignals(False,SIGPIPE);
2385 exit_server("Got sigpipe\n");
2389 /****************************************************************************
2390 open the socket communication
2391 ****************************************************************************/
2392 static BOOL open_sockets(BOOL is_daemon,int port)
2398 int num_interfaces = iface_count();
2399 int fd_listenset[FD_SETSIZE];
2405 #ifdef SIGCLD_IGNORE
2406 signal(SIGCLD, SIG_IGN);
2408 signal(SIGCLD, SIGNAL_CAST sig_cld);
2414 FD_ZERO(&listen_set);
2416 if(lp_interfaces() && lp_bind_interfaces_only())
2418 /* We have been given an interfaces line, and been
2419 told to only bind to those interfaces. Create a
2420 socket per interface and bind to only these.
2423 if(num_interfaces > FD_SETSIZE)
2425 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2426 max can be %d\n", num_interfaces, FD_SETSIZE));
2430 /* Now open a listen socket for each of the interfaces. */
2431 for(i = 0; i < num_interfaces; i++)
2433 struct in_addr *ifip = iface_n_ip(i);
2437 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2440 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2443 /* ready to listen */
2444 if (listen(s, 5) == -1)
2446 DEBUG(0,("listen: %s\n",strerror(errno)));
2450 FD_SET(s,&listen_set);
2455 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2458 /* open an incoming socket */
2459 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2463 /* ready to listen */
2464 if (listen(s, 5) == -1)
2466 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2471 fd_listenset[0] = s;
2472 FD_SET(s,&listen_set);
2475 /* now accept incoming connections - forking a new process
2476 for each incoming connection */
2477 DEBUG(2,("waiting for a connection\n"));
2483 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2485 num = sys_select(&lfds,NULL);
2487 if (num == -1 && errno == EINTR)
2490 /* Find the sockets that are read-ready - accept on these. */
2491 for( ; num > 0; num--)
2493 struct sockaddr addr;
2494 int in_addrlen = sizeof(addr);
2497 for(i = 0; i < num_interfaces; i++)
2499 if(FD_ISSET(fd_listenset[i],&lfds))
2501 s = fd_listenset[i];
2502 /* Clear this so we don't look at it again. */
2503 FD_CLR(fd_listenset[i],&lfds);
2508 Client = accept(s,&addr,&in_addrlen);
2510 if (Client == -1 && errno == EINTR)
2515 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2519 #ifdef NO_FORK_DEBUG
2520 #ifndef NO_SIGNAL_TEST
2521 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2522 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2523 #endif /* NO_SIGNAL_TEST */
2525 #else /* NO_FORK_DEBUG */
2526 if (Client != -1 && fork()==0)
2528 /* Child code ... */
2530 #ifndef NO_SIGNAL_TEST
2531 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2532 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2533 #endif /* NO_SIGNAL_TEST */
2534 /* close the listening socket(s) */
2535 for(i = 0; i < num_interfaces; i++)
2536 close(fd_listenset[i]);
2538 /* close our standard file descriptors */
2542 set_socket_options(Client,"SO_KEEPALIVE");
2543 set_socket_options(Client,user_socket_options);
2545 /* Reset global variables in util.c so that
2546 client substitutions will be done correctly
2549 reset_globals_after_fork();
2552 close(Client); /* The parent doesn't need this socket */
2553 #endif /* NO_FORK_DEBUG */
2556 } /* end if is_daemon */
2559 /* Started from inetd. fd 0 is the socket. */
2560 /* We will abort gracefully when the client or remote system
2562 #ifndef NO_SIGNAL_TEST
2563 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2567 /* close our standard file descriptors */
2570 set_socket_options(Client,"SO_KEEPALIVE");
2571 set_socket_options(Client,user_socket_options);
2577 /****************************************************************************
2578 process an smb from the client - split out from the process() code so
2579 it can be used by the oplock break code.
2580 ****************************************************************************/
2582 static void process_smb(char *inbuf, char *outbuf)
2585 static int trans_num;
2586 int msg_type = CVAL(inbuf,0);
2587 int32 len = smb_len(inbuf);
2588 int nread = len + 4;
2590 if (trans_num == 0) {
2591 /* on the first packet, check the global hosts allow/ hosts
2592 deny parameters before doing any parsing of the packet
2593 passed to us by the client. This prevents attacks on our
2594 parsing code from hosts not in the hosts allow list */
2595 if (!check_access(-1)) {
2596 /* send a negative session response "not listining on calling
2598 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2599 DEBUG(1,("%s Connection denied from %s\n",
2600 timestring(),client_addr()));
2601 send_smb(Client,(char *)buf);
2602 exit_server("connection denied");
2606 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2607 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2610 if(trans_num == 1 && VT_Check(inbuf))
2619 else if(msg_type == 0x85)
2620 return; /* Keepalive packet. */
2622 nread = construct_reply(inbuf,outbuf,nread,max_send);
2626 if (CVAL(outbuf,0) == 0)
2629 if (nread != smb_len(outbuf) + 4)
2631 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2632 nread, smb_len(outbuf)));
2635 send_smb(Client,outbuf);
2640 /****************************************************************************
2641 open the oplock IPC socket communication
2642 ****************************************************************************/
2643 static BOOL open_oplock_ipc()
2645 struct sockaddr_in sock_name;
2646 int len = sizeof(sock_name);
2648 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2650 /* Open a lookback UDP socket on a random port. */
2651 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2652 if (oplock_sock == -1)
2654 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2655 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2660 /* Find out the transient UDP port we have been allocated. */
2661 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2663 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2670 oplock_port = ntohs(sock_name.sin_port);
2672 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2673 getpid(), oplock_port));
2678 /****************************************************************************
2679 process an oplock break message.
2680 ****************************************************************************/
2681 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2687 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2688 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2690 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2692 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2693 msg_len, from_port));
2695 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2696 only valid request. */
2698 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2700 case OPLOCK_BREAK_CMD:
2701 /* Ensure that the msg length is correct. */
2702 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2704 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2705 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2709 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2710 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2711 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2712 struct timeval tval;
2713 struct sockaddr_in toaddr;
2715 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2716 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2718 DEBUG(5,("process_local_message: oplock break request from \
2719 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2722 * If we have no record of any currently open oplocks,
2723 * it's not an error, as a close command may have
2724 * just been issued on the file that was oplocked.
2725 * Just return success in this case.
2728 if(global_oplocks_open != 0)
2730 if(oplock_break(dev, inode, &tval) == False)
2732 DEBUG(0,("process_local_message: oplock break failed - \
2733 not returning udp message.\n"));
2739 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2740 oplocks. Returning success.\n"));
2743 /* Send the message back after OR'ing in the 'REPLY' bit. */
2744 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2746 bzero((char *)&toaddr,sizeof(toaddr));
2747 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2748 toaddr.sin_port = htons(from_port);
2749 toaddr.sin_family = AF_INET;
2751 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2752 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2754 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2755 remotepid, strerror(errno)));
2759 DEBUG(5,("process_local_message: oplock break reply sent to \
2760 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2761 from_port, dev, inode));
2766 * Keep this as a debug case - eventually we can remove it.
2769 DEBUG(0,("process_local_message: Received unsolicited break \
2770 reply - dumping info.\n"));
2772 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2774 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2775 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2780 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2781 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2782 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2784 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2785 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2791 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2792 (unsigned int)SVAL(msg_start,0)));
2798 /****************************************************************************
2799 Process an oplock break directly.
2800 ****************************************************************************/
2801 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2805 char *outbuf = NULL;
2806 files_struct *fsp = NULL;
2809 BOOL shutdown_server = False;
2811 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2812 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2814 /* We need to search the file open table for the
2815 entry containing this dev and inode, and ensure
2816 we have an oplock on it. */
2817 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2821 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2822 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2823 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2832 /* The file could have been closed in the meantime - return success. */
2833 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2834 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2838 /* Ensure we have an oplock on the file */
2840 /* There is a potential race condition in that an oplock could
2841 have been broken due to another udp request, and yet there are
2842 still oplock break messages being sent in the udp message
2843 queue for this file. So return true if we don't have an oplock,
2844 as we may have just freed it.
2847 if(!fsp->granted_oplock)
2849 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));
2853 /* mark the oplock break as sent - we don't want to send twice! */
2854 if (fsp->sent_oplock_break)
2856 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));
2858 /* We have to fail the open here as we cannot send another oplock break on this
2859 file whilst we are awaiting a response from the client - neither can we
2860 allow another open to succeed while we are waiting for the client. */
2864 /* Now comes the horrid part. We must send an oplock break to the client,
2865 and then process incoming messages until we get a close or oplock release.
2866 At this point we know we need a new inbuf/outbuf buffer pair.
2867 We cannot use these staticaly as we may recurse into here due to
2868 messages crossing on the wire.
2871 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2873 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2877 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2879 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2885 /* Prepare the SMBlockingX message. */
2886 bzero(outbuf,smb_size);
2887 set_message(outbuf,8,0,True);
2889 SCVAL(outbuf,smb_com,SMBlockingX);
2890 SSVAL(outbuf,smb_tid,fsp->cnum);
2891 SSVAL(outbuf,smb_pid,0xFFFF);
2892 SSVAL(outbuf,smb_uid,0);
2893 SSVAL(outbuf,smb_mid,0xFFFF);
2894 SCVAL(outbuf,smb_vwv0,0xFF);
2895 SSVAL(outbuf,smb_vwv2,fnum);
2896 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2897 /* Change this when we have level II oplocks. */
2898 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2900 send_smb(Client, outbuf);
2902 /* Remember we just sent an oplock break on this file. */
2903 fsp->sent_oplock_break = True;
2905 /* We need this in case a readraw crosses on the wire. */
2906 global_oplock_break = True;
2908 /* Process incoming messages. */
2910 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2911 seconds we should just die.... */
2913 start_time = time(NULL);
2915 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2917 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2920 * Die if we got an error.
2923 if (smb_read_error == READ_EOF)
2924 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2926 if (smb_read_error == READ_ERROR)
2927 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2928 timestring(), strerror(errno)));
2930 if (smb_read_error == READ_TIMEOUT)
2931 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2932 timestring(), OPLOCK_BREAK_TIMEOUT));
2934 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2935 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2936 shutdown_server = True;
2939 process_smb(inbuf, outbuf);
2942 * Die if we go over the time limit.
2945 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2947 DEBUG(0,("%s oplock_break: no break received from client within \
2948 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2949 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2950 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2951 shutdown_server = True;
2956 /* Free the buffers we've been using to recurse. */
2960 /* We need this in case a readraw crossed on the wire. */
2961 if(global_oplock_break)
2962 global_oplock_break = False;
2965 * If the client did not respond we must die.
2970 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2974 exit_server("oplock break failure");
2979 /* The lockingX reply will have removed the oplock flag
2980 from the sharemode. */
2982 fsp->granted_oplock = False;
2983 fsp->sent_oplock_break = False;
2984 global_oplocks_open--;
2987 /* Santity check - remove this later. JRA */
2988 if(global_oplocks_open < 0)
2990 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2991 global_oplocks_open));
2992 exit_server("oplock_break: global_oplocks_open < 0");
2995 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2996 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3001 /****************************************************************************
3002 Send an oplock break message to another smbd process. If the oplock is held
3003 by the local smbd then call the oplock break function directly.
3004 ****************************************************************************/
3006 BOOL request_oplock_break(share_mode_entry *share_entry,
3007 uint32 dev, uint32 inode)
3009 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3010 struct sockaddr_in addr_out;
3013 if(pid == share_entry->pid)
3015 /* We are breaking our own oplock, make sure it's us. */
3016 if(share_entry->op_port != oplock_port)
3018 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3019 should be %d\n", pid, share_entry->op_port, oplock_port));
3023 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3025 /* Call oplock break direct. */
3026 return oplock_break(dev, inode, &share_entry->time);
3029 /* We need to send a OPLOCK_BREAK_CMD message to the
3030 port in the share mode entry. */
3032 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3033 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3034 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3035 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3036 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3037 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3039 /* set the address and port */
3040 bzero((char *)&addr_out,sizeof(addr_out));
3041 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3042 addr_out.sin_port = htons( share_entry->op_port );
3043 addr_out.sin_family = AF_INET;
3045 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3046 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3048 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3049 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3051 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3052 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3053 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3059 * Now we must await the oplock broken message coming back
3060 * from the target smbd process. Timeout if it fails to
3061 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3062 * While we get messages that aren't ours, loop.
3067 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3068 int32 reply_msg_len;
3069 uint16 reply_from_port;
3070 char *reply_msg_start;
3072 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3073 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3075 if(smb_read_error == READ_TIMEOUT)
3077 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3078 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3079 share_entry->op_port, dev, inode));
3081 * This is a hack to make handling of failing clients more robust.
3082 * If a oplock break response message is not received in the timeout
3083 * period we may assume that the smbd servicing that client holding
3084 * the oplock has died and the client changes were lost anyway, so
3085 * we should continue to try and open the file.
3090 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3091 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3092 share_entry->op_port, dev, inode, strerror(errno)));
3097 * If the response we got was not an answer to our message, but
3098 * was a completely different request, push it onto the pending
3099 * udp message stack so that we can deal with it in the main loop.
3100 * It may be another oplock break request to us.
3104 * Local note from JRA. There exists the possibility of a denial
3105 * of service attack here by allowing non-root processes running
3106 * on a local machine sending many of these pending messages to
3107 * a smbd port. Currently I'm not sure how to restrict the messages
3108 * I will queue (although I could add a limit to the queue) to
3109 * those received by root processes only. There should be a
3110 * way to make this bulletproof....
3113 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3114 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3116 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3118 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3121 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3126 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3127 (reply_from_port != share_entry->op_port) ||
3128 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3129 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3130 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3132 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3133 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3134 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3135 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3143 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3148 /****************************************************************************
3149 Get the next SMB packet, doing the local message processing automatically.
3150 ****************************************************************************/
3152 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3154 BOOL got_smb = False;
3159 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3164 /* Deal with oplock break requests from other smbd's. */
3165 process_local_message(oplock_sock, inbuf, bufsize);
3169 if(ret && (CVAL(inbuf,0) == 0x85))
3171 /* Keepalive packet. */
3176 while(ret && !got_smb);
3181 /****************************************************************************
3182 check if a snum is in use
3183 ****************************************************************************/
3184 BOOL snum_used(int snum)
3187 for (i=0;i<MAX_CONNECTIONS;i++)
3188 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3193 /****************************************************************************
3194 reload the services file
3195 **************************************************************************/
3196 BOOL reload_services(BOOL test)
3203 pstrcpy(fname,lp_configfile());
3204 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3206 pstrcpy(servicesf,fname);
3213 if (test && !lp_file_list_changed())
3216 lp_killunused(snum_used);
3218 ret = lp_load(servicesf,False);
3220 /* perhaps the config filename is now set */
3222 reload_services(True);
3231 set_socket_options(Client,"SO_KEEPALIVE");
3232 set_socket_options(Client,user_socket_options);
3236 reset_mangled_stack( lp_mangledstack() );
3238 /* this forces service parameters to be flushed */
3239 become_service(-1,True);
3246 /****************************************************************************
3247 this prevents zombie child processes
3248 ****************************************************************************/
3249 static int sig_hup()
3251 BlockSignals(True,SIGHUP);
3252 DEBUG(0,("Got SIGHUP\n"));
3253 reload_services(False);
3254 #ifndef DONT_REINSTALL_SIG
3255 signal(SIGHUP,SIGNAL_CAST sig_hup);
3257 BlockSignals(False,SIGHUP);
3261 /****************************************************************************
3262 Setup the groups a user belongs to.
3263 ****************************************************************************/
3264 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3265 int **p_igroups, gid_t **p_groups,
3268 if (-1 == initgroups(user,gid))
3272 DEBUG(0,("Unable to initgroups!\n"));
3273 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3274 DEBUG(0,("This is probably a problem with the account %s\n",user));
3283 ngroups = getgroups(0,&grp);
3286 igroups = (int *)malloc(sizeof(int)*ngroups);
3287 attrs = (int *)malloc(sizeof(int)*ngroups);
3288 for (i=0;i<ngroups;i++)
3290 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3291 igroups[i] = 0x42424242;
3293 ngroups = getgroups(ngroups,(gid_t *)igroups);
3295 if (igroups[0] == 0x42424242)
3298 *p_ngroups = ngroups;
3301 /* The following bit of code is very strange. It is due to the
3302 fact that some OSes use int* and some use gid_t* for
3303 getgroups, and some (like SunOS) use both, one in prototypes,
3304 and one in man pages and the actual code. Thus we detect it
3305 dynamically using some very ugly code */
3308 /* does getgroups return ints or gid_t ?? */
3309 static BOOL groups_use_ints = True;
3311 if (groups_use_ints &&
3313 SVAL(igroups,2) == 0x4242)
3314 groups_use_ints = False;
3316 for (i=0;groups_use_ints && i<ngroups;i++)
3317 if (igroups[i] == 0x42424242)
3318 groups_use_ints = False;
3320 if (groups_use_ints)
3322 *p_igroups = igroups;
3323 *p_groups = (gid_t *)igroups;
3327 gid_t *groups = (gid_t *)igroups;
3328 igroups = (int *)malloc(sizeof(int)*ngroups);
3329 for (i=0;i<ngroups;i++)
3331 igroups[i] = groups[i];
3333 *p_igroups = igroups;
3334 *p_groups = (gid_t *)groups;
3337 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3338 for (i=0;i<ngroups;i++)
3339 DEBUG(3,("%d ",igroups[i]));
3345 /****************************************************************************
3346 make a connection to a service
3347 ****************************************************************************/
3348 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3352 struct passwd *pass = NULL;
3353 connection_struct *pcon;
3356 static BOOL first_connection = True;
3360 snum = find_service(service);
3363 if (strequal(service,"IPC$"))
3365 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3369 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3373 if (strequal(service,HOMES_NAME))
3375 if (*user && Get_Pwnam(user,True))
3376 return(make_connection(user,user,password,pwlen,dev,vuid));
3378 if (validated_username(vuid))
3380 strcpy(user,validated_username(vuid));
3381 return(make_connection(user,user,password,pwlen,dev,vuid));
3385 if (!lp_snum_ok(snum) || !check_access(snum)) {
3389 /* you can only connect to the IPC$ service as an ipc device */
3390 if (strequal(service,"IPC$"))
3393 if (*dev == '?' || !*dev)
3395 if (lp_print_ok(snum))
3396 strcpy(dev,"LPT1:");
3401 /* if the request is as a printer and you can't print then refuse */
3403 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3404 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3408 /* lowercase the user name */
3411 /* add it as a possible user name */
3412 add_session_user(service);
3414 /* shall we let them in? */
3415 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3417 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3421 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3424 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3428 pcon = &Connections[cnum];
3429 bzero((char *)pcon,sizeof(*pcon));
3431 /* find out some info about the user */
3432 pass = Get_Pwnam(user,True);
3436 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3440 pcon->read_only = lp_readonly(snum);
3444 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3445 string_sub(list,"%S",service);
3447 if (user_in_list(user,list))
3448 pcon->read_only = True;
3450 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3451 string_sub(list,"%S",service);
3453 if (user_in_list(user,list))
3454 pcon->read_only = False;
3457 /* admin user check */
3459 /* JRA - original code denied admin user if the share was
3460 marked read_only. Changed as I don't think this is needed,
3461 but old code left in case there is a problem here.
3463 if (user_in_list(user,lp_admin_users(snum))
3465 && !pcon->read_only)
3470 pcon->admin_user = True;
3471 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3474 pcon->admin_user = False;
3476 pcon->force_user = force;
3478 pcon->uid = pass->pw_uid;
3479 pcon->gid = pass->pw_gid;
3480 pcon->num_files_open = 0;
3481 pcon->lastused = time(NULL);
3482 pcon->service = snum;
3484 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3485 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3486 pcon->dirptr = NULL;
3487 pcon->veto_list = NULL;
3488 pcon->hide_list = NULL;
3489 pcon->veto_oplock_list = NULL;
3490 string_set(&pcon->dirpath,"");
3491 string_set(&pcon->user,user);
3494 if (*lp_force_group(snum))
3499 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3500 /* default service may be a group name */
3501 string_sub(gname,"%S",service);
3502 gptr = (struct group *)getgrnam(gname);
3506 pcon->gid = gptr->gr_gid;
3507 DEBUG(3,("Forced group %s\n",gname));
3510 DEBUG(1,("Couldn't find group %s\n",gname));
3514 if (*lp_force_user(snum))
3516 struct passwd *pass2;
3518 fstrcpy(fuser,lp_force_user(snum));
3519 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3522 pcon->uid = pass2->pw_uid;
3523 string_set(&pcon->user,fuser);
3524 fstrcpy(user,fuser);
3525 pcon->force_user = True;
3526 DEBUG(3,("Forced user %s\n",fuser));
3529 DEBUG(1,("Couldn't find user %s\n",fuser));
3534 pstrcpy(s,lp_pathname(snum));
3535 standard_sub(cnum,s);
3536 string_set(&pcon->connectpath,s);
3537 DEBUG(3,("Connect path is %s\n",s));
3540 /* groups stuff added by ih */
3542 pcon->igroups = NULL;
3543 pcon->groups = NULL;
3548 /* Find all the groups this uid is in and store them. Used by become_user() */
3549 setup_groups(pcon->user,pcon->uid,pcon->gid,
3550 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3552 /* check number of connections */
3553 if (!claim_connection(cnum,
3554 lp_servicename(SNUM(cnum)),
3555 lp_max_connections(SNUM(cnum)),False))
3557 DEBUG(1,("too many connections - rejected\n"));
3561 if (lp_status(SNUM(cnum)))
3562 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3564 first_connection = False;
3569 /* execute any "root preexec = " line */
3570 if (*lp_rootpreexec(SNUM(cnum)))
3573 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3574 standard_sub(cnum,cmd);
3575 DEBUG(5,("cmd=%s\n",cmd));
3576 smbrun(cmd,NULL,False);
3579 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3581 DEBUG(0,("Can't become connected user!\n"));
3583 if (!IS_IPC(cnum)) {
3584 yield_connection(cnum,
3585 lp_servicename(SNUM(cnum)),
3586 lp_max_connections(SNUM(cnum)));
3587 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3592 if (ChDir(pcon->connectpath) != 0)
3594 DEBUG(0,("Can't change directory to %s (%s)\n",
3595 pcon->connectpath,strerror(errno)));
3598 if (!IS_IPC(cnum)) {
3599 yield_connection(cnum,
3600 lp_servicename(SNUM(cnum)),
3601 lp_max_connections(SNUM(cnum)));
3602 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3607 string_set(&pcon->origpath,pcon->connectpath);
3609 #if SOFTLINK_OPTIMISATION
3610 /* resolve any soft links early */
3613 pstrcpy(s,pcon->connectpath);
3615 string_set(&pcon->connectpath,s);
3616 ChDir(pcon->connectpath);
3620 num_connections_open++;
3621 add_session_user(user);
3623 /* execute any "preexec = " line */
3624 if (*lp_preexec(SNUM(cnum)))
3627 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3628 standard_sub(cnum,cmd);
3629 smbrun(cmd,NULL,False);
3632 /* we've finished with the sensitive stuff */
3635 /* Add veto/hide lists */
3636 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3638 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3639 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3640 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3644 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3648 lp_servicename(SNUM(cnum)),user,
3658 /****************************************************************************
3659 find first available file slot
3660 ****************************************************************************/
3661 int find_free_file(void )
3664 static int first_file;
3666 /* we want to give out file handles differently on each new
3667 connection because of a common bug in MS clients where they try to
3668 reuse a file descriptor from an earlier smb connection. This code
3669 increases the chance that the errant client will get an error rather
3670 than causing corruption */
3671 if (first_file == 0) {
3672 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3673 if (first_file == 0) first_file = 1;
3676 if (first_file >= MAX_OPEN_FILES)
3679 for (i=first_file;i<MAX_OPEN_FILES;i++)
3680 if (!Files[i].open && !Files[i].reserved) {
3681 memset(&Files[i], 0, sizeof(Files[i]));
3683 Files[i].reserved = True;
3687 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3688 for (i=1;i<first_file;i++)
3689 if (!Files[i].open && !Files[i].reserved) {
3690 memset(&Files[i], 0, sizeof(Files[i]));
3692 Files[i].reserved = True;
3697 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3701 /****************************************************************************
3702 find first available connection slot, starting from a random position.
3703 The randomisation stops problems with the server dieing and clients
3704 thinking the server is still available.
3705 ****************************************************************************/
3706 static int find_free_connection(int hash )
3710 hash = (hash % (MAX_CONNECTIONS-2))+1;
3714 for (i=hash+1;i!=hash;)
3716 if (!Connections[i].open && Connections[i].used == used)
3718 DEBUG(3,("found free connection number %d\n",i));
3722 if (i == MAX_CONNECTIONS)
3732 DEBUG(1,("ERROR! Out of connection structures\n"));
3737 /****************************************************************************
3738 reply for the core protocol
3739 ****************************************************************************/
3740 int reply_corep(char *outbuf)
3742 int outsize = set_message(outbuf,1,0,True);
3744 Protocol = PROTOCOL_CORE;
3750 /****************************************************************************
3751 reply for the coreplus protocol
3752 ****************************************************************************/
3753 int reply_coreplus(char *outbuf)
3755 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3756 int outsize = set_message(outbuf,13,0,True);
3757 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3758 readbraw and writebraw (possibly) */
3759 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3760 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3762 Protocol = PROTOCOL_COREPLUS;
3768 /****************************************************************************
3769 reply for the lanman 1.0 protocol
3770 ****************************************************************************/
3771 int reply_lanman1(char *outbuf)
3773 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3775 BOOL doencrypt = SMBENCRYPT();
3776 time_t t = time(NULL);
3778 if (lp_security()>=SEC_USER) secword |= 1;
3779 if (doencrypt) secword |= 2;
3781 set_message(outbuf,13,doencrypt?8:0,True);
3782 SSVAL(outbuf,smb_vwv1,secword);
3783 /* Create a token value and add it to the outgoing packet. */
3785 generate_next_challenge(smb_buf(outbuf));
3787 Protocol = PROTOCOL_LANMAN1;
3789 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3790 SSVAL(outbuf,smb_vwv2,max_recv);
3791 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3792 SSVAL(outbuf,smb_vwv4,1);
3793 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3794 readbraw writebraw (possibly) */
3795 SIVAL(outbuf,smb_vwv6,getpid());
3796 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3798 put_dos_date(outbuf,smb_vwv8,t);
3800 return (smb_len(outbuf)+4);
3804 /****************************************************************************
3805 reply for the lanman 2.0 protocol
3806 ****************************************************************************/
3807 int reply_lanman2(char *outbuf)
3809 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3811 BOOL doencrypt = SMBENCRYPT();
3812 time_t t = time(NULL);
3813 struct cli_state *cli = NULL;
3817 if (lp_security() == SEC_SERVER) {
3818 cli = server_cryptkey();
3822 DEBUG(3,("using password server validation\n"));
3823 doencrypt = ((cli->sec_mode & 2) != 0);
3826 if (lp_security()>=SEC_USER) secword |= 1;
3827 if (doencrypt) secword |= 2;
3832 generate_next_challenge(cryptkey);
3834 memcpy(cryptkey, cli->cryptkey, 8);
3835 set_challenge(cli->cryptkey);
3839 set_message(outbuf,13,crypt_len,True);
3840 SSVAL(outbuf,smb_vwv1,secword);
3841 SIVAL(outbuf,smb_vwv6,getpid());
3843 memcpy(smb_buf(outbuf), cryptkey, 8);
3845 Protocol = PROTOCOL_LANMAN2;
3847 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3848 SSVAL(outbuf,smb_vwv2,max_recv);
3849 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3850 SSVAL(outbuf,smb_vwv4,1);
3851 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3852 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3853 put_dos_date(outbuf,smb_vwv8,t);
3855 return (smb_len(outbuf)+4);
3859 /****************************************************************************
3860 reply for the nt protocol
3861 ****************************************************************************/
3862 int reply_nt1(char *outbuf)
3864 /* dual names + lock_and_read + nt SMBs + remote API calls */
3865 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3867 other valid capabilities which we may support at some time...
3868 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3869 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3873 BOOL doencrypt = SMBENCRYPT();
3874 time_t t = time(NULL);
3876 struct cli_state *cli = NULL;
3880 if (lp_security() == SEC_SERVER) {
3881 cli = server_cryptkey();
3885 DEBUG(3,("using password server validation\n"));
3886 doencrypt = ((cli->sec_mode & 2) != 0);
3892 generate_next_challenge(cryptkey);
3894 memcpy(cryptkey, cli->cryptkey, 8);
3895 set_challenge(cli->cryptkey);
3899 if (lp_readraw() && lp_writeraw()) {
3900 capabilities |= CAP_RAW_MODE;
3903 if (lp_security() >= SEC_USER) secword |= 1;
3904 if (doencrypt) secword |= 2;
3906 /* decide where (if) to put the encryption challenge, and
3907 follow it with the OEM'd domain name
3909 data_len = crypt_len + strlen(myworkgroup) + 1;
3911 set_message(outbuf,17,data_len,True);
3912 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3914 CVAL(outbuf,smb_vwv1) = secword;
3915 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3917 memcpy(smb_buf(outbuf), cryptkey, 8);
3919 Protocol = PROTOCOL_NT1;
3921 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3922 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3923 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3924 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3925 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3926 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3927 put_long_date(outbuf+smb_vwv11+1,t);
3928 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3929 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3931 return (smb_len(outbuf)+4);
3934 /* these are the protocol lists used for auto architecture detection:
3937 protocol [PC NETWORK PROGRAM 1.0]
3938 protocol [XENIX CORE]
3939 protocol [MICROSOFT NETWORKS 1.03]
3940 protocol [LANMAN1.0]
3941 protocol [Windows for Workgroups 3.1a]
3942 protocol [LM1.2X002]
3943 protocol [LANMAN2.1]
3944 protocol [NT LM 0.12]
3947 protocol [PC NETWORK PROGRAM 1.0]
3948 protocol [XENIX CORE]
3949 protocol [MICROSOFT NETWORKS 1.03]
3950 protocol [LANMAN1.0]
3951 protocol [Windows for Workgroups 3.1a]
3952 protocol [LM1.2X002]
3953 protocol [LANMAN2.1]
3954 protocol [NT LM 0.12]
3957 protocol [PC NETWORK PROGRAM 1.0]
3958 protocol [XENIX CORE]
3959 protocol [LANMAN1.0]
3960 protocol [LM1.2X002]
3961 protocol [LANMAN2.1]
3965 * Modified to recognize the architecture of the remote machine better.
3967 * This appears to be the matrix of which protocol is used by which
3969 Protocol WfWg Win95 WinNT OS/2
3970 PC NETWORK PROGRAM 1.0 1 1 1 1
3972 MICROSOFT NETWORKS 3.0 2 2
3974 MICROSOFT NETWORKS 1.03 3
3977 Windows for Workgroups 3.1a 5 5 5
3982 * tim@fsg.com 09/29/95
3985 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3986 #define ARCH_WIN95 0x2
3987 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3988 #define ARCH_WINNT 0x8
3989 #define ARCH_SAMBA 0x10
3991 #define ARCH_ALL 0x1F
3993 /* List of supported protocols, most desired first */
3997 int (*proto_reply_fn)(char *);
3999 } supported_protocols[] = {
4000 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4001 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4002 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4003 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4004 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4005 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4006 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4007 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4008 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4013 /****************************************************************************
4015 ****************************************************************************/
4016 static int reply_negprot(char *inbuf,char *outbuf)
4018 int outsize = set_message(outbuf,1,0,True);
4023 int bcc = SVAL(smb_buf(inbuf),-2);
4024 int arch = ARCH_ALL;
4026 p = smb_buf(inbuf)+1;
4027 while (p < (smb_buf(inbuf) + bcc))
4030 DEBUG(3,("Requested protocol [%s]\n",p));
4031 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4032 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4033 else if (strcsequal(p,"DOS LM1.2X002"))
4034 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4035 else if (strcsequal(p,"DOS LANMAN2.1"))
4036 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4037 else if (strcsequal(p,"NT LM 0.12"))
4038 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4039 else if (strcsequal(p,"LANMAN2.1"))
4040 arch &= ( ARCH_WINNT | ARCH_OS2 );
4041 else if (strcsequal(p,"LM1.2X002"))
4042 arch &= ( ARCH_WINNT | ARCH_OS2 );
4043 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4045 else if (strcsequal(p,"XENIX CORE"))
4046 arch &= ( ARCH_WINNT | ARCH_OS2 );
4047 else if (strcsequal(p,"Samba")) {
4057 set_remote_arch(RA_SAMBA);
4060 set_remote_arch(RA_WFWG);
4063 set_remote_arch(RA_WIN95);
4066 set_remote_arch(RA_WINNT);
4069 set_remote_arch(RA_OS2);
4072 set_remote_arch(RA_UNKNOWN);
4076 /* possibly reload - change of architecture */
4077 reload_services(True);
4079 /* a special case to stop password server loops */
4080 if (Index == 1 && strequal(remote_machine,myhostname) &&
4081 lp_security()==SEC_SERVER)
4082 exit_server("Password server loop!");
4084 /* Check for protocols, most desirable first */
4085 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4087 p = smb_buf(inbuf)+1;
4089 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4090 while (p < (smb_buf(inbuf) + bcc))
4092 if (strequal(p,supported_protocols[protocol].proto_name))
4101 SSVAL(outbuf,smb_vwv0,choice);
4103 extern fstring remote_proto;
4104 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4105 reload_services(True);
4106 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4107 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4110 DEBUG(0,("No protocol supported !\n"));
4112 SSVAL(outbuf,smb_vwv0,choice);
4114 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4120 /****************************************************************************
4121 close all open files for a connection
4122 ****************************************************************************/
4123 static void close_open_files(int cnum)
4126 for (i=0;i<MAX_OPEN_FILES;i++)
4127 if( Files[i].cnum == cnum && Files[i].open) {
4128 close_file(i,False);
4134 /****************************************************************************
4136 ****************************************************************************/
4137 void close_cnum(int cnum, uint16 vuid)
4139 DirCacheFlush(SNUM(cnum));
4143 if (!OPEN_CNUM(cnum))
4145 DEBUG(0,("Can't close cnum %d\n",cnum));
4149 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4151 remote_machine,client_addr(),
4152 lp_servicename(SNUM(cnum))));
4154 yield_connection(cnum,
4155 lp_servicename(SNUM(cnum)),
4156 lp_max_connections(SNUM(cnum)));
4158 if (lp_status(SNUM(cnum)))
4159 yield_connection(cnum,"STATUS.",MAXSTATUS);
4161 close_open_files(cnum);
4162 dptr_closecnum(cnum);
4164 /* execute any "postexec = " line */
4165 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4168 strcpy(cmd,lp_postexec(SNUM(cnum)));
4169 standard_sub(cnum,cmd);
4170 smbrun(cmd,NULL,False);
4175 /* execute any "root postexec = " line */
4176 if (*lp_rootpostexec(SNUM(cnum)))
4179 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4180 standard_sub(cnum,cmd);
4181 smbrun(cmd,NULL,False);
4184 Connections[cnum].open = False;
4185 num_connections_open--;
4186 if (Connections[cnum].ngroups && Connections[cnum].groups)
4188 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4189 free(Connections[cnum].groups);
4190 free(Connections[cnum].igroups);
4191 Connections[cnum].groups = NULL;
4192 Connections[cnum].igroups = NULL;
4193 Connections[cnum].ngroups = 0;
4196 free_namearray(Connections[cnum].veto_list);
4197 free_namearray(Connections[cnum].hide_list);
4198 free_namearray(Connections[cnum].veto_oplock_list);
4200 string_set(&Connections[cnum].user,"");
4201 string_set(&Connections[cnum].dirpath,"");
4202 string_set(&Connections[cnum].connectpath,"");
4206 /****************************************************************************
4207 simple routines to do connection counting
4208 ****************************************************************************/
4209 BOOL yield_connection(int cnum,char *name,int max_connections)
4211 struct connect_record crec;
4214 int mypid = getpid();
4217 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4219 if (max_connections <= 0)
4222 bzero(&crec,sizeof(crec));
4224 pstrcpy(fname,lp_lockdir());
4225 standard_sub(cnum,fname);
4226 trim_string(fname,"","/");
4230 strcat(fname,".LCK");
4232 f = fopen(fname,"r+");
4235 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4239 fseek(f,0,SEEK_SET);
4241 /* find a free spot */
4242 for (i=0;i<max_connections;i++)
4244 if (fread(&crec,sizeof(crec),1,f) != 1)
4246 DEBUG(2,("Entry not found in lock file %s\n",fname));
4250 if (crec.pid == mypid && crec.cnum == cnum)
4254 if (crec.pid != mypid || crec.cnum != cnum)
4257 DEBUG(2,("Entry not found in lock file %s\n",fname));
4261 bzero((void *)&crec,sizeof(crec));
4263 /* remove our mark */
4264 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4265 fwrite(&crec,sizeof(crec),1,f) != 1)
4267 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4272 DEBUG(3,("Yield successful\n"));
4279 /****************************************************************************
4280 simple routines to do connection counting
4281 ****************************************************************************/
4282 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4284 struct connect_record crec;
4287 int snum = SNUM(cnum);
4291 if (max_connections <= 0)
4294 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4296 pstrcpy(fname,lp_lockdir());
4297 standard_sub(cnum,fname);
4298 trim_string(fname,"","/");
4300 if (!directory_exist(fname,NULL))
4305 strcat(fname,".LCK");
4307 if (!file_exist(fname,NULL))
4309 int oldmask = umask(022);
4310 f = fopen(fname,"w");
4315 total_recs = file_size(fname) / sizeof(crec);
4317 f = fopen(fname,"r+");
4321 DEBUG(1,("couldn't open lock file %s\n",fname));
4325 /* find a free spot */
4326 for (i=0;i<max_connections;i++)
4329 if (i>=total_recs ||
4330 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4331 fread(&crec,sizeof(crec),1,f) != 1)
4333 if (foundi < 0) foundi = i;
4337 if (Clear && crec.pid && !process_exists(crec.pid))
4339 fseek(f,i*sizeof(crec),SEEK_SET);
4340 bzero((void *)&crec,sizeof(crec));
4341 fwrite(&crec,sizeof(crec),1,f);
4342 if (foundi < 0) foundi = i;
4345 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4354 DEBUG(3,("no free locks in %s\n",fname));
4359 /* fill in the crec */
4360 bzero((void *)&crec,sizeof(crec));
4361 crec.magic = 0x280267;
4362 crec.pid = getpid();
4364 crec.uid = Connections[cnum].uid;
4365 crec.gid = Connections[cnum].gid;
4366 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4367 crec.start = time(NULL);
4369 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4370 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4373 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4374 fwrite(&crec,sizeof(crec),1,f) != 1)
4385 /*******************************************************************
4386 prepare to dump a core file - carefully!
4387 ********************************************************************/
4388 static BOOL dump_core(void)
4392 pstrcpy(dname,debugf);
4393 if ((p=strrchr(dname,'/'))) *p=0;
4394 strcat(dname,"/corefiles");
4396 sys_chown(dname,getuid(),getgid());
4398 if (chdir(dname)) return(False);
4401 #ifndef NO_GETRLIMIT
4405 getrlimit(RLIMIT_CORE, &rlp);
4406 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4407 setrlimit(RLIMIT_CORE, &rlp);
4408 getrlimit(RLIMIT_CORE, &rlp);
4409 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4415 DEBUG(0,("Dumping core in %s\n",dname));
4420 /****************************************************************************
4422 ****************************************************************************/
4423 void exit_server(char *reason)
4425 static int firsttime=1;
4428 if (!firsttime) exit(0);
4432 DEBUG(2,("Closing connections\n"));
4433 for (i=0;i<MAX_CONNECTIONS;i++)
4434 if (Connections[i].open)
4435 close_cnum(i,(uint16)-1);
4437 if (dcelogin_atmost_once)
4441 int oldlevel = DEBUGLEVEL;
4443 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4445 show_msg(last_inbuf);
4446 DEBUGLEVEL = oldlevel;
4447 DEBUG(0,("===============================================================\n"));
4449 if (dump_core()) return;
4455 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4459 /****************************************************************************
4460 do some standard substitutions in a string
4461 ****************************************************************************/
4462 void standard_sub(int cnum,char *str)
4464 if (VALID_CNUM(cnum)) {
4467 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4469 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4470 string_sub(p,"%H",home);
4474 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4475 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4476 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4477 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4478 case '\0' : p++; break; /* don't run off the end of the string */
4479 default : p+=2; break;
4483 standard_sub_basic(str);
4487 These flags determine some of the permissions required to do an operation
4489 Note that I don't set NEED_WRITE on some write operations because they
4490 are used by some brain-dead clients when printing, and I don't want to
4491 force write permissions on print services.
4493 #define AS_USER (1<<0)
4494 #define NEED_WRITE (1<<1)
4495 #define TIME_INIT (1<<2)
4496 #define CAN_IPC (1<<3)
4497 #define AS_GUEST (1<<5)
4501 define a list of possible SMB messages and their corresponding
4502 functions. Any message that has a NULL function is unimplemented -
4503 please feel free to contribute implementations!
4505 struct smb_message_struct
4519 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4520 {SMBtcon,"SMBtcon",reply_tcon,0},
4521 {SMBtdis,"SMBtdis",reply_tdis,0},
4522 {SMBexit,"SMBexit",reply_exit,0},
4523 {SMBioctl,"SMBioctl",reply_ioctl,0},
4524 {SMBecho,"SMBecho",reply_echo,0},
4525 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4526 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4527 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4528 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4529 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4530 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4531 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4532 {SMBopen,"SMBopen",reply_open,AS_USER},
4534 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4535 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4536 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4538 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4539 {SMBread,"SMBread",reply_read,AS_USER},
4540 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4541 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4542 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4543 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4544 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4545 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4547 /* this is a Pathworks specific call, allowing the
4548 changing of the root path */
4549 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4551 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4552 {SMBflush,"SMBflush",reply_flush,AS_USER},
4553 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4554 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4555 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4556 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4557 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4558 {SMBlock,"SMBlock",reply_lock,AS_USER},
4559 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4561 /* CORE+ PROTOCOL FOLLOWS */
4563 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4564 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4565 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4566 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4567 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4569 /* LANMAN1.0 PROTOCOL FOLLOWS */
4571 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4572 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4573 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4574 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4575 {SMBwritec,"SMBwritec",NULL,AS_USER},
4576 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4577 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4578 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4579 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4580 {SMBioctls,"SMBioctls",NULL,AS_USER},
4581 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4582 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4584 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4585 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4586 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4587 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4589 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4590 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4591 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4593 /* LANMAN2.0 PROTOCOL FOLLOWS */
4594 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4595 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4596 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4597 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4599 /* messaging routines */
4600 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4601 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4602 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4603 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4605 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4607 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4608 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4609 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4610 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4613 /****************************************************************************
4614 return a string containing the function name of a SMB command
4615 ****************************************************************************/
4616 char *smb_fn_name(int type)
4618 static char *unknown_name = "SMBunknown";
4619 static int num_smb_messages =
4620 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4623 for (match=0;match<num_smb_messages;match++)
4624 if (smb_messages[match].code == type)
4627 if (match == num_smb_messages)
4628 return(unknown_name);
4630 return(smb_messages[match].name);
4634 /****************************************************************************
4635 do a switch on the message type, and return the response size
4636 ****************************************************************************/
4637 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4641 static int num_smb_messages =
4642 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4646 struct timeval msg_start_time;
4647 struct timeval msg_end_time;
4648 static unsigned long total_time = 0;
4650 GetTimeOfDay(&msg_start_time);
4657 last_message = type;
4659 /* make sure this is an SMB packet */
4660 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4662 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4666 for (match=0;match<num_smb_messages;match++)
4667 if (smb_messages[match].code == type)
4670 if (match == num_smb_messages)
4672 DEBUG(0,("Unknown message type %d!\n",type));
4673 outsize = reply_unknown(inbuf,outbuf);
4677 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4678 if (smb_messages[match].fn)
4680 int cnum = SVAL(inbuf,smb_tid);
4681 int flags = smb_messages[match].flags;
4682 /* In share mode security we must ignore the vuid. */
4683 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4684 /* Ensure this value is replaced in the incoming packet. */
4685 SSVAL(inbuf,smb_uid,session_tag);
4687 /* does this protocol need to be run as root? */
4688 if (!(flags & AS_USER))
4691 /* does this protocol need to be run as the connected user? */
4692 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4693 if (flags & AS_GUEST)
4696 return(ERROR(ERRSRV,ERRinvnid));
4698 /* this code is to work around a bug is MS client 3 without
4699 introducing a security hole - it needs to be able to do
4700 print queue checks as guest if it isn't logged in properly */
4701 if (flags & AS_USER)
4704 /* does it need write permission? */
4705 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4706 return(ERROR(ERRSRV,ERRaccess));
4708 /* ipc services are limited */
4709 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4710 return(ERROR(ERRSRV,ERRaccess));
4712 /* load service specific parameters */
4713 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4714 return(ERROR(ERRSRV,ERRaccess));
4716 /* does this protocol need to be run as guest? */
4717 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4718 return(ERROR(ERRSRV,ERRaccess));
4722 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4726 outsize = reply_unknown(inbuf,outbuf);
4731 GetTimeOfDay(&msg_end_time);
4732 if (!(smb_messages[match].flags & TIME_INIT))
4734 smb_messages[match].time = 0;
4735 smb_messages[match].flags |= TIME_INIT;
4738 unsigned long this_time =
4739 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4740 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4741 smb_messages[match].time += this_time;
4742 total_time += this_time;
4744 DEBUG(2,("TIME %s %d usecs %g pct\n",
4745 smb_fn_name(type),smb_messages[match].time,
4746 (100.0*smb_messages[match].time) / total_time));
4753 /****************************************************************************
4754 construct a chained reply and add it to the already made reply
4755 **************************************************************************/
4756 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4758 static char *orig_inbuf;
4759 static char *orig_outbuf;
4760 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4761 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4762 char *inbuf2, *outbuf2;
4764 char inbuf_saved[smb_wct];
4765 char outbuf_saved[smb_wct];
4766 extern int chain_size;
4767 int wct = CVAL(outbuf,smb_wct);
4768 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4770 /* maybe its not chained */
4771 if (smb_com2 == 0xFF) {
4772 CVAL(outbuf,smb_vwv0) = 0xFF;
4776 if (chain_size == 0) {
4777 /* this is the first part of the chain */
4779 orig_outbuf = outbuf;
4782 /* we need to tell the client where the next part of the reply will be */
4783 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4784 CVAL(outbuf,smb_vwv0) = smb_com2;
4786 /* remember how much the caller added to the chain, only counting stuff
4787 after the parameter words */
4788 chain_size += outsize - smb_wct;
4790 /* work out pointers into the original packets. The
4791 headers on these need to be filled in */
4792 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4793 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4795 /* remember the original command type */
4796 smb_com1 = CVAL(orig_inbuf,smb_com);
4798 /* save the data which will be overwritten by the new headers */
4799 memcpy(inbuf_saved,inbuf2,smb_wct);
4800 memcpy(outbuf_saved,outbuf2,smb_wct);
4802 /* give the new packet the same header as the last part of the SMB */
4803 memmove(inbuf2,inbuf,smb_wct);
4805 /* create the in buffer */
4806 CVAL(inbuf2,smb_com) = smb_com2;
4808 /* create the out buffer */
4809 bzero(outbuf2,smb_size);
4810 set_message(outbuf2,0,0,True);
4811 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4813 memcpy(outbuf2+4,inbuf2+4,4);
4814 CVAL(outbuf2,smb_rcls) = SUCCESS;
4815 CVAL(outbuf2,smb_reh) = 0;
4816 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4818 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4819 SSVAL(outbuf2,smb_err,SUCCESS);
4820 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4821 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4822 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4823 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4825 DEBUG(3,("Chained message\n"));
4828 /* process the request */
4829 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4830 bufsize-chain_size);
4832 /* copy the new reply and request headers over the old ones, but
4833 preserve the smb_com field */
4834 memmove(orig_outbuf,outbuf2,smb_wct);
4835 CVAL(orig_outbuf,smb_com) = smb_com1;
4837 /* restore the saved data, being careful not to overwrite any
4838 data from the reply header */
4839 memcpy(inbuf2,inbuf_saved,smb_wct);
4841 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4842 if (ofs < 0) ofs = 0;
4843 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4851 /****************************************************************************
4852 construct a reply to the incoming packet
4853 ****************************************************************************/
4854 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4856 int type = CVAL(inbuf,smb_com);
4858 int msg_type = CVAL(inbuf,0);
4859 extern int chain_size;
4861 smb_last_time = time(NULL);
4867 bzero(outbuf,smb_size);
4870 return(reply_special(inbuf,outbuf));
4872 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4873 set_message(outbuf,0,0,True);
4875 memcpy(outbuf+4,inbuf+4,4);
4876 CVAL(outbuf,smb_rcls) = SUCCESS;
4877 CVAL(outbuf,smb_reh) = 0;
4878 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4880 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4881 SSVAL(outbuf,smb_err,SUCCESS);
4882 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4883 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4884 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4885 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4887 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4889 outsize += chain_size;
4892 smb_setlen(outbuf,outsize - 4);
4896 /****************************************************************************
4897 process commands from the client
4898 ****************************************************************************/
4899 static void process(void)
4903 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4904 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4905 if ((InBuffer == NULL) || (OutBuffer == NULL))
4908 InBuffer += SMB_ALIGNMENT;
4909 OutBuffer += SMB_ALIGNMENT;
4912 DEBUG(3,("priming nmbd\n"));
4915 ip = *interpret_addr2("localhost");
4916 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4918 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4922 /* re-initialise the timezone */
4927 int deadtime = lp_deadtime()*60;
4929 int last_keepalive=0;
4930 int service_load_counter = 0;
4931 BOOL got_smb = False;
4934 deadtime = DEFAULT_SMBD_TIMEOUT;
4936 #if USE_READ_PREDICTION
4937 if (lp_readprediction())
4938 do_read_prediction();
4943 for (counter=SMBD_SELECT_LOOP;
4944 !receive_message_or_smb(Client,oplock_sock,
4945 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4946 counter += SMBD_SELECT_LOOP)
4950 BOOL allidle = True;
4951 extern int keepalive;
4953 if (counter > 365 * 3600) /* big number of seconds. */
4956 service_load_counter = 0;
4959 if (smb_read_error == READ_EOF)
4961 DEBUG(3,("end of file from client\n"));
4965 if (smb_read_error == READ_ERROR)
4967 DEBUG(3,("receive_smb error (%s) exiting\n",
4974 /* become root again if waiting */
4977 /* check for smb.conf reload */
4978 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4980 service_load_counter = counter;
4982 /* reload services, if files have changed. */
4983 reload_services(True);
4986 /* automatic timeout if all connections are closed */
4987 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4989 DEBUG(2,("%s Closing idle connection\n",timestring()));
4993 if (keepalive && (counter-last_keepalive)>keepalive)
4995 struct cli_state *cli = server_client();
4996 if (!send_keepalive(Client)) {
4997 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5000 /* also send a keepalive to the password server if its still
5002 if (cli && cli->initialised)
5003 send_keepalive(cli->fd);
5004 last_keepalive = counter;
5007 /* check for connection timeouts */
5008 for (i=0;i<MAX_CONNECTIONS;i++)
5009 if (Connections[i].open)
5011 /* close dirptrs on connections that are idle */
5012 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5015 if (Connections[i].num_files_open > 0 ||
5016 (t-Connections[i].lastused)<deadtime)
5020 if (allidle && num_connections_open>0)
5022 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5028 process_smb(InBuffer, OutBuffer);
5030 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5035 /****************************************************************************
5036 initialise connect, service and file structs
5037 ****************************************************************************/
5038 static void init_structs(void )
5041 get_myname(myhostname,NULL);
5043 for (i=0;i<MAX_CONNECTIONS;i++)
5045 Connections[i].open = False;
5046 Connections[i].num_files_open=0;
5047 Connections[i].lastused=0;
5048 Connections[i].used=False;
5049 string_init(&Connections[i].user,"");
5050 string_init(&Connections[i].dirpath,"");
5051 string_init(&Connections[i].connectpath,"");
5052 string_init(&Connections[i].origpath,"");
5055 for (i=0;i<MAX_OPEN_FILES;i++)
5057 Files[i].open = False;
5058 string_init(&Files[i].name,"");
5062 for (i=0;i<MAX_OPEN_FILES;i++)
5064 file_fd_struct *fd_ptr = &FileFd[i];
5065 fd_ptr->ref_count = 0;
5066 fd_ptr->dev = (int32)-1;
5067 fd_ptr->inode = (int32)-1;
5069 fd_ptr->fd_readonly = -1;
5070 fd_ptr->fd_writeonly = -1;
5071 fd_ptr->real_open_flags = -1;
5075 init_rpc_pipe_hnd();
5078 /* for LSA handles */
5079 init_lsa_policy_hnd();
5085 /****************************************************************************
5086 usage on the program
5087 ****************************************************************************/
5088 static void usage(char *pname)
5090 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5092 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5093 printf("Version %s\n",VERSION);
5094 printf("\t-D become a daemon\n");
5095 printf("\t-p port listen on the specified port\n");
5096 printf("\t-d debuglevel set the debuglevel\n");
5097 printf("\t-l log basename. Basename for log/debug files\n");
5098 printf("\t-s services file. Filename of services file\n");
5099 printf("\t-P passive only\n");
5100 printf("\t-a overwrite log file, don't append\n");
5105 /****************************************************************************
5107 ****************************************************************************/
5108 int main(int argc,char *argv[])
5110 extern BOOL append_log;
5111 /* shall I run as a daemon */
5112 BOOL is_daemon = False;
5113 int port = SMB_PORT;
5115 extern char *optarg;
5120 #ifdef NEED_AUTH_PARAMETERS
5121 set_auth_parameters(argc,argv);
5132 strcpy(debugf,SMBLOGFILE);
5134 setup_logging(argv[0],False);
5136 charset_initialise();
5138 /* make absolutely sure we run as root - to handle cases where people
5139 are crazy enough to have it setuid */
5149 fault_setup(exit_server);
5150 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5152 /* we want total control over the permissions on created files,
5153 so set our umask to 0 */
5160 /* this is for people who can't start the program correctly */
5161 while (argc > 1 && (*argv[1] != '-'))
5167 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5171 strncpy(pidFile, optarg, sizeof(pidFile));
5174 strcpy(user_socket_options,optarg);
5177 strcpy(scope,optarg);
5181 extern BOOL passive;
5186 strcpy(servicesf,optarg);
5189 strcpy(debugf,optarg);
5193 extern BOOL append_log;
5194 append_log = !append_log;
5204 DEBUGLEVEL = atoi(optarg);
5207 port = atoi(optarg);
5220 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5221 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5223 #ifndef NO_GETRLIMIT
5224 #ifdef RLIMIT_NOFILE
5227 getrlimit(RLIMIT_NOFILE, &rlp);
5228 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5229 setrlimit(RLIMIT_NOFILE, &rlp);
5230 getrlimit(RLIMIT_NOFILE, &rlp);
5231 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5237 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5238 getuid(),getgid(),geteuid(),getegid()));
5240 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5242 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5248 if (!reload_services(False))
5251 codepage_initialise(lp_client_code_page());
5253 strcpy(myworkgroup, lp_workgroup());
5255 #ifndef NO_SIGNAL_TEST
5256 signal(SIGHUP,SIGNAL_CAST sig_hup);
5259 /* Setup the signals that allow the debug log level
5260 to by dynamically changed. */
5262 #if defined(SIGUSR1)
5263 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5264 #endif /* SIGUSR1 */
5266 #if defined(SIGUSR2)
5267 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5268 #endif /* SIGUSR2 */
5270 DEBUG(3,("%s loaded services\n",timestring()));
5272 if (!is_daemon && !is_a_socket(0))
5274 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5280 DEBUG(3,("%s becoming a daemon\n",timestring()));
5284 if (!directory_exist(lp_lockdir(), NULL)) {
5285 mkdir(lp_lockdir(), 0755);
5293 if ((fd = open(pidFile,
5297 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5299 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5302 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5304 DEBUG(0,("ERROR: smbd is already running\n"));
5307 sprintf(buf, "%u\n", (unsigned int) getpid());
5308 if (write(fd, buf, strlen(buf)) < 0)
5310 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5313 /* Leave pid file open & locked for the duration... */
5316 if (!open_sockets(is_daemon,port))
5319 if (!locking_init(0))
5322 /* possibly reload the services file. */
5323 reload_services(True);
5325 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5329 if (sys_chroot(lp_rootdir()) == 0)
5330 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5333 /* Setup the oplock IPC socket. */
5334 if(!open_oplock_ipc())
5340 exit_server("normal exit");