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)))) {
456 check_mangled_stack(name);
458 /* open the directory */
459 if (!(cur_dir = OpenDir(cnum, path, True)))
461 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
465 /* now scan for matching names */
466 while ((dname = ReadDirName(cur_dir)))
469 (strequal(dname,".") || strequal(dname,"..")))
472 pstrcpy(name2,dname);
473 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
475 if ((mangled && mangled_equal(name,name2))
476 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
478 /* we've found the file, change it's name and return */
479 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
490 /****************************************************************************
491 This routine is called to convert names from the dos namespace to unix
492 namespace. It needs to handle any case conversions, mangling, format
495 We assume that we have already done a chdir() to the right "root" directory
498 The function will return False if some part of the name except for the last
499 part cannot be resolved
501 If the saved_last_component != 0, then the unmodified last component
502 of the pathname is returned there. This is used in an exceptional
503 case in reply_mv (so far). If saved_last_component == 0 then nothing
506 The bad_path arg is set to True if the filename walk failed. This is
507 used to pick the correct error code to return between ENOENT and ENOTDIR
508 as Windows applications depend on ERRbadpath being returned if a component
509 of a pathname does not exist.
510 ****************************************************************************/
511 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
521 if(saved_last_component)
522 *saved_last_component = 0;
524 /* convert to basic unix format - removing \ chars and cleaning it up */
526 unix_clean_name(name);
528 /* names must be relative to the root of the service - trim any leading /.
529 also trim trailing /'s */
530 trim_string(name,"/","/");
533 * Ensure saved_last_component is valid even if file exists.
535 if(saved_last_component) {
536 end = strrchr(name, '/');
538 strcpy(saved_last_component, end + 1);
540 strcpy(saved_last_component, name);
543 if (!case_sensitive &&
544 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
547 /* check if it's a printer file */
548 if (Connections[cnum].printer)
550 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
554 sprintf(name2,"%.6s.XXXXXX",remote_machine);
555 /* sanitise the name */
556 for (s=name2 ; *s ; s++)
557 if (!issafe(*s)) *s = '_';
558 strcpy(name,(char *)mktemp(name2));
563 /* stat the name - if it exists then we are all done! */
564 if (sys_stat(name,&st) == 0)
569 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
571 /* a special case - if we don't have any mangling chars and are case
572 sensitive then searching won't help */
573 if (case_sensitive && !is_mangled(name) &&
574 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
577 /* now we need to recursively match the name against the real
578 directory structure */
581 while (strncmp(start,"./",2) == 0)
584 /* now match each part of the path name separately, trying the names
585 as is first, then trying to scan the directory for matching names */
586 for (;start;start = (end?end+1:(char *)NULL))
588 /* pinpoint the end of this section of the filename */
589 end = strchr(start, '/');
591 /* chop the name at this point */
594 if(saved_last_component != 0)
595 strcpy(saved_last_component, end ? end + 1 : start);
597 /* check if the name exists up to this point */
598 if (sys_stat(name, &st) == 0)
600 /* it exists. it must either be a directory or this must be
601 the last part of the path for it to be OK */
602 if (end && !(st.st_mode & S_IFDIR))
604 /* an intermediate part of the name isn't a directory */
605 DEBUG(5,("Not a dir %s\n",start));
616 /* remember the rest of the pathname so it can be restored
618 if (end) pstrcpy(rest,end+1);
620 /* try to find this part of the path in the directory */
621 if (strchr(start,'?') || strchr(start,'*') ||
622 !scan_directory(dirpath, start, cnum, end?True:False))
626 /* an intermediate part of the name can't be found */
627 DEBUG(5,("Intermediate not found %s\n",start));
629 /* We need to return the fact that the intermediate
630 name resolution failed. This is used to return an
631 error of ERRbadpath rather than ERRbadfile. Some
632 Windows applications depend on the difference between
639 /* just the last part of the name doesn't exist */
640 /* we may need to strupper() or strlower() it in case
641 this conversion is being used for file creation
643 /* if the filename is of mixed case then don't normalise it */
644 if (!case_preserve &&
645 (!strhasupper(start) || !strhaslower(start)))
648 /* check on the mangled stack to see if we can recover the
649 base of the filename */
650 if (is_mangled(start))
651 check_mangled_stack(start);
653 DEBUG(5,("New file %s\n",start));
657 /* restore the rest of the string */
660 strcpy(start+strlen(start)+1,rest);
661 end = start + strlen(start);
665 /* add to the dirpath that we have resolved so far */
666 if (*dirpath) strcat(dirpath,"/");
667 strcat(dirpath,start);
669 /* restore the / that we wiped out earlier */
673 /* the name has been resolved */
674 DEBUG(5,("conversion finished %s\n",name));
679 /****************************************************************************
680 normalise for DOS usage
681 ****************************************************************************/
682 static void disk_norm(int *bsize,int *dfree,int *dsize)
684 /* check if the disk is beyond the max disk size */
685 int maxdisksize = lp_maxdisksize();
687 /* convert to blocks - and don't overflow */
688 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
689 if (*dsize > maxdisksize) *dsize = maxdisksize;
690 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
695 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
700 if (*bsize > WORDMAX )
703 if (*dsize > WORDMAX)
705 if (*dfree > WORDMAX)
712 /****************************************************************************
713 return number of 1K blocks available on a path and total number
714 ****************************************************************************/
715 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
717 char *df_command = lp_dfree_command();
738 /* possibly use system() to get the result */
739 if (df_command && *df_command)
745 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
746 sprintf(syscmd,"%s %s",df_command,path);
747 standard_sub_basic(syscmd);
749 ret = smbrun(syscmd,outfile,False);
750 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
753 FILE *f = fopen(outfile,"r");
759 fscanf(f,"%d %d %d",dsize,dfree,bsize);
763 DEBUG(0,("Can't open %s\n",outfile));
767 disk_norm(bsize,dfree,dsize);
768 dfree_retval = ((*bsize)/1024)*(*dfree);
770 /* Ensure we return the min value between the users quota and
771 what's free on the disk. Thanks to Albrecht Gebhardt
772 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
774 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
776 disk_norm(&bsizeq, &dfreeq, &dsizeq);
777 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
778 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
779 dfree_retval : dfreeq_retval ;
780 /* maybe dfree and dfreeq are calculated using different bsizes
781 so convert dfree from bsize into bsizeq */
782 /* avoid overflows due to multiplication, so do not:
783 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
784 bsize and bsizeq are powers of 2 so its better to
785 to divide them getting a multiplication or division factor
786 for dfree. Rene Nieuwenhuizen (07-10-1997) */
787 if (*bsize >= bsizeq)
788 *dfree = *dfree * (*bsize / bsizeq);
790 *dfree = *dfree / (bsizeq / *bsize);
791 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
796 return(dfree_retval);
800 DEBUG(1,("Warning - no statfs function\n"));
804 if (statfs(path,&fs,sizeof(fs),0) != 0)
807 if (statvfs(path, &fs))
810 if (statfs(path,&fs,sizeof(fs)) == -1)
812 if (statfs(path,&fs) == -1)
814 #endif /* USE_STATVFS */
817 DEBUG(3,("dfree call failed code errno=%d\n",errno));
821 return(((*bsize)/1024)*(*dfree));
826 *dfree = fs.fd_req.bfree;
827 *dsize = fs.fd_req.btot;
830 *bsize = fs.f_frsize;
833 /* eg: osf1 has f_fsize = fundamental filesystem block size,
834 f_bsize = optimal transfer block size (MX: 94-04-19) */
839 #endif /* USE_STATVFS */
844 *dfree = fs.f_bavail;
846 *dsize = fs.f_blocks;
849 #if defined(SCO) || defined(ISC) || defined(MIPS)
853 /* handle rediculous bsize values - some OSes are broken */
854 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
856 disk_norm(bsize,dfree,dsize);
862 DEBUG(0,("dfree seems to be broken on your system\n"));
863 *dsize = 20*1024*1024/(*bsize);
864 *dfree = MAX(1,*dfree);
866 dfree_retval = ((*bsize)/1024)*(*dfree);
868 /* Ensure we return the min value between the users quota and
869 what's free on the disk. Thanks to Albrecht Gebhardt
870 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
872 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
874 disk_norm(&bsizeq, &dfreeq, &dsizeq);
875 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
876 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
877 dfree_retval : dfreeq_retval ;
878 /* maybe dfree and dfreeq are calculated using different bsizes
879 so convert dfree from bsize into bsizeq */
880 /* avoid overflows due to multiplication, so do not:
881 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
882 bsize and bsizeq are powers of 2 so its better to
883 to divide them getting a multiplication or division factor
884 for dfree. Rene Nieuwenhuizen (07-10-1997) */
885 if (*bsize >= bsizeq)
886 *dfree = *dfree * (*bsize / bsizeq);
888 *dfree = *dfree / (bsizeq / *bsize);
889 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
894 return(dfree_retval);
899 /****************************************************************************
900 wrap it to get filenames right
901 ****************************************************************************/
902 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
904 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
909 /****************************************************************************
910 check a filename - possibly caling reducename
912 This is called by every routine before it allows an operation on a filename.
913 It does any final confirmation necessary to ensure that the filename is
914 a valid one for the user to access.
915 ****************************************************************************/
916 BOOL check_name(char *name,int cnum)
922 if( IS_VETO_PATH(cnum, name))
924 DEBUG(5,("file path name %s vetoed\n",name));
928 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
930 /* Check if we are allowing users to follow symlinks */
931 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
932 University of Geneva */
935 if (!lp_symlinks(SNUM(cnum)))
938 if ( (sys_lstat(name,&statbuf) != -1) &&
939 (S_ISLNK(statbuf.st_mode)) )
941 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
948 DEBUG(5,("check_name on %s failed\n",name));
953 /****************************************************************************
954 check a filename - possibly caling reducename
955 ****************************************************************************/
956 static void check_for_pipe(char *fname)
958 /* special case of pipe opens */
962 if (strstr(s,"pipe/"))
964 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
965 unix_ERR_class = ERRSRV;
966 unix_ERR_code = ERRaccess;
970 /****************************************************************************
971 fd support routines - attempt to do a sys_open
972 ****************************************************************************/
973 static int fd_attempt_open(char *fname, int flags, int mode)
975 int fd = sys_open(fname,flags,mode);
977 /* Fix for files ending in '.' */
978 if((fd == -1) && (errno == ENOENT) &&
979 (strchr(fname,'.')==NULL))
982 fd = sys_open(fname,flags,mode);
985 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
986 if ((fd == -1) && (errno == ENAMETOOLONG))
989 char *p = strrchr(fname, '/');
991 if (p == fname) /* name is "/xxx" */
993 max_len = pathconf("/", _PC_NAME_MAX);
996 else if ((p == NULL) || (p == fname))
999 max_len = pathconf(".", _PC_NAME_MAX);
1004 max_len = pathconf(fname, _PC_NAME_MAX);
1008 if (strlen(p) > max_len)
1010 char tmp = p[max_len];
1013 if ((fd = sys_open(fname,flags,mode)) == -1)
1021 /****************************************************************************
1022 fd support routines - attempt to find an already open file by dev
1023 and inode - increments the ref_count of the returned file_fd_struct *.
1024 ****************************************************************************/
1025 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1028 file_fd_struct *fd_ptr;
1033 for(i = 0; i <= max_file_fd_used; i++) {
1034 fd_ptr = &FileFd[i];
1035 if((fd_ptr->ref_count > 0) &&
1036 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1037 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1038 fd_ptr->ref_count++;
1040 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1041 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1048 /****************************************************************************
1049 fd support routines - attempt to find a empty slot in the FileFd array.
1050 Increments the ref_count of the returned entry.
1051 ****************************************************************************/
1052 static file_fd_struct *fd_get_new()
1055 file_fd_struct *fd_ptr;
1057 for(i = 0; i < MAX_OPEN_FILES; i++) {
1058 fd_ptr = &FileFd[i];
1059 if(fd_ptr->ref_count == 0) {
1060 fd_ptr->dev = (uint32)-1;
1061 fd_ptr->inode = (uint32)-1;
1063 fd_ptr->fd_readonly = -1;
1064 fd_ptr->fd_writeonly = -1;
1065 fd_ptr->real_open_flags = -1;
1066 fd_ptr->ref_count++;
1067 /* Increment max used counter if neccessary, cuts down
1068 on search time when re-using */
1069 if(i > max_file_fd_used)
1070 max_file_fd_used = i;
1071 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1072 i, fd_ptr->dev, fd_ptr->inode));
1076 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1081 /****************************************************************************
1082 fd support routines - attempt to re-open an already open fd as O_RDWR.
1083 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1084 ****************************************************************************/
1085 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1087 int fd = sys_open( fname, O_RDWR, mode);
1092 if(fd_ptr->real_open_flags == O_RDONLY)
1093 fd_ptr->fd_readonly = fd_ptr->fd;
1094 if(fd_ptr->real_open_flags == O_WRONLY)
1095 fd_ptr->fd_writeonly = fd_ptr->fd;
1098 fd_ptr->real_open_flags = O_RDWR;
1101 /****************************************************************************
1102 fd support routines - attempt to close the file referenced by this fd.
1103 Decrements the ref_count and returns it.
1104 ****************************************************************************/
1105 static int fd_attempt_close(file_fd_struct *fd_ptr)
1107 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1108 fd_ptr - &FileFd[0],
1109 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1110 fd_ptr->real_open_flags,
1111 fd_ptr->ref_count));
1112 if(fd_ptr->ref_count > 0) {
1113 fd_ptr->ref_count--;
1114 if(fd_ptr->ref_count == 0) {
1115 if(fd_ptr->fd != -1)
1117 if(fd_ptr->fd_readonly != -1)
1118 close(fd_ptr->fd_readonly);
1119 if(fd_ptr->fd_writeonly != -1)
1120 close(fd_ptr->fd_writeonly);
1122 fd_ptr->fd_readonly = -1;
1123 fd_ptr->fd_writeonly = -1;
1124 fd_ptr->real_open_flags = -1;
1125 fd_ptr->dev = (uint32)-1;
1126 fd_ptr->inode = (uint32)-1;
1129 return fd_ptr->ref_count;
1132 /****************************************************************************
1134 ****************************************************************************/
1135 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1137 extern struct current_user current_user;
1139 struct stat statbuf;
1140 file_fd_struct *fd_ptr;
1141 files_struct *fsp = &Files[fnum];
1145 fsp->granted_oplock = False;
1148 pstrcpy(fname,fname1);
1150 /* check permissions */
1151 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1153 DEBUG(3,("Permission denied opening %s\n",fname));
1154 check_for_pipe(fname);
1158 /* this handles a bug in Win95 - it doesn't say to create the file when it
1160 if (Connections[cnum].printer)
1164 if (flags == O_WRONLY)
1165 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1169 * Ensure we have a valid struct stat so we can search the
1173 if(stat(fname, &statbuf) < 0) {
1174 if(errno != ENOENT) {
1175 DEBUG(3,("Error doing stat on file %s (%s)\n",
1176 fname,strerror(errno)));
1178 check_for_pipe(fname);
1188 * Check to see if we have this file already
1189 * open. If we do, just use the already open fd and increment the
1190 * reference count (fd_get_already_open increments the ref_count).
1192 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1194 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1196 /* File was already open. */
1197 if((flags & O_CREAT) && (flags & O_EXCL)) {
1198 fd_ptr->ref_count--;
1204 * If not opened O_RDWR try
1205 * and do that here - a chmod may have been done
1206 * between the last open and now.
1208 if(fd_ptr->real_open_flags != O_RDWR)
1209 fd_attempt_reopen(fname, mode, fd_ptr);
1212 * Ensure that if we wanted write access
1213 * it has been opened for write, and if we wanted read it
1214 * was open for read.
1216 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1217 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1218 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1219 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1220 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1221 check_for_pipe(fname);
1222 fd_ptr->ref_count--;
1228 /* We need to allocate a new file_fd_struct (this increments the
1230 if((fd_ptr = fd_get_new()) == 0)
1233 * Whatever the requested flags, attempt read/write access,
1234 * as we don't know what flags future file opens may require.
1235 * If this fails, try again with the required flags.
1236 * Even if we open read/write when only read access was
1237 * requested the setting of the can_write flag in
1238 * the file_struct will protect us from errant
1239 * write requests. We never need to worry about O_APPEND
1240 * as this is not set anywhere in Samba.
1242 fd_ptr->real_open_flags = O_RDWR;
1243 /* Set the flags as needed without the read/write modes. */
1244 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1245 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1247 * On some systems opening a file for R/W access on a read only
1248 * filesystems sets errno to EROFS.
1251 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1252 #else /* No EROFS */
1253 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1255 if(flags & O_WRONLY) {
1256 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1257 fd_ptr->real_open_flags = O_WRONLY;
1259 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1260 fd_ptr->real_open_flags = O_RDONLY;
1265 if ((fd_ptr->fd >=0) &&
1266 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1270 pstrcpy(dname,fname);
1271 p = strrchr(dname,'/');
1273 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1274 lp_minprintspace(SNUM(cnum))) {
1275 fd_attempt_close(fd_ptr);
1277 if(fd_ptr->ref_count == 0)
1286 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1287 fname,strerror(errno),flags));
1288 /* Ensure the ref_count is decremented. */
1289 fd_attempt_close(fd_ptr);
1290 check_for_pipe(fname);
1294 if (fd_ptr->fd >= 0)
1298 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1299 /* Error - backout !! */
1300 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1301 fd_ptr->fd, fname,strerror(errno)));
1302 /* Ensure the ref_count is decremented. */
1303 fd_attempt_close(fd_ptr);
1308 /* Set the correct entries in fd_ptr. */
1309 fd_ptr->dev = (uint32)sbuf->st_dev;
1310 fd_ptr->inode = (uint32)sbuf->st_ino;
1312 fsp->fd_ptr = fd_ptr;
1313 Connections[cnum].num_files_open++;
1314 fsp->mode = sbuf->st_mode;
1315 GetTimeOfDay(&fsp->open_time);
1316 fsp->uid = current_user.id;
1320 fsp->mmap_ptr = NULL;
1322 fsp->can_lock = True;
1323 fsp->can_read = ((flags & O_WRONLY)==0);
1324 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1325 fsp->share_mode = 0;
1326 fsp->print_file = Connections[cnum].printer;
1327 fsp->modified = False;
1328 fsp->granted_oplock = False;
1330 string_set(&fsp->name,dos_to_unix(fname,False));
1331 fsp->wbmpx_ptr = NULL;
1334 * If the printer is marked as postscript output a leading
1335 * file identifier to ensure the file is treated as a raw
1337 * This has a similar effect as CtrlD=0 in WIN.INI file.
1338 * tim@fsg.com 09/06/94
1340 if (fsp->print_file && POSTSCRIPT(cnum) &&
1343 DEBUG(3,("Writing postscript line\n"));
1344 write_file(fnum,"%!\n",3);
1347 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1348 timestring(),Connections[cnum].user,fname,
1349 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1350 Connections[cnum].num_files_open,fnum));
1355 /* mmap it if read-only */
1356 if (!fsp->can_write)
1358 fsp->mmap_size = file_size(fname);
1359 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1360 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1362 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1364 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1365 fsp->mmap_ptr = NULL;
1371 /*******************************************************************
1373 ********************************************************************/
1374 void sync_file(int fnum)
1377 fsync(Files[fnum].fd_ptr->fd);
1381 /****************************************************************************
1382 run a file if it is a magic script
1383 ****************************************************************************/
1384 static void check_magic(int fnum,int cnum)
1386 if (!*lp_magicscript(SNUM(cnum)))
1389 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1393 if (!(p = strrchr(Files[fnum].name,'/')))
1394 p = Files[fnum].name;
1398 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1404 pstring magic_output;
1406 pstrcpy(fname,Files[fnum].name);
1408 if (*lp_magicoutput(SNUM(cnum)))
1409 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1411 sprintf(magic_output,"%s.out",fname);
1414 ret = smbrun(fname,magic_output,False);
1415 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1421 /****************************************************************************
1422 close a file - possibly invalidating the read prediction
1424 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1425 operation otherwise it came as the result of some other operation such as
1426 the closing of the connection. In the latter case printing and
1427 magic scripts are not run
1428 ****************************************************************************/
1429 void close_file(int fnum, BOOL normal_close)
1431 files_struct *fs_p = &Files[fnum];
1432 int cnum = fs_p->cnum;
1433 uint32 dev = fs_p->fd_ptr->dev;
1434 uint32 inode = fs_p->fd_ptr->inode;
1437 #if USE_READ_PREDICTION
1438 invalidate_read_prediction(fs_p->fd_ptr->fd);
1442 Connections[cnum].num_files_open--;
1445 free((char *)fs_p->wbmpx_ptr);
1446 fs_p->wbmpx_ptr = NULL;
1452 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1453 fs_p->mmap_ptr = NULL;
1457 if (lp_share_modes(SNUM(cnum)))
1459 lock_share_entry( cnum, dev, inode, &token);
1460 del_share_mode(token, fnum);
1463 fd_attempt_close(fs_p->fd_ptr);
1465 if (lp_share_modes(SNUM(cnum)))
1466 unlock_share_entry( cnum, dev, inode, token);
1468 /* NT uses smbclose to start a print - weird */
1469 if (normal_close && fs_p->print_file)
1472 /* check for magic scripts */
1474 check_magic(fnum,cnum);
1476 if(fs_p->granted_oplock == True)
1477 global_oplocks_open--;
1479 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1480 timestring(),Connections[cnum].user,fs_p->name,
1481 Connections[cnum].num_files_open));
1484 enum {AFAIL,AREAD,AWRITE,AALL};
1486 /*******************************************************************
1487 reproduce the share mode access table
1488 ********************************************************************/
1489 static int access_table(int new_deny,int old_deny,int old_mode,
1490 int share_pid,char *fname)
1492 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1494 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1496 if (old_deny == new_deny && share_pid == pid)
1499 if (old_mode == 0) return(AREAD);
1501 /* the new smbpub.zip spec says that if the file extension is
1502 .com, .dll, .exe or .sym then allow the open. I will force
1503 it to read-only as this seems sensible although the spec is
1504 a little unclear on this. */
1505 if ((fname = strrchr(fname,'.'))) {
1506 if (strequal(fname,".com") ||
1507 strequal(fname,".dll") ||
1508 strequal(fname,".exe") ||
1509 strequal(fname,".sym"))
1519 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1520 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1521 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1524 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1525 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1526 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1529 if (old_deny==DENY_WRITE) return(AREAD);
1530 if (old_deny==DENY_READ) return(AWRITE);
1531 if (old_deny==DENY_NONE) return(AALL);
1537 /*******************************************************************
1538 check if the share mode on a file allows it to be deleted or unlinked
1539 return True if sharing doesn't prevent the operation
1540 ********************************************************************/
1541 BOOL check_file_sharing(int cnum,char *fname)
1545 share_mode_entry *old_shares = 0;
1546 int num_share_modes;
1552 if(!lp_share_modes(SNUM(cnum)))
1555 if (stat(fname,&sbuf) == -1) return(True);
1557 dev = (uint32)sbuf.st_dev;
1558 inode = (uint32)sbuf.st_ino;
1560 lock_share_entry(cnum, dev, inode, &token);
1561 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1564 * Check if the share modes will give us access.
1567 if(num_share_modes != 0)
1574 broke_oplock = False;
1575 for(i = 0; i < num_share_modes; i++)
1577 share_mode_entry *share_entry = &old_shares[i];
1580 * Break oplocks before checking share modes. See comment in
1581 * open_file_shared for details.
1582 * Check if someone has an oplock on this file. If so we must
1583 * break it before continuing.
1585 if(share_entry->op_type & BATCH_OPLOCK)
1588 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1589 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1591 /* Oplock break.... */
1592 unlock_share_entry(cnum, dev, inode, token);
1593 if(request_oplock_break(share_entry, dev, inode) == False)
1595 free((char *)old_shares);
1596 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1597 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1600 lock_share_entry(cnum, dev, inode, &token);
1601 broke_oplock = True;
1605 /* someone else has a share lock on it, check to see
1607 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1614 free((char *)old_shares);
1615 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1617 } while(broke_oplock);
1620 /* XXXX exactly what share mode combinations should be allowed for
1621 deleting/renaming? */
1622 /* If we got here then either there were no share modes or
1623 all share modes were DENY_DOS and the pid == getpid() */
1628 unlock_share_entry(cnum, dev, inode, token);
1629 if(old_shares != NULL)
1630 free((char *)old_shares);
1634 /****************************************************************************
1636 Helper for open_file_shared.
1637 Truncate a file after checking locking; close file if locked.
1638 **************************************************************************/
1639 static void truncate_unless_locked(int fnum, int cnum, int token,
1642 if (Files[fnum].can_write){
1643 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1644 /* If share modes are in force for this connection we
1645 have the share entry locked. Unlock it before closing. */
1646 if (*share_locked && lp_share_modes(SNUM(cnum)))
1647 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1648 Files[fnum].fd_ptr->inode, token);
1649 close_file(fnum,False);
1650 /* Share mode no longer locked. */
1651 *share_locked = False;
1653 unix_ERR_class = ERRDOS;
1654 unix_ERR_code = ERRlock;
1657 ftruncate(Files[fnum].fd_ptr->fd,0);
1661 /****************************************************************************
1662 check if we can open a file with a share mode
1663 ****************************************************************************/
1664 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1665 BOOL fcbopen, int *flags)
1667 int old_open_mode = share->share_mode &0xF;
1668 int old_deny_mode = (share->share_mode >>4)&7;
1670 if (old_deny_mode > 4 || old_open_mode > 2)
1672 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1673 deny_mode,old_deny_mode,old_open_mode,fname));
1678 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1681 if ((access_allowed == AFAIL) ||
1682 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1683 (access_allowed == AREAD && *flags == O_WRONLY) ||
1684 (access_allowed == AWRITE && *flags == O_RDONLY))
1686 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1687 deny_mode,old_deny_mode,old_open_mode,
1688 share->pid,fname, fcbopen, *flags, access_allowed));
1692 if (access_allowed == AREAD)
1695 if (access_allowed == AWRITE)
1702 /****************************************************************************
1703 open a file with a share mode
1704 ****************************************************************************/
1705 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1706 int mode,int oplock_request, int *Access,int *action)
1708 files_struct *fs_p = &Files[fnum];
1711 int deny_mode = (share_mode>>4)&7;
1713 BOOL file_existed = file_exist(fname,&sbuf);
1714 BOOL share_locked = False;
1715 BOOL fcbopen = False;
1719 int num_share_modes = 0;
1724 /* this is for OS/2 EAs - try and say we don't support them */
1725 if (strstr(fname,".+,;=[]."))
1727 unix_ERR_class = ERRDOS;
1728 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1730 unix_ERR_code = ERRcannotopen;
1731 #else /* OS2_WPS_FIX */
1732 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1733 #endif /* OS2_WPS_FIX */
1738 if ((ofun & 0x3) == 0 && file_existed)
1746 if ((ofun & 0x3) == 2)
1749 /* note that we ignore the append flag as
1750 append does not mean the same thing under dos and unix */
1752 switch (share_mode&0xF)
1769 if (flags != O_RDONLY && file_existed &&
1770 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1780 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1782 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1787 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1789 if (lp_share_modes(SNUM(cnum)))
1792 share_mode_entry *old_shares = 0;
1796 dev = (uint32)sbuf.st_dev;
1797 inode = (uint32)sbuf.st_ino;
1798 lock_share_entry(cnum, dev, inode, &token);
1799 share_locked = True;
1800 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1804 * Check if the share modes will give us access.
1807 if(share_locked && (num_share_modes != 0))
1814 broke_oplock = False;
1815 for(i = 0; i < num_share_modes; i++)
1817 share_mode_entry *share_entry = &old_shares[i];
1820 * By observation of NetBench, oplocks are broken *before* share
1821 * modes are checked. This allows a file to be closed by the client
1822 * if the share mode would deny access and the client has an oplock.
1823 * Check if someone has an oplock on this file. If so we must break
1824 * it before continuing.
1826 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1829 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1830 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1832 /* Oplock break.... */
1833 unlock_share_entry(cnum, dev, inode, token);
1834 if(request_oplock_break(share_entry, dev, inode) == False)
1836 free((char *)old_shares);
1837 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1838 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1840 unix_ERR_class = ERRDOS;
1841 unix_ERR_code = ERRbadshare;
1844 lock_share_entry(cnum, dev, inode, &token);
1845 broke_oplock = True;
1849 /* someone else has a share lock on it, check to see
1851 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1853 free((char *)old_shares);
1854 unlock_share_entry(cnum, dev, inode, token);
1856 unix_ERR_class = ERRDOS;
1857 unix_ERR_code = ERRbadshare;
1865 free((char *)old_shares);
1866 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1868 } while(broke_oplock);
1872 free((char *)old_shares);
1875 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1876 flags,flags2,mode));
1878 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1879 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1882 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1889 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1891 /* We created the file - thus we must now lock the share entry before creating it. */
1892 dev = fs_p->fd_ptr->dev;
1893 inode = fs_p->fd_ptr->inode;
1894 lock_share_entry(cnum, dev, inode, &token);
1895 share_locked = True;
1911 fs_p->share_mode = (deny_mode<<4) | open_mode;
1914 (*Access) = open_mode;
1918 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1919 if (!file_existed) *action = 2;
1920 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1922 /* We must create the share mode entry before truncate as
1923 truncate can fail due to locking and have to close the
1924 file (which expects the share_mode_entry to be there).
1926 if (lp_share_modes(SNUM(cnum)))
1929 /* JRA. Currently this only services Exlcusive and batch
1930 oplocks (no other opens on this file). This needs to
1931 be extended to level II oplocks (multiple reader
1934 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
1935 !IS_VETO_OPLOCK_PATH(cnum,fname))
1937 fs_p->granted_oplock = True;
1938 global_oplocks_open++;
1941 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1942 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1950 set_share_mode(token, fnum, port, oplock_request);
1953 if ((flags2&O_TRUNC) && file_existed)
1954 truncate_unless_locked(fnum,cnum,token,&share_locked);
1957 if (share_locked && lp_share_modes(SNUM(cnum)))
1958 unlock_share_entry( cnum, dev, inode, token);
1961 /****************************************************************************
1962 seek a file. Try to avoid the seek if possible
1963 ****************************************************************************/
1964 int seek_file(int fnum,uint32 pos)
1967 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1970 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1972 return(Files[fnum].pos);
1975 /****************************************************************************
1977 ****************************************************************************/
1978 int read_file(int fnum,char *data,uint32 pos,int n)
1982 #if USE_READ_PREDICTION
1983 if (!Files[fnum].can_write)
1985 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1994 if (Files[fnum].mmap_ptr)
1996 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1999 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2011 if (seek_file(fnum,pos) != pos)
2013 DEBUG(3,("Failed to seek to %d\n",pos));
2018 readret = read(Files[fnum].fd_ptr->fd,data,n);
2019 if (readret > 0) ret += readret;
2026 /****************************************************************************
2028 ****************************************************************************/
2029 int write_file(int fnum,char *data,int n)
2031 if (!Files[fnum].can_write) {
2036 if (!Files[fnum].modified) {
2038 Files[fnum].modified = True;
2039 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2040 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2041 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2042 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2047 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2051 /****************************************************************************
2052 load parameters specific to a connection/service
2053 ****************************************************************************/
2054 BOOL become_service(int cnum,BOOL do_chdir)
2056 extern char magic_char;
2057 static int last_cnum = -1;
2060 if (!OPEN_CNUM(cnum))
2066 Connections[cnum].lastused = smb_last_time;
2071 ChDir(Connections[cnum].connectpath) != 0 &&
2072 ChDir(Connections[cnum].origpath) != 0)
2074 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2075 Connections[cnum].connectpath,cnum));
2079 if (cnum == last_cnum)
2084 case_default = lp_defaultcase(snum);
2085 case_preserve = lp_preservecase(snum);
2086 short_case_preserve = lp_shortpreservecase(snum);
2087 case_mangle = lp_casemangle(snum);
2088 case_sensitive = lp_casesensitive(snum);
2089 magic_char = lp_magicchar(snum);
2090 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2095 /****************************************************************************
2096 find a service entry
2097 ****************************************************************************/
2098 int find_service(char *service)
2102 string_sub(service,"\\","/");
2104 iService = lp_servicenumber(service);
2106 /* now handle the special case of a home directory */
2109 char *phome_dir = get_home_dir(service);
2110 DEBUG(3,("checking for home directory %s gave %s\n",service,
2111 phome_dir?phome_dir:"(NULL)"));
2115 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2117 lp_add_home(service,iHomeService,phome_dir);
2118 iService = lp_servicenumber(service);
2123 /* If we still don't have a service, attempt to add it as a printer. */
2126 int iPrinterService;
2128 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2132 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2134 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2136 DEBUG(3,("%s is a valid printer name\n", service));
2137 DEBUG(3,("adding %s as a printer service\n", service));
2138 lp_add_printer(service,iPrinterService);
2139 iService = lp_servicenumber(service);
2141 DEBUG(0,("failed to add %s as a printer service!\n", service));
2144 DEBUG(3,("%s is not a valid printer name\n", service));
2148 /* just possibly it's a default service? */
2151 char *defservice = lp_defaultservice();
2152 if (defservice && *defservice && !strequal(defservice,service)) {
2153 iService = find_service(defservice);
2154 if (iService >= 0) {
2155 string_sub(service,"_","/");
2156 iService = lp_add_service(service,iService);
2162 if (!VALID_SNUM(iService))
2164 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2169 DEBUG(3,("find_service() failed to find service %s\n", service));
2175 /****************************************************************************
2176 create an error packet from a cached error.
2177 ****************************************************************************/
2178 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2180 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2182 int32 eclass = wbmpx->wr_errclass;
2183 int32 err = wbmpx->wr_error;
2185 /* We can now delete the auxiliary struct */
2186 free((char *)wbmpx);
2187 Files[fnum].wbmpx_ptr = NULL;
2188 return error_packet(inbuf,outbuf,eclass,err,line);
2197 } unix_smb_errmap[] =
2199 {EPERM,ERRDOS,ERRnoaccess},
2200 {EACCES,ERRDOS,ERRnoaccess},
2201 {ENOENT,ERRDOS,ERRbadfile},
2202 {ENOTDIR,ERRDOS,ERRbadpath},
2203 {EIO,ERRHRD,ERRgeneral},
2204 {EBADF,ERRSRV,ERRsrverror},
2205 {EINVAL,ERRSRV,ERRsrverror},
2206 {EEXIST,ERRDOS,ERRfilexists},
2207 {ENFILE,ERRDOS,ERRnofids},
2208 {EMFILE,ERRDOS,ERRnofids},
2209 {ENOSPC,ERRHRD,ERRdiskfull},
2211 {EDQUOT,ERRHRD,ERRdiskfull},
2214 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2217 {EXDEV,ERRDOS,ERRdiffdevice},
2219 {EROFS,ERRHRD,ERRnowrite},
2223 /****************************************************************************
2224 create an error packet from errno
2225 ****************************************************************************/
2226 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2228 int eclass=def_class;
2232 if (unix_ERR_class != SUCCESS)
2234 eclass = unix_ERR_class;
2235 ecode = unix_ERR_code;
2236 unix_ERR_class = SUCCESS;
2241 while (unix_smb_errmap[i].smbclass != 0)
2243 if (unix_smb_errmap[i].unixerror == errno)
2245 eclass = unix_smb_errmap[i].smbclass;
2246 ecode = unix_smb_errmap[i].smbcode;
2253 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2257 /****************************************************************************
2258 create an error packet. Normally called using the ERROR() macro
2259 ****************************************************************************/
2260 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2262 int outsize = set_message(outbuf,0,0,True);
2264 cmd = CVAL(inbuf,smb_com);
2266 CVAL(outbuf,smb_rcls) = error_class;
2267 SSVAL(outbuf,smb_err,error_code);
2269 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2272 (int)CVAL(inbuf,smb_com),
2273 smb_fn_name(CVAL(inbuf,smb_com)),
2278 DEBUG(3,("error string = %s\n",strerror(errno)));
2284 #ifndef SIGCLD_IGNORE
2285 /****************************************************************************
2286 this prevents zombie child processes
2287 ****************************************************************************/
2288 static int sig_cld()
2290 static int depth = 0;
2293 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2299 BlockSignals(True,SIGCLD);
2300 DEBUG(5,("got SIGCLD\n"));
2303 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2307 /* Stevens, Adv. Unix Prog. says that on system V you must call
2308 wait before reinstalling the signal handler, because the kernel
2309 calls the handler from within the signal-call when there is a
2310 child that has exited. This would lead to an infinite recursion
2311 if done vice versa. */
2313 #ifndef DONT_REINSTALL_SIG
2314 #ifdef SIGCLD_IGNORE
2315 signal(SIGCLD, SIG_IGN);
2317 signal(SIGCLD, SIGNAL_CAST sig_cld);
2322 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2325 BlockSignals(False,SIGCLD);
2330 /****************************************************************************
2331 this is called when the client exits abruptly
2332 **************************************************************************/
2333 static int sig_pipe()
2335 struct cli_state *cli;
2336 BlockSignals(True,SIGPIPE);
2338 if ((cli = server_client()) && cli->initialised) {
2339 DEBUG(3,("lost connection to password server\n"));
2341 #ifndef DONT_REINSTALL_SIG
2342 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2344 BlockSignals(False,SIGPIPE);
2348 exit_server("Got sigpipe\n");
2352 /****************************************************************************
2353 open the socket communication
2354 ****************************************************************************/
2355 static BOOL open_sockets(BOOL is_daemon,int port)
2361 int num_interfaces = iface_count();
2362 int fd_listenset[FD_SETSIZE];
2368 #ifdef SIGCLD_IGNORE
2369 signal(SIGCLD, SIG_IGN);
2371 signal(SIGCLD, SIGNAL_CAST sig_cld);
2377 FD_ZERO(&listen_set);
2379 if(lp_interfaces() && lp_bind_interfaces_only())
2381 /* We have been given an interfaces line, and been
2382 told to only bind to those interfaces. Create a
2383 socket per interface and bind to only these.
2386 if(num_interfaces > FD_SETSIZE)
2388 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2389 max can be %d\n", num_interfaces, FD_SETSIZE));
2393 /* Now open a listen socket for each of the interfaces. */
2394 for(i = 0; i < num_interfaces; i++)
2396 struct in_addr *ifip = iface_n_ip(i);
2400 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2403 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2406 /* ready to listen */
2407 if (listen(s, 5) == -1)
2409 DEBUG(0,("listen: %s\n",strerror(errno)));
2413 FD_SET(s,&listen_set);
2418 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2421 /* open an incoming socket */
2422 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2426 /* ready to listen */
2427 if (listen(s, 5) == -1)
2429 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2434 fd_listenset[0] = s;
2435 FD_SET(s,&listen_set);
2438 /* now accept incoming connections - forking a new process
2439 for each incoming connection */
2440 DEBUG(2,("waiting for a connection\n"));
2446 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2448 num = sys_select(&lfds,NULL);
2450 if (num == -1 && errno == EINTR)
2453 /* Find the sockets that are read-ready - accept on these. */
2454 for( ; num > 0; num--)
2456 struct sockaddr addr;
2457 int in_addrlen = sizeof(addr);
2460 for(i = 0; i < num_interfaces; i++)
2462 if(FD_ISSET(fd_listenset[i],&lfds))
2464 s = fd_listenset[i];
2465 /* Clear this so we don't look at it again. */
2466 FD_CLR(fd_listenset[i],&lfds);
2471 Client = accept(s,&addr,&in_addrlen);
2473 if (Client == -1 && errno == EINTR)
2478 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2482 #ifdef NO_FORK_DEBUG
2483 #ifndef NO_SIGNAL_TEST
2484 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2485 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2486 #endif /* NO_SIGNAL_TEST */
2488 #else /* NO_FORK_DEBUG */
2489 if (Client != -1 && fork()==0)
2491 /* Child code ... */
2493 #ifndef NO_SIGNAL_TEST
2494 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2495 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2496 #endif /* NO_SIGNAL_TEST */
2497 /* close the listening socket(s) */
2498 for(i = 0; i < num_interfaces; i++)
2499 close(fd_listenset[i]);
2501 /* close our standard file descriptors */
2505 set_socket_options(Client,"SO_KEEPALIVE");
2506 set_socket_options(Client,user_socket_options);
2508 /* Reset global variables in util.c so that
2509 client substitutions will be done correctly
2512 reset_globals_after_fork();
2515 close(Client); /* The parent doesn't need this socket */
2516 #endif /NO_FORK_DEBUG */
2519 } /* end if is_daemon */
2522 /* Started from inetd. fd 0 is the socket. */
2523 /* We will abort gracefully when the client or remote system
2525 #ifndef NO_SIGNAL_TEST
2526 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2530 /* close our standard file descriptors */
2533 set_socket_options(Client,"SO_KEEPALIVE");
2534 set_socket_options(Client,user_socket_options);
2540 /****************************************************************************
2541 process an smb from the client - split out from the process() code so
2542 it can be used by the oplock break code.
2543 ****************************************************************************/
2545 static void process_smb(char *inbuf, char *outbuf)
2548 static int trans_num;
2549 int msg_type = CVAL(inbuf,0);
2550 int32 len = smb_len(inbuf);
2551 int nread = len + 4;
2553 if (trans_num == 0) {
2554 /* on the first packet, check the global hosts allow/ hosts
2555 deny parameters before doing any parsing of the packet
2556 passed to us by the client. This prevents attacks on our
2557 parsing code from hosts not in the hosts allow list */
2558 if (!check_access(-1)) {
2559 /* send a negative session response "not listining on calling
2561 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2562 DEBUG(1,("%s Connection denied from %s\n",
2563 timestring(),client_addr()));
2564 send_smb(Client,(char *)buf);
2565 exit_server("connection denied");
2569 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2570 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2573 if(trans_num == 1 && VT_Check(inbuf))
2583 nread = construct_reply(inbuf,outbuf,nread,max_send);
2587 if (CVAL(outbuf,0) == 0)
2590 if (nread != smb_len(outbuf) + 4)
2592 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2593 nread, smb_len(outbuf)));
2596 send_smb(Client,outbuf);
2601 /****************************************************************************
2602 open the oplock IPC socket communication
2603 ****************************************************************************/
2604 static BOOL open_oplock_ipc()
2606 struct sockaddr_in sock_name;
2607 int len = sizeof(sock_name);
2609 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2611 /* Open a lookback UDP socket on a random port. */
2612 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2613 if (oplock_sock == -1)
2615 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2616 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2621 /* Find out the transient UDP port we have been allocated. */
2622 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2624 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2631 oplock_port = ntohs(sock_name.sin_port);
2633 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2634 getpid(), oplock_port));
2639 /****************************************************************************
2640 process an oplock break message.
2641 ****************************************************************************/
2642 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2648 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2649 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2651 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2653 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2654 msg_len, from_port));
2656 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2657 only valid request. */
2659 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2661 case OPLOCK_BREAK_CMD:
2662 /* Ensure that the msg length is correct. */
2663 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2665 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2666 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2670 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2671 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2672 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2673 struct timeval tval;
2674 struct sockaddr_in toaddr;
2676 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2677 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2679 DEBUG(5,("process_local_message: oplock break request from \
2680 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2683 * If we have no record of any currently open oplocks,
2684 * it's not an error, as a close command may have
2685 * just been issued on the file that was oplocked.
2686 * Just return success in this case.
2689 if(global_oplocks_open != 0)
2691 if(oplock_break(dev, inode, &tval) == False)
2693 DEBUG(0,("process_local_message: oplock break failed - \
2694 not returning udp message.\n"));
2700 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2701 oplocks. Returning success.\n"));
2704 /* Send the message back after OR'ing in the 'REPLY' bit. */
2705 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2707 bzero((char *)&toaddr,sizeof(toaddr));
2708 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2709 toaddr.sin_port = htons(from_port);
2710 toaddr.sin_family = AF_INET;
2712 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2713 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2715 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2716 remotepid, strerror(errno)));
2720 DEBUG(5,("process_local_message: oplock break reply sent to \
2721 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2722 from_port, dev, inode));
2727 * Keep this as a debug case - eventually we can remove it.
2730 DEBUG(0,("process_local_message: Received unsolicited break \
2731 reply - dumping info.\n"));
2733 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2735 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2736 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2741 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2742 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2743 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2745 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2746 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2752 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2753 (unsigned int)SVAL(msg_start,0)));
2759 /****************************************************************************
2760 Process an oplock break directly.
2761 ****************************************************************************/
2762 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2765 static char *inbuf = NULL;
2766 static char *outbuf = NULL;
2767 files_struct *fsp = NULL;
2770 BOOL shutdown_server = False;
2772 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2773 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2777 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2779 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2782 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2783 if(outbuf == NULL) {
2784 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2791 /* We need to search the file open table for the
2792 entry containing this dev and inode, and ensure
2793 we have an oplock on it. */
2794 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2799 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2800 (fsp->open_time.tv_sec == tval->tv_sec) &&
2801 (fsp->open_time.tv_usec == tval->tv_usec))
2808 /* The file could have been closed in the meantime - return success. */
2809 DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2810 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2814 /* Ensure we have an oplock on the file */
2816 /* There is a potential race condition in that an oplock could
2817 have been broken due to another udp request, and yet there are
2818 still oplock break messages being sent in the udp message
2819 queue for this file. So return true if we don't have an oplock,
2820 as we may have just freed it.
2823 if(!fsp->granted_oplock)
2825 DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2826 Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2830 /* Now comes the horrid part. We must send an oplock break to the client,
2831 and then process incoming messages until we get a close or oplock release.
2834 /* Prepare the SMBlockingX message. */
2835 bzero(outbuf,smb_size);
2836 set_message(outbuf,8,0,True);
2838 SCVAL(outbuf,smb_com,SMBlockingX);
2839 SSVAL(outbuf,smb_tid,fsp->cnum);
2840 SSVAL(outbuf,smb_pid,0xFFFF);
2841 SSVAL(outbuf,smb_uid,0);
2842 SSVAL(outbuf,smb_mid,0xFFFF);
2843 SCVAL(outbuf,smb_vwv0,0xFF);
2844 SSVAL(outbuf,smb_vwv2,fnum);
2845 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2846 /* Change this when we have level II oplocks. */
2847 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2849 send_smb(Client, outbuf);
2851 /* We need this in case a readraw crosses on the wire. */
2852 global_oplock_break = True;
2854 /* Process incoming messages. */
2856 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2857 seconds we should just die.... */
2859 start_time = time(NULL);
2861 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2863 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2866 * Die if we got an error.
2869 if (smb_read_error == READ_EOF)
2870 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2872 if (smb_read_error == READ_ERROR)
2873 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2874 timestring(), strerror(errno)));
2876 if (smb_read_error == READ_TIMEOUT)
2877 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2878 timestring(), OPLOCK_BREAK_TIMEOUT));
2880 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2881 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2882 shutdown_server = True;
2885 process_smb(inbuf, outbuf);
2888 * Die if we go over the time limit.
2891 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2893 DEBUG(0,("%s oplock_break: no break received from client within \
2894 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2895 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2896 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2897 shutdown_server = True;
2902 /* We need this in case a readraw crossed on the wire. */
2903 if(global_oplock_break)
2904 global_oplock_break = False;
2907 * If the client did not respond we must die.
2912 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2916 exit_server("oplock break failure");
2921 /* The lockingX reply will have removed the oplock flag
2922 from the sharemode. */
2924 fsp->granted_oplock = False;
2925 global_oplocks_open--;
2928 /* Santity check - remove this later. JRA */
2929 if(global_oplocks_open < 0)
2931 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2932 global_oplocks_open));
2933 exit_server("oplock_break: global_oplocks_open < 0");
2936 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2937 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2942 /****************************************************************************
2943 Send an oplock break message to another smbd process. If the oplock is held
2944 by the local smbd then call the oplock break function directly.
2945 ****************************************************************************/
2947 BOOL request_oplock_break(share_mode_entry *share_entry,
2948 uint32 dev, uint32 inode)
2950 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2951 struct sockaddr_in addr_out;
2954 if(pid == share_entry->pid)
2956 /* We are breaking our own oplock, make sure it's us. */
2957 if(share_entry->op_port != oplock_port)
2959 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2960 should be %d\n", pid, share_entry->op_port, oplock_port));
2964 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2966 /* Call oplock break direct. */
2967 return oplock_break(dev, inode, &share_entry->time);
2970 /* We need to send a OPLOCK_BREAK_CMD message to the
2971 port in the share mode entry. */
2973 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2974 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2975 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2976 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2977 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2978 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2980 /* set the address and port */
2981 bzero((char *)&addr_out,sizeof(addr_out));
2982 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2983 addr_out.sin_port = htons( share_entry->op_port );
2984 addr_out.sin_family = AF_INET;
2986 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2987 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
2989 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2990 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2992 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2993 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2994 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3000 * Now we must await the oplock broken message coming back
3001 * from the target smbd process. Timeout if it fails to
3002 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3003 * While we get messages that aren't ours, loop.
3008 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3009 int32 reply_msg_len;
3010 uint16 reply_from_port;
3011 char *reply_msg_start;
3013 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3014 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3016 if(smb_read_error == READ_TIMEOUT)
3018 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3019 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3020 share_entry->op_port, dev, inode));
3022 * This is a hack to make handling of failing clients more robust.
3023 * If a oplock break response message is not received in the timeout
3024 * period we may assume that the smbd servicing that client holding
3025 * the oplock has died and the client changes were lost anyway, so
3026 * we should continue to try and open the file.
3031 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3032 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3033 share_entry->op_port, dev, inode, strerror(errno)));
3038 * If the response we got was not an answer to our message, but
3039 * was a completely different request, push it onto the pending
3040 * udp message stack so that we can deal with it in the main loop.
3041 * It may be another oplock break request to us.
3045 * Local note from JRA. There exists the possibility of a denial
3046 * of service attack here by allowing non-root processes running
3047 * on a local machine sending many of these pending messages to
3048 * a smbd port. Currently I'm not sure how to restrict the messages
3049 * I will queue (although I could add a limit to the queue) to
3050 * those received by root processes only. There should be a
3051 * way to make this bulletproof....
3054 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3055 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3057 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3059 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3062 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3067 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3068 (reply_from_port != share_entry->op_port) ||
3069 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3070 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3071 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3073 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3074 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3075 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3076 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3084 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3089 /****************************************************************************
3090 Get the next SMB packet, doing the local message processing automatically.
3091 ****************************************************************************/
3093 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3095 BOOL got_smb = False;
3100 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3105 /* Deal with oplock break requests from other smbd's. */
3106 process_local_message(oplock_sock, inbuf, bufsize);
3110 while(ret && !got_smb);
3115 /****************************************************************************
3116 check if a snum is in use
3117 ****************************************************************************/
3118 BOOL snum_used(int snum)
3121 for (i=0;i<MAX_CONNECTIONS;i++)
3122 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3127 /****************************************************************************
3128 reload the services file
3129 **************************************************************************/
3130 BOOL reload_services(BOOL test)
3137 pstrcpy(fname,lp_configfile());
3138 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3140 pstrcpy(servicesf,fname);
3147 if (test && !lp_file_list_changed())
3150 lp_killunused(snum_used);
3152 ret = lp_load(servicesf,False);
3154 /* perhaps the config filename is now set */
3156 reload_services(True);
3165 set_socket_options(Client,"SO_KEEPALIVE");
3166 set_socket_options(Client,user_socket_options);
3170 reset_mangled_stack( lp_mangledstack() );
3172 /* this forces service parameters to be flushed */
3173 become_service(-1,True);
3180 /****************************************************************************
3181 this prevents zombie child processes
3182 ****************************************************************************/
3183 static int sig_hup()
3185 BlockSignals(True,SIGHUP);
3186 DEBUG(0,("Got SIGHUP\n"));
3187 reload_services(False);
3188 #ifndef DONT_REINSTALL_SIG
3189 signal(SIGHUP,SIGNAL_CAST sig_hup);
3191 BlockSignals(False,SIGHUP);
3195 /****************************************************************************
3196 Setup the groups a user belongs to.
3197 ****************************************************************************/
3198 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3199 int **p_igroups, gid_t **p_groups,
3202 if (-1 == initgroups(user,gid))
3206 DEBUG(0,("Unable to initgroups!\n"));
3207 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3208 DEBUG(0,("This is probably a problem with the account %s\n",user));
3217 ngroups = getgroups(0,&grp);
3220 igroups = (int *)malloc(sizeof(int)*ngroups);
3221 attrs = (int *)malloc(sizeof(int)*ngroups);
3222 for (i=0;i<ngroups;i++)
3224 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3225 igroups[i] = 0x42424242;
3227 ngroups = getgroups(ngroups,(gid_t *)igroups);
3229 if (igroups[0] == 0x42424242)
3232 *p_ngroups = ngroups;
3235 /* The following bit of code is very strange. It is due to the
3236 fact that some OSes use int* and some use gid_t* for
3237 getgroups, and some (like SunOS) use both, one in prototypes,
3238 and one in man pages and the actual code. Thus we detect it
3239 dynamically using some very ugly code */
3242 /* does getgroups return ints or gid_t ?? */
3243 static BOOL groups_use_ints = True;
3245 if (groups_use_ints &&
3247 SVAL(igroups,2) == 0x4242)
3248 groups_use_ints = False;
3250 for (i=0;groups_use_ints && i<ngroups;i++)
3251 if (igroups[i] == 0x42424242)
3252 groups_use_ints = False;
3254 if (groups_use_ints)
3256 *p_igroups = igroups;
3257 *p_groups = (gid_t *)igroups;
3261 gid_t *groups = (gid_t *)igroups;
3262 igroups = (int *)malloc(sizeof(int)*ngroups);
3263 for (i=0;i<ngroups;i++)
3265 igroups[i] = groups[i];
3267 *p_igroups = igroups;
3268 *p_groups = (gid_t *)groups;
3271 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3272 for (i=0;i<ngroups;i++)
3273 DEBUG(3,("%d ",igroups[i]));
3279 /****************************************************************************
3280 make a connection to a service
3281 ****************************************************************************/
3282 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3286 struct passwd *pass = NULL;
3287 connection_struct *pcon;
3290 static BOOL first_connection = True;
3294 snum = find_service(service);
3297 if (strequal(service,"IPC$"))
3299 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3303 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3307 if (strequal(service,HOMES_NAME))
3309 if (*user && Get_Pwnam(user,True))
3310 return(make_connection(user,user,password,pwlen,dev,vuid));
3312 if (validated_username(vuid))
3314 strcpy(user,validated_username(vuid));
3315 return(make_connection(user,user,password,pwlen,dev,vuid));
3319 if (!lp_snum_ok(snum) || !check_access(snum)) {
3323 /* you can only connect to the IPC$ service as an ipc device */
3324 if (strequal(service,"IPC$"))
3327 if (*dev == '?' || !*dev)
3329 if (lp_print_ok(snum))
3330 strcpy(dev,"LPT1:");
3335 /* if the request is as a printer and you can't print then refuse */
3337 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3338 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3342 /* lowercase the user name */
3345 /* add it as a possible user name */
3346 add_session_user(service);
3348 /* shall we let them in? */
3349 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3351 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3355 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3358 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3362 pcon = &Connections[cnum];
3363 bzero((char *)pcon,sizeof(*pcon));
3365 /* find out some info about the user */
3366 pass = Get_Pwnam(user,True);
3370 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3374 pcon->read_only = lp_readonly(snum);
3378 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3379 string_sub(list,"%S",service);
3381 if (user_in_list(user,list))
3382 pcon->read_only = True;
3384 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3385 string_sub(list,"%S",service);
3387 if (user_in_list(user,list))
3388 pcon->read_only = False;
3391 /* admin user check */
3393 /* JRA - original code denied admin user if the share was
3394 marked read_only. Changed as I don't think this is needed,
3395 but old code left in case there is a problem here.
3397 if (user_in_list(user,lp_admin_users(snum))
3399 && !pcon->read_only)
3404 pcon->admin_user = True;
3405 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3408 pcon->admin_user = False;
3410 pcon->force_user = force;
3412 pcon->uid = pass->pw_uid;
3413 pcon->gid = pass->pw_gid;
3414 pcon->num_files_open = 0;
3415 pcon->lastused = time(NULL);
3416 pcon->service = snum;
3418 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3419 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3420 pcon->dirptr = NULL;
3421 pcon->veto_list = NULL;
3422 pcon->hide_list = NULL;
3423 pcon->veto_oplock_list = NULL;
3424 string_set(&pcon->dirpath,"");
3425 string_set(&pcon->user,user);
3428 if (*lp_force_group(snum))
3433 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3434 /* default service may be a group name */
3435 string_sub(gname,"%S",service);
3436 gptr = (struct group *)getgrnam(gname);
3440 pcon->gid = gptr->gr_gid;
3441 DEBUG(3,("Forced group %s\n",gname));
3444 DEBUG(1,("Couldn't find group %s\n",gname));
3448 if (*lp_force_user(snum))
3450 struct passwd *pass2;
3452 fstrcpy(fuser,lp_force_user(snum));
3453 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3456 pcon->uid = pass2->pw_uid;
3457 string_set(&pcon->user,fuser);
3458 fstrcpy(user,fuser);
3459 pcon->force_user = True;
3460 DEBUG(3,("Forced user %s\n",fuser));
3463 DEBUG(1,("Couldn't find user %s\n",fuser));
3468 pstrcpy(s,lp_pathname(snum));
3469 standard_sub(cnum,s);
3470 string_set(&pcon->connectpath,s);
3471 DEBUG(3,("Connect path is %s\n",s));
3474 /* groups stuff added by ih */
3476 pcon->igroups = NULL;
3477 pcon->groups = NULL;
3482 /* Find all the groups this uid is in and store them. Used by become_user() */
3483 setup_groups(pcon->user,pcon->uid,pcon->gid,
3484 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3486 /* check number of connections */
3487 if (!claim_connection(cnum,
3488 lp_servicename(SNUM(cnum)),
3489 lp_max_connections(SNUM(cnum)),False))
3491 DEBUG(1,("too many connections - rejected\n"));
3495 if (lp_status(SNUM(cnum)))
3496 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3498 first_connection = False;
3503 /* execute any "root preexec = " line */
3504 if (*lp_rootpreexec(SNUM(cnum)))
3507 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3508 standard_sub(cnum,cmd);
3509 DEBUG(5,("cmd=%s\n",cmd));
3510 smbrun(cmd,NULL,False);
3513 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3515 DEBUG(0,("Can't become connected user!\n"));
3517 if (!IS_IPC(cnum)) {
3518 yield_connection(cnum,
3519 lp_servicename(SNUM(cnum)),
3520 lp_max_connections(SNUM(cnum)));
3521 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3526 if (ChDir(pcon->connectpath) != 0)
3528 DEBUG(0,("Can't change directory to %s (%s)\n",
3529 pcon->connectpath,strerror(errno)));
3532 if (!IS_IPC(cnum)) {
3533 yield_connection(cnum,
3534 lp_servicename(SNUM(cnum)),
3535 lp_max_connections(SNUM(cnum)));
3536 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3541 string_set(&pcon->origpath,pcon->connectpath);
3543 #if SOFTLINK_OPTIMISATION
3544 /* resolve any soft links early */
3547 pstrcpy(s,pcon->connectpath);
3549 string_set(&pcon->connectpath,s);
3550 ChDir(pcon->connectpath);
3554 num_connections_open++;
3555 add_session_user(user);
3557 /* execute any "preexec = " line */
3558 if (*lp_preexec(SNUM(cnum)))
3561 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3562 standard_sub(cnum,cmd);
3563 smbrun(cmd,NULL,False);
3566 /* we've finished with the sensitive stuff */
3569 /* Add veto/hide lists */
3570 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3572 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3573 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3574 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3578 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3582 lp_servicename(SNUM(cnum)),user,
3592 /****************************************************************************
3593 find first available file slot
3594 ****************************************************************************/
3595 int find_free_file(void )
3598 /* we start at 1 here for an obscure reason I can't now remember,
3599 but I think is important :-) */
3600 for (i=1;i<MAX_OPEN_FILES;i++)
3603 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3607 /****************************************************************************
3608 find first available connection slot, starting from a random position.
3609 The randomisation stops problems with the server dieing and clients
3610 thinking the server is still available.
3611 ****************************************************************************/
3612 static int find_free_connection(int hash )
3616 hash = (hash % (MAX_CONNECTIONS-2))+1;
3620 for (i=hash+1;i!=hash;)
3622 if (!Connections[i].open && Connections[i].used == used)
3624 DEBUG(3,("found free connection number %d\n",i));
3628 if (i == MAX_CONNECTIONS)
3638 DEBUG(1,("ERROR! Out of connection structures\n"));
3643 /****************************************************************************
3644 reply for the core protocol
3645 ****************************************************************************/
3646 int reply_corep(char *outbuf)
3648 int outsize = set_message(outbuf,1,0,True);
3650 Protocol = PROTOCOL_CORE;
3656 /****************************************************************************
3657 reply for the coreplus protocol
3658 ****************************************************************************/
3659 int reply_coreplus(char *outbuf)
3661 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3662 int outsize = set_message(outbuf,13,0,True);
3663 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3664 readbraw and writebraw (possibly) */
3665 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3666 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3668 Protocol = PROTOCOL_COREPLUS;
3674 /****************************************************************************
3675 reply for the lanman 1.0 protocol
3676 ****************************************************************************/
3677 int reply_lanman1(char *outbuf)
3679 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3681 BOOL doencrypt = SMBENCRYPT();
3682 time_t t = time(NULL);
3684 if (lp_security()>=SEC_USER) secword |= 1;
3685 if (doencrypt) secword |= 2;
3687 set_message(outbuf,13,doencrypt?8:0,True);
3688 SSVAL(outbuf,smb_vwv1,secword);
3689 /* Create a token value and add it to the outgoing packet. */
3691 generate_next_challenge(smb_buf(outbuf));
3693 Protocol = PROTOCOL_LANMAN1;
3695 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3696 SSVAL(outbuf,smb_vwv2,max_recv);
3697 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3698 SSVAL(outbuf,smb_vwv4,1);
3699 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3700 readbraw writebraw (possibly) */
3701 SIVAL(outbuf,smb_vwv6,getpid());
3702 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3704 put_dos_date(outbuf,smb_vwv8,t);
3706 return (smb_len(outbuf)+4);
3710 /****************************************************************************
3711 reply for the lanman 2.0 protocol
3712 ****************************************************************************/
3713 int reply_lanman2(char *outbuf)
3715 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3717 BOOL doencrypt = SMBENCRYPT();
3718 time_t t = time(NULL);
3719 struct cli_state *cli = NULL;
3723 if (lp_security() == SEC_SERVER) {
3724 cli = server_cryptkey();
3728 DEBUG(3,("using password server validation\n"));
3729 doencrypt = ((cli->sec_mode & 2) != 0);
3732 if (lp_security()>=SEC_USER) secword |= 1;
3733 if (doencrypt) secword |= 2;
3738 generate_next_challenge(cryptkey);
3740 memcpy(cryptkey, cli->cryptkey, 8);
3741 set_challenge(cli->cryptkey);
3745 set_message(outbuf,13,crypt_len,True);
3746 SSVAL(outbuf,smb_vwv1,secword);
3747 SIVAL(outbuf,smb_vwv6,getpid());
3749 memcpy(smb_buf(outbuf), cryptkey, 8);
3751 Protocol = PROTOCOL_LANMAN2;
3753 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3754 SSVAL(outbuf,smb_vwv2,max_recv);
3755 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3756 SSVAL(outbuf,smb_vwv4,1);
3757 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3758 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3759 put_dos_date(outbuf,smb_vwv8,t);
3761 return (smb_len(outbuf)+4);
3765 /****************************************************************************
3766 reply for the nt protocol
3767 ****************************************************************************/
3768 int reply_nt1(char *outbuf)
3770 /* dual names + lock_and_read + nt SMBs + remote API calls */
3771 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3773 other valid capabilities which we may support at some time...
3774 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3775 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3779 BOOL doencrypt = SMBENCRYPT();
3780 time_t t = time(NULL);
3782 struct cli_state *cli = NULL;
3786 if (lp_security() == SEC_SERVER) {
3787 cli = server_cryptkey();
3791 DEBUG(3,("using password server validation\n"));
3792 doencrypt = ((cli->sec_mode & 2) != 0);
3798 generate_next_challenge(cryptkey);
3800 memcpy(cryptkey, cli->cryptkey, 8);
3801 set_challenge(cli->cryptkey);
3805 if (lp_readraw() && lp_writeraw()) {
3806 capabilities |= CAP_RAW_MODE;
3809 if (lp_security() >= SEC_USER) secword |= 1;
3810 if (doencrypt) secword |= 2;
3812 /* decide where (if) to put the encryption challenge, and
3813 follow it with the OEM'd domain name
3815 data_len = crypt_len + strlen(myworkgroup) + 1;
3817 set_message(outbuf,17,data_len,True);
3818 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3820 CVAL(outbuf,smb_vwv1) = secword;
3821 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3823 memcpy(smb_buf(outbuf), cryptkey, 8);
3825 Protocol = PROTOCOL_NT1;
3827 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3828 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3829 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3830 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3831 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3832 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3833 put_long_date(outbuf+smb_vwv11+1,t);
3834 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3835 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3837 return (smb_len(outbuf)+4);
3840 /* these are the protocol lists used for auto architecture detection:
3843 protocol [PC NETWORK PROGRAM 1.0]
3844 protocol [XENIX CORE]
3845 protocol [MICROSOFT NETWORKS 1.03]
3846 protocol [LANMAN1.0]
3847 protocol [Windows for Workgroups 3.1a]
3848 protocol [LM1.2X002]
3849 protocol [LANMAN2.1]
3850 protocol [NT LM 0.12]
3853 protocol [PC NETWORK PROGRAM 1.0]
3854 protocol [XENIX CORE]
3855 protocol [MICROSOFT NETWORKS 1.03]
3856 protocol [LANMAN1.0]
3857 protocol [Windows for Workgroups 3.1a]
3858 protocol [LM1.2X002]
3859 protocol [LANMAN2.1]
3860 protocol [NT LM 0.12]
3863 protocol [PC NETWORK PROGRAM 1.0]
3864 protocol [XENIX CORE]
3865 protocol [LANMAN1.0]
3866 protocol [LM1.2X002]
3867 protocol [LANMAN2.1]
3871 * Modified to recognize the architecture of the remote machine better.
3873 * This appears to be the matrix of which protocol is used by which
3875 Protocol WfWg Win95 WinNT OS/2
3876 PC NETWORK PROGRAM 1.0 1 1 1 1
3878 MICROSOFT NETWORKS 3.0 2 2
3880 MICROSOFT NETWORKS 1.03 3
3883 Windows for Workgroups 3.1a 5 5 5
3888 * tim@fsg.com 09/29/95
3891 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3892 #define ARCH_WIN95 0x2
3893 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3894 #define ARCH_WINNT 0x8
3895 #define ARCH_SAMBA 0x10
3897 #define ARCH_ALL 0x1F
3899 /* List of supported protocols, most desired first */
3903 int (*proto_reply_fn)(char *);
3905 } supported_protocols[] = {
3906 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3907 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3908 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3909 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3910 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3911 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3912 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3913 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3914 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3919 /****************************************************************************
3921 ****************************************************************************/
3922 static int reply_negprot(char *inbuf,char *outbuf)
3924 int outsize = set_message(outbuf,1,0,True);
3929 int bcc = SVAL(smb_buf(inbuf),-2);
3930 int arch = ARCH_ALL;
3932 p = smb_buf(inbuf)+1;
3933 while (p < (smb_buf(inbuf) + bcc))
3936 DEBUG(3,("Requested protocol [%s]\n",p));
3937 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3938 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3939 else if (strcsequal(p,"DOS LM1.2X002"))
3940 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3941 else if (strcsequal(p,"DOS LANMAN2.1"))
3942 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3943 else if (strcsequal(p,"NT LM 0.12"))
3944 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3945 else if (strcsequal(p,"LANMAN2.1"))
3946 arch &= ( ARCH_WINNT | ARCH_OS2 );
3947 else if (strcsequal(p,"LM1.2X002"))
3948 arch &= ( ARCH_WINNT | ARCH_OS2 );
3949 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3951 else if (strcsequal(p,"XENIX CORE"))
3952 arch &= ( ARCH_WINNT | ARCH_OS2 );
3953 else if (strcsequal(p,"Samba")) {
3963 set_remote_arch(RA_SAMBA);
3966 set_remote_arch(RA_WFWG);
3969 set_remote_arch(RA_WIN95);
3972 set_remote_arch(RA_WINNT);
3975 set_remote_arch(RA_OS2);
3978 set_remote_arch(RA_UNKNOWN);
3982 /* possibly reload - change of architecture */
3983 reload_services(True);
3985 /* a special case to stop password server loops */
3986 if (Index == 1 && strequal(remote_machine,myhostname) &&
3987 lp_security()==SEC_SERVER)
3988 exit_server("Password server loop!");
3990 /* Check for protocols, most desirable first */
3991 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3993 p = smb_buf(inbuf)+1;
3995 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3996 while (p < (smb_buf(inbuf) + bcc))
3998 if (strequal(p,supported_protocols[protocol].proto_name))
4007 SSVAL(outbuf,smb_vwv0,choice);
4009 extern fstring remote_proto;
4010 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4011 reload_services(True);
4012 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4013 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4016 DEBUG(0,("No protocol supported !\n"));
4018 SSVAL(outbuf,smb_vwv0,choice);
4020 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4026 /****************************************************************************
4027 close all open files for a connection
4028 ****************************************************************************/
4029 static void close_open_files(int cnum)
4032 for (i=0;i<MAX_OPEN_FILES;i++)
4033 if( Files[i].cnum == cnum && Files[i].open) {
4034 close_file(i,False);
4040 /****************************************************************************
4042 ****************************************************************************/
4043 void close_cnum(int cnum, uint16 vuid)
4045 DirCacheFlush(SNUM(cnum));
4049 if (!OPEN_CNUM(cnum))
4051 DEBUG(0,("Can't close cnum %d\n",cnum));
4055 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4057 remote_machine,client_addr(),
4058 lp_servicename(SNUM(cnum))));
4060 yield_connection(cnum,
4061 lp_servicename(SNUM(cnum)),
4062 lp_max_connections(SNUM(cnum)));
4064 if (lp_status(SNUM(cnum)))
4065 yield_connection(cnum,"STATUS.",MAXSTATUS);
4067 close_open_files(cnum);
4068 dptr_closecnum(cnum);
4070 /* execute any "postexec = " line */
4071 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4074 strcpy(cmd,lp_postexec(SNUM(cnum)));
4075 standard_sub(cnum,cmd);
4076 smbrun(cmd,NULL,False);
4081 /* execute any "root postexec = " line */
4082 if (*lp_rootpostexec(SNUM(cnum)))
4085 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4086 standard_sub(cnum,cmd);
4087 smbrun(cmd,NULL,False);
4090 Connections[cnum].open = False;
4091 num_connections_open--;
4092 if (Connections[cnum].ngroups && Connections[cnum].groups)
4094 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4095 free(Connections[cnum].groups);
4096 free(Connections[cnum].igroups);
4097 Connections[cnum].groups = NULL;
4098 Connections[cnum].igroups = NULL;
4099 Connections[cnum].ngroups = 0;
4102 free_namearray(Connections[cnum].veto_list);
4103 free_namearray(Connections[cnum].hide_list);
4104 free_namearray(Connections[cnum].veto_oplock_list);
4106 string_set(&Connections[cnum].user,"");
4107 string_set(&Connections[cnum].dirpath,"");
4108 string_set(&Connections[cnum].connectpath,"");
4112 /****************************************************************************
4113 simple routines to do connection counting
4114 ****************************************************************************/
4115 BOOL yield_connection(int cnum,char *name,int max_connections)
4117 struct connect_record crec;
4120 int mypid = getpid();
4123 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4125 if (max_connections <= 0)
4128 bzero(&crec,sizeof(crec));
4130 pstrcpy(fname,lp_lockdir());
4131 standard_sub(cnum,fname);
4132 trim_string(fname,"","/");
4136 strcat(fname,".LCK");
4138 f = fopen(fname,"r+");
4141 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4145 fseek(f,0,SEEK_SET);
4147 /* find a free spot */
4148 for (i=0;i<max_connections;i++)
4150 if (fread(&crec,sizeof(crec),1,f) != 1)
4152 DEBUG(2,("Entry not found in lock file %s\n",fname));
4156 if (crec.pid == mypid && crec.cnum == cnum)
4160 if (crec.pid != mypid || crec.cnum != cnum)
4163 DEBUG(2,("Entry not found in lock file %s\n",fname));
4167 bzero((void *)&crec,sizeof(crec));
4169 /* remove our mark */
4170 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4171 fwrite(&crec,sizeof(crec),1,f) != 1)
4173 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4178 DEBUG(3,("Yield successful\n"));
4185 /****************************************************************************
4186 simple routines to do connection counting
4187 ****************************************************************************/
4188 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4190 struct connect_record crec;
4193 int snum = SNUM(cnum);
4197 if (max_connections <= 0)
4200 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4202 pstrcpy(fname,lp_lockdir());
4203 standard_sub(cnum,fname);
4204 trim_string(fname,"","/");
4206 if (!directory_exist(fname,NULL))
4211 strcat(fname,".LCK");
4213 if (!file_exist(fname,NULL))
4215 int oldmask = umask(022);
4216 f = fopen(fname,"w");
4221 total_recs = file_size(fname) / sizeof(crec);
4223 f = fopen(fname,"r+");
4227 DEBUG(1,("couldn't open lock file %s\n",fname));
4231 /* find a free spot */
4232 for (i=0;i<max_connections;i++)
4235 if (i>=total_recs ||
4236 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4237 fread(&crec,sizeof(crec),1,f) != 1)
4239 if (foundi < 0) foundi = i;
4243 if (Clear && crec.pid && !process_exists(crec.pid))
4245 fseek(f,i*sizeof(crec),SEEK_SET);
4246 bzero((void *)&crec,sizeof(crec));
4247 fwrite(&crec,sizeof(crec),1,f);
4248 if (foundi < 0) foundi = i;
4251 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4260 DEBUG(3,("no free locks in %s\n",fname));
4265 /* fill in the crec */
4266 bzero((void *)&crec,sizeof(crec));
4267 crec.magic = 0x280267;
4268 crec.pid = getpid();
4270 crec.uid = Connections[cnum].uid;
4271 crec.gid = Connections[cnum].gid;
4272 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4273 crec.start = time(NULL);
4275 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4276 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4279 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4280 fwrite(&crec,sizeof(crec),1,f) != 1)
4291 /*******************************************************************
4292 prepare to dump a core file - carefully!
4293 ********************************************************************/
4294 static BOOL dump_core(void)
4298 pstrcpy(dname,debugf);
4299 if ((p=strrchr(dname,'/'))) *p=0;
4300 strcat(dname,"/corefiles");
4302 sys_chown(dname,getuid(),getgid());
4304 if (chdir(dname)) return(False);
4307 #ifndef NO_GETRLIMIT
4311 getrlimit(RLIMIT_CORE, &rlp);
4312 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4313 setrlimit(RLIMIT_CORE, &rlp);
4314 getrlimit(RLIMIT_CORE, &rlp);
4315 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4321 DEBUG(0,("Dumping core in %s\n",dname));
4326 /****************************************************************************
4328 ****************************************************************************/
4329 void exit_server(char *reason)
4331 static int firsttime=1;
4334 if (!firsttime) exit(0);
4338 DEBUG(2,("Closing connections\n"));
4339 for (i=0;i<MAX_CONNECTIONS;i++)
4340 if (Connections[i].open)
4341 close_cnum(i,(uint16)-1);
4343 if (dcelogin_atmost_once)
4347 int oldlevel = DEBUGLEVEL;
4349 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4351 show_msg(last_inbuf);
4352 DEBUGLEVEL = oldlevel;
4353 DEBUG(0,("===============================================================\n"));
4355 if (dump_core()) return;
4361 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4365 /****************************************************************************
4366 do some standard substitutions in a string
4367 ****************************************************************************/
4368 void standard_sub(int cnum,char *str)
4370 if (VALID_CNUM(cnum)) {
4373 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4375 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4376 string_sub(p,"%H",home);
4380 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4381 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4382 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4383 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4384 case '\0' : p++; break; /* don't run off the end of the string */
4385 default : p+=2; break;
4389 standard_sub_basic(str);
4393 These flags determine some of the permissions required to do an operation
4395 Note that I don't set NEED_WRITE on some write operations because they
4396 are used by some brain-dead clients when printing, and I don't want to
4397 force write permissions on print services.
4399 #define AS_USER (1<<0)
4400 #define NEED_WRITE (1<<1)
4401 #define TIME_INIT (1<<2)
4402 #define CAN_IPC (1<<3)
4403 #define AS_GUEST (1<<5)
4407 define a list of possible SMB messages and their corresponding
4408 functions. Any message that has a NULL function is unimplemented -
4409 please feel free to contribute implementations!
4411 struct smb_message_struct
4425 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4426 {SMBtcon,"SMBtcon",reply_tcon,0},
4427 {SMBtdis,"SMBtdis",reply_tdis,0},
4428 {SMBexit,"SMBexit",reply_exit,0},
4429 {SMBioctl,"SMBioctl",reply_ioctl,0},
4430 {SMBecho,"SMBecho",reply_echo,0},
4431 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4432 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4433 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4434 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4435 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4436 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4437 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4438 {SMBopen,"SMBopen",reply_open,AS_USER},
4440 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4441 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4442 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4444 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4445 {SMBread,"SMBread",reply_read,AS_USER},
4446 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4447 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4448 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4449 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4450 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4451 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4453 /* this is a Pathworks specific call, allowing the
4454 changing of the root path */
4455 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4457 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4458 {SMBflush,"SMBflush",reply_flush,AS_USER},
4459 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4460 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4461 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4462 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4463 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4464 {SMBlock,"SMBlock",reply_lock,AS_USER},
4465 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4467 /* CORE+ PROTOCOL FOLLOWS */
4469 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4470 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4471 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4472 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4473 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4475 /* LANMAN1.0 PROTOCOL FOLLOWS */
4477 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4478 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4479 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4480 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4481 {SMBwritec,"SMBwritec",NULL,AS_USER},
4482 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4483 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4484 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4485 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4486 {SMBioctls,"SMBioctls",NULL,AS_USER},
4487 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4488 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4490 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4491 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4492 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4493 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4495 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4496 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4497 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4499 /* LANMAN2.0 PROTOCOL FOLLOWS */
4500 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4501 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4502 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4503 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4505 /* messaging routines */
4506 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4507 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4508 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4509 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4511 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4513 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4514 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4515 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4516 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4519 /****************************************************************************
4520 return a string containing the function name of a SMB command
4521 ****************************************************************************/
4522 char *smb_fn_name(int type)
4524 static char *unknown_name = "SMBunknown";
4525 static int num_smb_messages =
4526 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4529 for (match=0;match<num_smb_messages;match++)
4530 if (smb_messages[match].code == type)
4533 if (match == num_smb_messages)
4534 return(unknown_name);
4536 return(smb_messages[match].name);
4540 /****************************************************************************
4541 do a switch on the message type, and return the response size
4542 ****************************************************************************/
4543 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4547 static int num_smb_messages =
4548 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4552 struct timeval msg_start_time;
4553 struct timeval msg_end_time;
4554 static unsigned long total_time = 0;
4556 GetTimeOfDay(&msg_start_time);
4563 last_message = type;
4565 /* make sure this is an SMB packet */
4566 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4568 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4572 for (match=0;match<num_smb_messages;match++)
4573 if (smb_messages[match].code == type)
4576 if (match == num_smb_messages)
4578 DEBUG(0,("Unknown message type %d!\n",type));
4579 outsize = reply_unknown(inbuf,outbuf);
4583 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4584 if (smb_messages[match].fn)
4586 int cnum = SVAL(inbuf,smb_tid);
4587 int flags = smb_messages[match].flags;
4588 uint16 session_tag = SVAL(inbuf,smb_uid);
4590 /* does this protocol need to be run as root? */
4591 if (!(flags & AS_USER))
4594 /* does this protocol need to be run as the connected user? */
4595 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4596 if (flags & AS_GUEST)
4599 return(ERROR(ERRSRV,ERRinvnid));
4601 /* this code is to work around a bug is MS client 3 without
4602 introducing a security hole - it needs to be able to do
4603 print queue checks as guest if it isn't logged in properly */
4604 if (flags & AS_USER)
4607 /* does it need write permission? */
4608 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4609 return(ERROR(ERRSRV,ERRaccess));
4611 /* ipc services are limited */
4612 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4613 return(ERROR(ERRSRV,ERRaccess));
4615 /* load service specific parameters */
4616 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4617 return(ERROR(ERRSRV,ERRaccess));
4619 /* does this protocol need to be run as guest? */
4620 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4621 return(ERROR(ERRSRV,ERRaccess));
4625 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4629 outsize = reply_unknown(inbuf,outbuf);
4634 GetTimeOfDay(&msg_end_time);
4635 if (!(smb_messages[match].flags & TIME_INIT))
4637 smb_messages[match].time = 0;
4638 smb_messages[match].flags |= TIME_INIT;
4641 unsigned long this_time =
4642 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4643 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4644 smb_messages[match].time += this_time;
4645 total_time += this_time;
4647 DEBUG(2,("TIME %s %d usecs %g pct\n",
4648 smb_fn_name(type),smb_messages[match].time,
4649 (100.0*smb_messages[match].time) / total_time));
4656 /****************************************************************************
4657 construct a chained reply and add it to the already made reply
4658 **************************************************************************/
4659 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4661 static char *orig_inbuf;
4662 static char *orig_outbuf;
4663 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4664 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4665 char *inbuf2, *outbuf2;
4667 char inbuf_saved[smb_wct];
4668 char outbuf_saved[smb_wct];
4669 extern int chain_size;
4670 int wct = CVAL(outbuf,smb_wct);
4671 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4673 /* maybe its not chained */
4674 if (smb_com2 == 0xFF) {
4675 CVAL(outbuf,smb_vwv0) = 0xFF;
4679 if (chain_size == 0) {
4680 /* this is the first part of the chain */
4682 orig_outbuf = outbuf;
4685 /* we need to tell the client where the next part of the reply will be */
4686 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4687 CVAL(outbuf,smb_vwv0) = smb_com2;
4689 /* remember how much the caller added to the chain, only counting stuff
4690 after the parameter words */
4691 chain_size += outsize - smb_wct;
4693 /* work out pointers into the original packets. The
4694 headers on these need to be filled in */
4695 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4696 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4698 /* remember the original command type */
4699 smb_com1 = CVAL(orig_inbuf,smb_com);
4701 /* save the data which will be overwritten by the new headers */
4702 memcpy(inbuf_saved,inbuf2,smb_wct);
4703 memcpy(outbuf_saved,outbuf2,smb_wct);
4705 /* give the new packet the same header as the last part of the SMB */
4706 memmove(inbuf2,inbuf,smb_wct);
4708 /* create the in buffer */
4709 CVAL(inbuf2,smb_com) = smb_com2;
4711 /* create the out buffer */
4712 bzero(outbuf2,smb_size);
4713 set_message(outbuf2,0,0,True);
4714 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4716 memcpy(outbuf2+4,inbuf2+4,4);
4717 CVAL(outbuf2,smb_rcls) = SUCCESS;
4718 CVAL(outbuf2,smb_reh) = 0;
4719 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4721 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4722 SSVAL(outbuf2,smb_err,SUCCESS);
4723 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4724 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4725 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4726 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4728 DEBUG(3,("Chained message\n"));
4731 /* process the request */
4732 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4733 bufsize-chain_size);
4735 /* copy the new reply and request headers over the old ones, but
4736 preserve the smb_com field */
4737 memmove(orig_outbuf,outbuf2,smb_wct);
4738 CVAL(orig_outbuf,smb_com) = smb_com1;
4740 /* restore the saved data, being careful not to overwrite any
4741 data from the reply header */
4742 memcpy(inbuf2,inbuf_saved,smb_wct);
4744 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4745 if (ofs < 0) ofs = 0;
4746 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4754 /****************************************************************************
4755 construct a reply to the incoming packet
4756 ****************************************************************************/
4757 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4759 int type = CVAL(inbuf,smb_com);
4761 int msg_type = CVAL(inbuf,0);
4762 extern int chain_size;
4764 smb_last_time = time(NULL);
4770 bzero(outbuf,smb_size);
4773 return(reply_special(inbuf,outbuf));
4775 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4776 set_message(outbuf,0,0,True);
4778 memcpy(outbuf+4,inbuf+4,4);
4779 CVAL(outbuf,smb_rcls) = SUCCESS;
4780 CVAL(outbuf,smb_reh) = 0;
4781 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4783 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4784 SSVAL(outbuf,smb_err,SUCCESS);
4785 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4786 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4787 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4788 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4790 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4792 outsize += chain_size;
4795 smb_setlen(outbuf,outsize - 4);
4799 /****************************************************************************
4800 process commands from the client
4801 ****************************************************************************/
4802 static void process(void)
4806 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4807 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4808 if ((InBuffer == NULL) || (OutBuffer == NULL))
4811 InBuffer += SMB_ALIGNMENT;
4812 OutBuffer += SMB_ALIGNMENT;
4815 DEBUG(3,("priming nmbd\n"));
4818 ip = *interpret_addr2("localhost");
4819 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4821 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4825 /* re-initialise the timezone */
4830 int deadtime = lp_deadtime()*60;
4832 int last_keepalive=0;
4833 int service_load_counter = 0;
4834 BOOL got_smb = False;
4837 deadtime = DEFAULT_SMBD_TIMEOUT;
4839 #if USE_READ_PREDICTION
4840 if (lp_readprediction())
4841 do_read_prediction();
4846 for (counter=SMBD_SELECT_LOOP;
4847 !receive_message_or_smb(Client,oplock_sock,
4848 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4849 counter += SMBD_SELECT_LOOP)
4853 BOOL allidle = True;
4854 extern int keepalive;
4856 if (counter > 365 * 3600) /* big number of seconds. */
4859 service_load_counter = 0;
4862 if (smb_read_error == READ_EOF)
4864 DEBUG(3,("end of file from client\n"));
4868 if (smb_read_error == READ_ERROR)
4870 DEBUG(3,("receive_smb error (%s) exiting\n",
4877 /* become root again if waiting */
4880 /* check for smb.conf reload */
4881 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4883 service_load_counter = counter;
4885 /* reload services, if files have changed. */
4886 reload_services(True);
4889 /* automatic timeout if all connections are closed */
4890 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4892 DEBUG(2,("%s Closing idle connection\n",timestring()));
4896 if (keepalive && (counter-last_keepalive)>keepalive)
4898 struct cli_state *cli = server_client();
4899 if (!send_keepalive(Client)) {
4900 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4903 /* also send a keepalive to the password server if its still
4905 if (cli && cli->initialised)
4906 send_keepalive(cli->fd);
4907 last_keepalive = counter;
4910 /* check for connection timeouts */
4911 for (i=0;i<MAX_CONNECTIONS;i++)
4912 if (Connections[i].open)
4914 /* close dirptrs on connections that are idle */
4915 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4918 if (Connections[i].num_files_open > 0 ||
4919 (t-Connections[i].lastused)<deadtime)
4923 if (allidle && num_connections_open>0)
4925 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4931 process_smb(InBuffer, OutBuffer);
4933 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4938 /****************************************************************************
4939 initialise connect, service and file structs
4940 ****************************************************************************/
4941 static void init_structs(void )
4944 get_myname(myhostname,NULL);
4946 for (i=0;i<MAX_CONNECTIONS;i++)
4948 Connections[i].open = False;
4949 Connections[i].num_files_open=0;
4950 Connections[i].lastused=0;
4951 Connections[i].used=False;
4952 string_init(&Connections[i].user,"");
4953 string_init(&Connections[i].dirpath,"");
4954 string_init(&Connections[i].connectpath,"");
4955 string_init(&Connections[i].origpath,"");
4958 for (i=0;i<MAX_OPEN_FILES;i++)
4960 Files[i].open = False;
4961 string_init(&Files[i].name,"");
4965 for (i=0;i<MAX_OPEN_FILES;i++)
4967 file_fd_struct *fd_ptr = &FileFd[i];
4968 fd_ptr->ref_count = 0;
4969 fd_ptr->dev = (int32)-1;
4970 fd_ptr->inode = (int32)-1;
4972 fd_ptr->fd_readonly = -1;
4973 fd_ptr->fd_writeonly = -1;
4974 fd_ptr->real_open_flags = -1;
4978 init_rpc_pipe_hnd();
4981 /* for LSA handles */
4982 init_lsa_policy_hnd();
4988 /****************************************************************************
4989 usage on the program
4990 ****************************************************************************/
4991 static void usage(char *pname)
4993 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4995 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4996 printf("Version %s\n",VERSION);
4997 printf("\t-D become a daemon\n");
4998 printf("\t-p port listen on the specified port\n");
4999 printf("\t-d debuglevel set the debuglevel\n");
5000 printf("\t-l log basename. Basename for log/debug files\n");
5001 printf("\t-s services file. Filename of services file\n");
5002 printf("\t-P passive only\n");
5003 printf("\t-a overwrite log file, don't append\n");
5008 /****************************************************************************
5010 ****************************************************************************/
5011 int main(int argc,char *argv[])
5013 extern BOOL append_log;
5014 /* shall I run as a daemon */
5015 BOOL is_daemon = False;
5016 int port = SMB_PORT;
5018 extern char *optarg;
5019 char pidFile[100] = { 0 };
5021 #ifdef NEED_AUTH_PARAMETERS
5022 set_auth_parameters(argc,argv);
5033 strcpy(debugf,SMBLOGFILE);
5035 setup_logging(argv[0],False);
5037 charset_initialise();
5039 /* make absolutely sure we run as root - to handle cases whre people
5040 are crazy enough to have it setuid */
5050 fault_setup(exit_server);
5051 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5053 /* we want total control over the permissions on created files,
5054 so set our umask to 0 */
5061 /* this is for people who can't start the program correctly */
5062 while (argc > 1 && (*argv[1] != '-'))
5068 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5072 strncpy(pidFile, optarg, sizeof(pidFile));
5075 strcpy(user_socket_options,optarg);
5078 strcpy(scope,optarg);
5082 extern BOOL passive;
5087 strcpy(servicesf,optarg);
5090 strcpy(debugf,optarg);
5094 extern BOOL append_log;
5095 append_log = !append_log;
5105 DEBUGLEVEL = atoi(optarg);
5108 port = atoi(optarg);
5121 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5122 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5124 #ifndef NO_GETRLIMIT
5125 #ifdef RLIMIT_NOFILE
5128 getrlimit(RLIMIT_NOFILE, &rlp);
5129 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5130 setrlimit(RLIMIT_NOFILE, &rlp);
5131 getrlimit(RLIMIT_NOFILE, &rlp);
5132 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5138 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5139 getuid(),getgid(),geteuid(),getegid()));
5141 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5143 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5149 if (!reload_services(False))
5152 codepage_initialise(lp_client_code_page());
5154 strcpy(myworkgroup, lp_workgroup());
5156 #ifndef NO_SIGNAL_TEST
5157 signal(SIGHUP,SIGNAL_CAST sig_hup);
5160 DEBUG(3,("%s loaded services\n",timestring()));
5162 if (!is_daemon && !is_a_socket(0))
5164 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5170 DEBUG(3,("%s becoming a daemon\n",timestring()));
5174 if (!directory_exist(lp_lockdir(), NULL)) {
5175 mkdir(lp_lockdir(), 0755);
5183 if ((fd = open(pidFile,
5187 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5189 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5192 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5194 DEBUG(0,("ERROR: smbd is already running\n"));
5197 sprintf(buf, "%u\n", (unsigned int) getpid());
5198 if (write(fd, buf, strlen(buf)) < 0)
5200 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5203 /* Leave pid file open & locked for the duration... */
5206 if (!open_sockets(is_daemon,port))
5209 if (!locking_init(0))
5212 /* possibly reload the services file. */
5213 reload_services(True);
5215 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5219 if (sys_chroot(lp_rootdir()) == 0)
5220 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5223 /* Setup the oplock IPC socket. */
5224 if(!open_oplock_ipc())
5230 exit_server("normal exit");