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 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1477 timestring(),Connections[cnum].user,fs_p->name,
1478 Connections[cnum].num_files_open));
1481 enum {AFAIL,AREAD,AWRITE,AALL};
1483 /*******************************************************************
1484 reproduce the share mode access table
1485 ********************************************************************/
1486 static int access_table(int new_deny,int old_deny,int old_mode,
1487 int share_pid,char *fname)
1489 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1491 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1493 if (old_deny == new_deny && share_pid == pid)
1496 if (old_mode == 0) return(AREAD);
1498 /* the new smbpub.zip spec says that if the file extension is
1499 .com, .dll, .exe or .sym then allow the open. I will force
1500 it to read-only as this seems sensible although the spec is
1501 a little unclear on this. */
1502 if ((fname = strrchr(fname,'.'))) {
1503 if (strequal(fname,".com") ||
1504 strequal(fname,".dll") ||
1505 strequal(fname,".exe") ||
1506 strequal(fname,".sym"))
1516 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1517 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1518 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1521 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1522 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1523 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1526 if (old_deny==DENY_WRITE) return(AREAD);
1527 if (old_deny==DENY_READ) return(AWRITE);
1528 if (old_deny==DENY_NONE) return(AALL);
1534 /*******************************************************************
1535 check if the share mode on a file allows it to be deleted or unlinked
1536 return True if sharing doesn't prevent the operation
1537 ********************************************************************/
1538 BOOL check_file_sharing(int cnum,char *fname)
1542 share_mode_entry *old_shares = 0;
1543 int num_share_modes;
1549 if(!lp_share_modes(SNUM(cnum)))
1552 if (stat(fname,&sbuf) == -1) return(True);
1554 dev = (uint32)sbuf.st_dev;
1555 inode = (uint32)sbuf.st_ino;
1557 lock_share_entry(cnum, dev, inode, &token);
1558 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1561 * Check if the share modes will give us access.
1564 if(num_share_modes != 0)
1571 broke_oplock = False;
1572 for(i = 0; i < num_share_modes; i++)
1574 share_mode_entry *share_entry = &old_shares[i];
1577 * Break oplocks before checking share modes. See comment in
1578 * open_file_shared for details.
1579 * Check if someone has an oplock on this file. If so we must
1580 * break it before continuing.
1582 if(share_entry->op_type & BATCH_OPLOCK)
1585 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1586 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1588 /* Oplock break.... */
1589 unlock_share_entry(cnum, dev, inode, token);
1590 if(request_oplock_break(share_entry, dev, inode) == False)
1592 free((char *)old_shares);
1593 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1594 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1597 lock_share_entry(cnum, dev, inode, &token);
1598 broke_oplock = True;
1602 /* someone else has a share lock on it, check to see
1604 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1611 free((char *)old_shares);
1612 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1614 } while(broke_oplock);
1617 /* XXXX exactly what share mode combinations should be allowed for
1618 deleting/renaming? */
1619 /* If we got here then either there were no share modes or
1620 all share modes were DENY_DOS and the pid == getpid() */
1625 unlock_share_entry(cnum, dev, inode, token);
1626 if(old_shares != NULL)
1627 free((char *)old_shares);
1631 /****************************************************************************
1633 Helper for open_file_shared.
1634 Truncate a file after checking locking; close file if locked.
1635 **************************************************************************/
1636 static void truncate_unless_locked(int fnum, int cnum, int token,
1639 if (Files[fnum].can_write){
1640 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1641 /* If share modes are in force for this connection we
1642 have the share entry locked. Unlock it before closing. */
1643 if (*share_locked && lp_share_modes(SNUM(cnum)))
1644 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1645 Files[fnum].fd_ptr->inode, token);
1646 close_file(fnum,False);
1647 /* Share mode no longer locked. */
1648 *share_locked = False;
1650 unix_ERR_class = ERRDOS;
1651 unix_ERR_code = ERRlock;
1654 ftruncate(Files[fnum].fd_ptr->fd,0);
1658 /****************************************************************************
1659 check if we can open a file with a share mode
1660 ****************************************************************************/
1661 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1662 BOOL fcbopen, int *flags)
1664 int old_open_mode = share->share_mode &0xF;
1665 int old_deny_mode = (share->share_mode >>4)&7;
1667 if (old_deny_mode > 4 || old_open_mode > 2)
1669 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1670 deny_mode,old_deny_mode,old_open_mode,fname));
1675 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1678 if ((access_allowed == AFAIL) ||
1679 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1680 (access_allowed == AREAD && *flags == O_WRONLY) ||
1681 (access_allowed == AWRITE && *flags == O_RDONLY))
1683 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1684 deny_mode,old_deny_mode,old_open_mode,
1685 share->pid,fname, access_allowed));
1689 if (access_allowed == AREAD)
1692 if (access_allowed == AWRITE)
1699 /****************************************************************************
1700 open a file with a share mode
1701 ****************************************************************************/
1702 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1703 int mode,int oplock_request, int *Access,int *action)
1705 files_struct *fs_p = &Files[fnum];
1708 int deny_mode = (share_mode>>4)&7;
1710 BOOL file_existed = file_exist(fname,&sbuf);
1711 BOOL share_locked = False;
1712 BOOL fcbopen = False;
1716 int num_share_modes = 0;
1721 /* this is for OS/2 EAs - try and say we don't support them */
1722 if (strstr(fname,".+,;=[]."))
1724 unix_ERR_class = ERRDOS;
1725 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1727 unix_ERR_code = ERRcannotopen;
1728 #else /* OS2_WPS_FIX */
1729 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1730 #endif /* OS2_WPS_FIX */
1735 if ((ofun & 0x3) == 0 && file_existed)
1743 if ((ofun & 0x3) == 2)
1746 /* note that we ignore the append flag as
1747 append does not mean the same thing under dos and unix */
1749 switch (share_mode&0xF)
1766 if (flags != O_RDONLY && file_existed &&
1767 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1777 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1779 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1784 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1786 if (lp_share_modes(SNUM(cnum)))
1789 share_mode_entry *old_shares = 0;
1793 dev = (uint32)sbuf.st_dev;
1794 inode = (uint32)sbuf.st_ino;
1795 lock_share_entry(cnum, dev, inode, &token);
1796 share_locked = True;
1797 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1801 * Check if the share modes will give us access.
1804 if(share_locked && (num_share_modes != 0))
1811 broke_oplock = False;
1812 for(i = 0; i < num_share_modes; i++)
1814 share_mode_entry *share_entry = &old_shares[i];
1817 * By observation of NetBench, oplocks are broken *before* share
1818 * modes are checked. This allows a file to be closed by the client
1819 * if the share mode would deny access and the client has an oplock.
1820 * Check if someone has an oplock on this file. If so we must break
1821 * it before continuing.
1823 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1826 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1827 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1829 /* Oplock break.... */
1830 unlock_share_entry(cnum, dev, inode, token);
1831 if(request_oplock_break(share_entry, dev, inode) == False)
1833 free((char *)old_shares);
1834 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1835 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1837 unix_ERR_class = ERRDOS;
1838 unix_ERR_code = ERRbadshare;
1841 lock_share_entry(cnum, dev, inode, &token);
1842 broke_oplock = True;
1846 /* someone else has a share lock on it, check to see
1848 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1850 free((char *)old_shares);
1851 unlock_share_entry(cnum, dev, inode, token);
1853 unix_ERR_class = ERRDOS;
1854 unix_ERR_code = ERRbadshare;
1862 free((char *)old_shares);
1863 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1865 } while(broke_oplock);
1869 free((char *)old_shares);
1872 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1873 flags,flags2,mode));
1875 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1876 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1879 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1886 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1888 /* We created the file - thus we must now lock the share entry before creating it. */
1889 dev = fs_p->fd_ptr->dev;
1890 inode = fs_p->fd_ptr->inode;
1891 lock_share_entry(cnum, dev, inode, &token);
1892 share_locked = True;
1908 fs_p->share_mode = (deny_mode<<4) | open_mode;
1911 (*Access) = open_mode;
1915 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1916 if (!file_existed) *action = 2;
1917 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1919 /* We must create the share mode entry before truncate as
1920 truncate can fail due to locking and have to close the
1921 file (which expects the share_mode_entry to be there).
1923 if (lp_share_modes(SNUM(cnum)))
1926 /* JRA. Currently this only services Exlcusive and batch
1927 oplocks (no other opens on this file). This needs to
1928 be extended to level II oplocks (multiple reader
1931 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
1933 fs_p->granted_oplock = True;
1934 global_oplocks_open++;
1937 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1938 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1946 set_share_mode(token, fnum, port, oplock_request);
1949 if ((flags2&O_TRUNC) && file_existed)
1950 truncate_unless_locked(fnum,cnum,token,&share_locked);
1953 if (share_locked && lp_share_modes(SNUM(cnum)))
1954 unlock_share_entry( cnum, dev, inode, token);
1957 /****************************************************************************
1958 seek a file. Try to avoid the seek if possible
1959 ****************************************************************************/
1960 int seek_file(int fnum,uint32 pos)
1963 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1966 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1968 return(Files[fnum].pos);
1971 /****************************************************************************
1973 ****************************************************************************/
1974 int read_file(int fnum,char *data,uint32 pos,int n)
1978 #if USE_READ_PREDICTION
1979 if (!Files[fnum].can_write)
1981 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1990 if (Files[fnum].mmap_ptr)
1992 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1995 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2007 if (seek_file(fnum,pos) != pos)
2009 DEBUG(3,("Failed to seek to %d\n",pos));
2014 readret = read(Files[fnum].fd_ptr->fd,data,n);
2015 if (readret > 0) ret += readret;
2022 /****************************************************************************
2024 ****************************************************************************/
2025 int write_file(int fnum,char *data,int n)
2027 if (!Files[fnum].can_write) {
2032 if (!Files[fnum].modified) {
2034 Files[fnum].modified = True;
2035 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2036 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2037 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2038 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2043 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2047 /****************************************************************************
2048 load parameters specific to a connection/service
2049 ****************************************************************************/
2050 BOOL become_service(int cnum,BOOL do_chdir)
2052 extern char magic_char;
2053 static int last_cnum = -1;
2056 if (!OPEN_CNUM(cnum))
2062 Connections[cnum].lastused = smb_last_time;
2067 ChDir(Connections[cnum].connectpath) != 0 &&
2068 ChDir(Connections[cnum].origpath) != 0)
2070 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2071 Connections[cnum].connectpath,cnum));
2075 if (cnum == last_cnum)
2080 case_default = lp_defaultcase(snum);
2081 case_preserve = lp_preservecase(snum);
2082 short_case_preserve = lp_shortpreservecase(snum);
2083 case_mangle = lp_casemangle(snum);
2084 case_sensitive = lp_casesensitive(snum);
2085 magic_char = lp_magicchar(snum);
2086 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2091 /****************************************************************************
2092 find a service entry
2093 ****************************************************************************/
2094 int find_service(char *service)
2098 string_sub(service,"\\","/");
2100 iService = lp_servicenumber(service);
2102 /* now handle the special case of a home directory */
2105 char *phome_dir = get_home_dir(service);
2106 DEBUG(3,("checking for home directory %s gave %s\n",service,
2107 phome_dir?phome_dir:"(NULL)"));
2111 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2113 lp_add_home(service,iHomeService,phome_dir);
2114 iService = lp_servicenumber(service);
2119 /* If we still don't have a service, attempt to add it as a printer. */
2122 int iPrinterService;
2124 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2128 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2130 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2132 DEBUG(3,("%s is a valid printer name\n", service));
2133 DEBUG(3,("adding %s as a printer service\n", service));
2134 lp_add_printer(service,iPrinterService);
2135 iService = lp_servicenumber(service);
2137 DEBUG(0,("failed to add %s as a printer service!\n", service));
2140 DEBUG(3,("%s is not a valid printer name\n", service));
2144 /* just possibly it's a default service? */
2147 char *defservice = lp_defaultservice();
2148 if (defservice && *defservice && !strequal(defservice,service)) {
2149 iService = find_service(defservice);
2150 if (iService >= 0) {
2151 string_sub(service,"_","/");
2152 iService = lp_add_service(service,iService);
2158 if (!VALID_SNUM(iService))
2160 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2165 DEBUG(3,("find_service() failed to find service %s\n", service));
2171 /****************************************************************************
2172 create an error packet from a cached error.
2173 ****************************************************************************/
2174 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2176 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2178 int32 eclass = wbmpx->wr_errclass;
2179 int32 err = wbmpx->wr_error;
2181 /* We can now delete the auxiliary struct */
2182 free((char *)wbmpx);
2183 Files[fnum].wbmpx_ptr = NULL;
2184 return error_packet(inbuf,outbuf,eclass,err,line);
2193 } unix_smb_errmap[] =
2195 {EPERM,ERRDOS,ERRnoaccess},
2196 {EACCES,ERRDOS,ERRnoaccess},
2197 {ENOENT,ERRDOS,ERRbadfile},
2198 {ENOTDIR,ERRDOS,ERRbadpath},
2199 {EIO,ERRHRD,ERRgeneral},
2200 {EBADF,ERRSRV,ERRsrverror},
2201 {EINVAL,ERRSRV,ERRsrverror},
2202 {EEXIST,ERRDOS,ERRfilexists},
2203 {ENFILE,ERRDOS,ERRnofids},
2204 {EMFILE,ERRDOS,ERRnofids},
2205 {ENOSPC,ERRHRD,ERRdiskfull},
2207 {EDQUOT,ERRHRD,ERRdiskfull},
2210 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2213 {EXDEV,ERRDOS,ERRdiffdevice},
2215 {EROFS,ERRHRD,ERRnowrite},
2219 /****************************************************************************
2220 create an error packet from errno
2221 ****************************************************************************/
2222 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2224 int eclass=def_class;
2228 if (unix_ERR_class != SUCCESS)
2230 eclass = unix_ERR_class;
2231 ecode = unix_ERR_code;
2232 unix_ERR_class = SUCCESS;
2237 while (unix_smb_errmap[i].smbclass != 0)
2239 if (unix_smb_errmap[i].unixerror == errno)
2241 eclass = unix_smb_errmap[i].smbclass;
2242 ecode = unix_smb_errmap[i].smbcode;
2249 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2253 /****************************************************************************
2254 create an error packet. Normally called using the ERROR() macro
2255 ****************************************************************************/
2256 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2258 int outsize = set_message(outbuf,0,0,True);
2260 cmd = CVAL(inbuf,smb_com);
2262 CVAL(outbuf,smb_rcls) = error_class;
2263 SSVAL(outbuf,smb_err,error_code);
2265 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2268 (int)CVAL(inbuf,smb_com),
2269 smb_fn_name(CVAL(inbuf,smb_com)),
2274 DEBUG(3,("error string = %s\n",strerror(errno)));
2280 #ifndef SIGCLD_IGNORE
2281 /****************************************************************************
2282 this prevents zombie child processes
2283 ****************************************************************************/
2284 static int sig_cld()
2286 static int depth = 0;
2289 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2295 BlockSignals(True,SIGCLD);
2296 DEBUG(5,("got SIGCLD\n"));
2299 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2303 /* Stevens, Adv. Unix Prog. says that on system V you must call
2304 wait before reinstalling the signal handler, because the kernel
2305 calls the handler from within the signal-call when there is a
2306 child that has exited. This would lead to an infinite recursion
2307 if done vice versa. */
2309 #ifndef DONT_REINSTALL_SIG
2310 #ifdef SIGCLD_IGNORE
2311 signal(SIGCLD, SIG_IGN);
2313 signal(SIGCLD, SIGNAL_CAST sig_cld);
2318 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2321 BlockSignals(False,SIGCLD);
2326 /****************************************************************************
2327 this is called when the client exits abruptly
2328 **************************************************************************/
2329 static int sig_pipe()
2331 struct cli_state *cli;
2332 BlockSignals(True,SIGPIPE);
2334 if ((cli = server_client()) && cli->initialised) {
2335 DEBUG(3,("lost connection to password server\n"));
2337 #ifndef DONT_REINSTALL_SIG
2338 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2340 BlockSignals(False,SIGPIPE);
2344 exit_server("Got sigpipe\n");
2348 /****************************************************************************
2349 open the socket communication
2350 ****************************************************************************/
2351 static BOOL open_sockets(BOOL is_daemon,int port)
2357 int num_interfaces = iface_count();
2358 int fd_listenset[FD_SETSIZE];
2364 #ifdef SIGCLD_IGNORE
2365 signal(SIGCLD, SIG_IGN);
2367 signal(SIGCLD, SIGNAL_CAST sig_cld);
2373 FD_ZERO(&listen_set);
2375 if(lp_interfaces() && lp_bind_interfaces_only())
2377 /* We have been given an interfaces line, and been
2378 told to only bind to those interfaces. Create a
2379 socket per interface and bind to only these.
2382 if(num_interfaces > FD_SETSIZE)
2384 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2385 max can be %d\n", num_interfaces, FD_SETSIZE));
2389 /* Now open a listen socket for each of the interfaces. */
2390 for(i = 0; i < num_interfaces; i++)
2392 struct in_addr *ifip = iface_n_ip(i);
2396 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2399 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2402 /* ready to listen */
2403 if (listen(s, 5) == -1)
2405 DEBUG(0,("listen: %s\n",strerror(errno)));
2409 FD_SET(s,&listen_set);
2414 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2417 /* open an incoming socket */
2418 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2422 /* ready to listen */
2423 if (listen(s, 5) == -1)
2425 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2430 fd_listenset[0] = s;
2431 FD_SET(s,&listen_set);
2434 /* now accept incoming connections - forking a new process
2435 for each incoming connection */
2436 DEBUG(2,("waiting for a connection\n"));
2442 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2444 num = sys_select(&lfds,NULL);
2446 if (num == -1 && errno == EINTR)
2449 /* Find the sockets that are read-ready - accept on these. */
2450 for( ; num > 0; num--)
2452 struct sockaddr addr;
2453 int in_addrlen = sizeof(addr);
2456 for(i = 0; i < num_interfaces; i++)
2458 if(FD_ISSET(fd_listenset[i],&lfds))
2460 s = fd_listenset[i];
2461 /* Clear this so we don't look at it again. */
2462 FD_CLR(fd_listenset[i],&lfds);
2467 Client = accept(s,&addr,&in_addrlen);
2469 if (Client == -1 && errno == EINTR)
2474 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2478 #ifdef NO_FORK_DEBUG
2479 #ifndef NO_SIGNAL_TEST
2480 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2481 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2482 #endif /* NO_SIGNAL_TEST */
2484 #else /* NO_FORK_DEBUG */
2485 if (Client != -1 && fork()==0)
2487 /* Child code ... */
2489 #ifndef NO_SIGNAL_TEST
2490 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2491 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2492 #endif /* NO_SIGNAL_TEST */
2493 /* close the listening socket(s) */
2494 for(i = 0; i < num_interfaces; i++)
2495 close(fd_listenset[i]);
2497 /* close our standard file descriptors */
2501 set_socket_options(Client,"SO_KEEPALIVE");
2502 set_socket_options(Client,user_socket_options);
2504 /* Reset global variables in util.c so that
2505 client substitutions will be done correctly
2508 reset_globals_after_fork();
2511 close(Client); /* The parent doesn't need this socket */
2512 #endif /NO_FORK_DEBUG */
2515 } /* end if is_daemon */
2518 /* Started from inetd. fd 0 is the socket. */
2519 /* We will abort gracefully when the client or remote system
2521 #ifndef NO_SIGNAL_TEST
2522 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2526 /* close our standard file descriptors */
2529 set_socket_options(Client,"SO_KEEPALIVE");
2530 set_socket_options(Client,user_socket_options);
2536 /****************************************************************************
2537 process an smb from the client - split out from the process() code so
2538 it can be used by the oplock break code.
2539 ****************************************************************************/
2541 static void process_smb(char *inbuf, char *outbuf)
2544 static int trans_num;
2545 int msg_type = CVAL(inbuf,0);
2546 int32 len = smb_len(inbuf);
2547 int nread = len + 4;
2549 if (trans_num == 0) {
2550 /* on the first packet, check the global hosts allow/ hosts
2551 deny parameters before doing any parsing of the packet
2552 passed to us by the client. This prevents attacks on our
2553 parsing code from hosts not in the hosts allow list */
2554 if (!check_access(-1)) {
2555 /* send a negative session response "not listining on calling
2557 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2558 DEBUG(1,("%s Connection denied from %s\n",
2559 timestring(),client_addr()));
2560 send_smb(Client,(char *)buf);
2561 exit_server("connection denied");
2565 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2566 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2569 if(trans_num == 1 && VT_Check(inbuf))
2579 nread = construct_reply(inbuf,outbuf,nread,max_send);
2583 if (CVAL(outbuf,0) == 0)
2586 if (nread != smb_len(outbuf) + 4)
2588 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2589 nread, smb_len(outbuf)));
2592 send_smb(Client,outbuf);
2597 /****************************************************************************
2598 open the oplock IPC socket communication
2599 ****************************************************************************/
2600 static BOOL open_oplock_ipc()
2602 struct sockaddr_in sock_name;
2603 int len = sizeof(sock_name);
2605 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2607 /* Open a lookback UDP socket on a random port. */
2608 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2609 if (oplock_sock == -1)
2611 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2612 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2617 /* Find out the transient UDP port we have been allocated. */
2618 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2620 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2627 oplock_port = ntohs(sock_name.sin_port);
2629 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2630 getpid(), oplock_port));
2635 /****************************************************************************
2636 process an oplock break message.
2637 ****************************************************************************/
2638 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2644 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2645 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2647 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2649 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2650 msg_len, from_port));
2652 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2653 only valid request. */
2655 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2657 case OPLOCK_BREAK_CMD:
2658 /* Ensure that the msg length is correct. */
2659 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2661 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2662 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2666 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2667 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2668 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2669 struct timeval tval;
2670 struct sockaddr_in toaddr;
2672 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2673 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2675 DEBUG(5,("process_local_message: oplock break request from \
2676 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2679 * If we have no record of any currently open oplocks,
2680 * it's not an error, as a close command may have
2681 * just been issued on the file that was oplocked.
2682 * Just return success in this case.
2685 if(global_oplocks_open != 0)
2687 if(oplock_break(dev, inode, &tval) == False)
2689 DEBUG(0,("process_local_message: oplock break failed - \
2690 not returning udp message.\n"));
2696 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2697 oplocks. Returning success.\n"));
2700 /* Send the message back after OR'ing in the 'REPLY' bit. */
2701 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2703 bzero((char *)&toaddr,sizeof(toaddr));
2704 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2705 toaddr.sin_port = htons(from_port);
2706 toaddr.sin_family = AF_INET;
2708 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2709 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2711 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2712 remotepid, strerror(errno)));
2716 DEBUG(5,("process_local_message: oplock break reply sent to \
2717 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2718 from_port, dev, inode));
2723 * Keep this as a debug case - eventually we can remove it.
2726 DEBUG(0,("process_local_message: Received unsolicited break \
2727 reply - dumping info.\n"));
2729 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2731 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2732 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2737 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2738 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2739 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2741 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2742 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2748 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2749 (unsigned int)SVAL(msg_start,0)));
2755 /****************************************************************************
2756 Process an oplock break directly.
2757 ****************************************************************************/
2758 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2761 static char *inbuf = NULL;
2762 static char *outbuf = NULL;
2763 files_struct *fsp = NULL;
2766 BOOL shutdown_server = False;
2768 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2769 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2773 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2775 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2778 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2779 if(outbuf == NULL) {
2780 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2787 /* We need to search the file open table for the
2788 entry containing this dev and inode, and ensure
2789 we have an oplock on it. */
2790 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2795 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2796 (fsp->open_time.tv_sec == tval->tv_sec) &&
2797 (fsp->open_time.tv_usec == tval->tv_usec))
2804 /* The file could have been closed in the meantime - return success. */
2805 DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2806 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2810 /* Ensure we have an oplock on the file */
2812 /* There is a potential race condition in that an oplock could
2813 have been broken due to another udp request, and yet there are
2814 still oplock break messages being sent in the udp message
2815 queue for this file. So return true if we don't have an oplock,
2816 as we may have just freed it.
2819 if(!fsp->granted_oplock)
2821 DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2822 Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2826 /* Now comes the horrid part. We must send an oplock break to the client,
2827 and then process incoming messages until we get a close or oplock release.
2830 /* Prepare the SMBlockingX message. */
2831 bzero(outbuf,smb_size);
2832 set_message(outbuf,8,0,True);
2834 SCVAL(outbuf,smb_com,SMBlockingX);
2835 SSVAL(outbuf,smb_tid,fsp->cnum);
2836 SSVAL(outbuf,smb_pid,0xFFFF);
2837 SSVAL(outbuf,smb_uid,0);
2838 SSVAL(outbuf,smb_mid,0xFFFF);
2839 SCVAL(outbuf,smb_vwv0,0xFF);
2840 SSVAL(outbuf,smb_vwv2,fnum);
2841 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2842 /* Change this when we have level II oplocks. */
2843 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2845 send_smb(Client, outbuf);
2847 /* We need this in case a readraw crosses on the wire. */
2848 global_oplock_break = True;
2850 /* Process incoming messages. */
2852 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2853 seconds we should just die.... */
2855 start_time = time(NULL);
2857 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2859 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2862 * Die if we got an error.
2865 if (smb_read_error == READ_EOF)
2866 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2868 if (smb_read_error == READ_ERROR)
2869 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2870 timestring(), strerror(errno)));
2872 if (smb_read_error == READ_TIMEOUT)
2873 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2874 timestring(), OPLOCK_BREAK_TIMEOUT));
2876 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2877 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2878 shutdown_server = True;
2881 process_smb(inbuf, outbuf);
2884 * Die if we go over the time limit.
2887 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2889 DEBUG(0,("%s oplock_break: no break received from client within \
2890 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2891 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2892 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2893 shutdown_server = True;
2898 /* We need this in case a readraw crossed on the wire. */
2899 if(global_oplock_break)
2900 global_oplock_break = False;
2903 * If the client did not respond we must die.
2908 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2912 exit_server("oplock break failure");
2917 /* The lockingX reply will have removed the oplock flag
2918 from the sharemode. */
2920 fsp->granted_oplock = False;
2923 global_oplocks_open--;
2925 /* Santity check - remove this later. JRA */
2926 if(global_oplocks_open < 0)
2928 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2929 global_oplocks_open));
2930 exit_server("oplock_break: global_oplocks_open < 0");
2933 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2934 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2939 /****************************************************************************
2940 Send an oplock break message to another smbd process. If the oplock is held
2941 by the local smbd then call the oplock break function directly.
2942 ****************************************************************************/
2944 BOOL request_oplock_break(share_mode_entry *share_entry,
2945 uint32 dev, uint32 inode)
2947 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2948 struct sockaddr_in addr_out;
2951 if(pid == share_entry->pid)
2953 /* We are breaking our own oplock, make sure it's us. */
2954 if(share_entry->op_port != oplock_port)
2956 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2957 should be %d\n", pid, share_entry->op_port, oplock_port));
2961 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2963 /* Call oplock break direct. */
2964 return oplock_break(dev, inode, &share_entry->time);
2967 /* We need to send a OPLOCK_BREAK_CMD message to the
2968 port in the share mode entry. */
2970 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2971 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2972 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2973 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2974 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2975 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2977 /* set the address and port */
2978 bzero((char *)&addr_out,sizeof(addr_out));
2979 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2980 addr_out.sin_port = htons( share_entry->op_port );
2981 addr_out.sin_family = AF_INET;
2983 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2984 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
2986 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2987 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2989 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2990 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2991 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
2997 * Now we must await the oplock broken message coming back
2998 * from the target smbd process. Timeout if it fails to
2999 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3000 * While we get messages that aren't ours, loop.
3005 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3006 int32 reply_msg_len;
3007 uint16 reply_from_port;
3008 char *reply_msg_start;
3010 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3011 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3013 if(smb_read_error == READ_TIMEOUT)
3015 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3016 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3017 share_entry->op_port, dev, inode));
3019 * This is a hack to make handling of failing clients more robust.
3020 * If a oplock break response message is not received in the timeout
3021 * period we may assume that the smbd servicing that client holding
3022 * the oplock has died and the client changes were lost anyway, so
3023 * we should continue to try and open the file.
3028 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3029 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3030 share_entry->op_port, dev, inode, strerror(errno)));
3035 * If the response we got was not an answer to our message, but
3036 * was a completely different request, push it onto the pending
3037 * udp message stack so that we can deal with it in the main loop.
3038 * It may be another oplock break request to us.
3042 * Local note from JRA. There exists the possibility of a denial
3043 * of service attack here by allowing non-root processes running
3044 * on a local machine sending many of these pending messages to
3045 * a smbd port. Currently I'm not sure how to restrict the messages
3046 * I will queue (although I could add a limit to the queue) to
3047 * those received by root processes only. There should be a
3048 * way to make this bulletproof....
3051 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3052 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3054 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3056 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3059 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3064 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3065 (reply_from_port != share_entry->op_port) ||
3066 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3067 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3068 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3070 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3071 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3072 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3073 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3081 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3086 /****************************************************************************
3087 check if a snum is in use
3088 ****************************************************************************/
3089 BOOL snum_used(int snum)
3092 for (i=0;i<MAX_CONNECTIONS;i++)
3093 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3098 /****************************************************************************
3099 reload the services file
3100 **************************************************************************/
3101 BOOL reload_services(BOOL test)
3108 pstrcpy(fname,lp_configfile());
3109 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3111 pstrcpy(servicesf,fname);
3118 if (test && !lp_file_list_changed())
3121 lp_killunused(snum_used);
3123 ret = lp_load(servicesf,False);
3125 /* perhaps the config filename is now set */
3127 reload_services(True);
3136 set_socket_options(Client,"SO_KEEPALIVE");
3137 set_socket_options(Client,user_socket_options);
3141 reset_mangled_stack( lp_mangledstack() );
3143 /* this forces service parameters to be flushed */
3144 become_service(-1,True);
3151 /****************************************************************************
3152 this prevents zombie child processes
3153 ****************************************************************************/
3154 static int sig_hup()
3156 BlockSignals(True,SIGHUP);
3157 DEBUG(0,("Got SIGHUP\n"));
3158 reload_services(False);
3159 #ifndef DONT_REINSTALL_SIG
3160 signal(SIGHUP,SIGNAL_CAST sig_hup);
3162 BlockSignals(False,SIGHUP);
3166 /****************************************************************************
3167 Setup the groups a user belongs to.
3168 ****************************************************************************/
3169 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3170 int **p_igroups, gid_t **p_groups,
3173 if (-1 == initgroups(user,gid))
3177 DEBUG(0,("Unable to initgroups!\n"));
3178 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3179 DEBUG(0,("This is probably a problem with the account %s\n",user));
3188 ngroups = getgroups(0,&grp);
3191 igroups = (int *)malloc(sizeof(int)*ngroups);
3192 attrs = (int *)malloc(sizeof(int)*ngroups);
3193 for (i=0;i<ngroups;i++)
3195 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3196 igroups[i] = 0x42424242;
3198 ngroups = getgroups(ngroups,(gid_t *)igroups);
3200 if (igroups[0] == 0x42424242)
3203 *p_ngroups = ngroups;
3206 /* The following bit of code is very strange. It is due to the
3207 fact that some OSes use int* and some use gid_t* for
3208 getgroups, and some (like SunOS) use both, one in prototypes,
3209 and one in man pages and the actual code. Thus we detect it
3210 dynamically using some very ugly code */
3213 /* does getgroups return ints or gid_t ?? */
3214 static BOOL groups_use_ints = True;
3216 if (groups_use_ints &&
3218 SVAL(igroups,2) == 0x4242)
3219 groups_use_ints = False;
3221 for (i=0;groups_use_ints && i<ngroups;i++)
3222 if (igroups[i] == 0x42424242)
3223 groups_use_ints = False;
3225 if (groups_use_ints)
3227 *p_igroups = igroups;
3228 *p_groups = (gid_t *)igroups;
3232 gid_t *groups = (gid_t *)igroups;
3233 igroups = (int *)malloc(sizeof(int)*ngroups);
3234 for (i=0;i<ngroups;i++)
3236 igroups[i] = groups[i];
3238 *p_igroups = igroups;
3239 *p_groups = (gid_t *)groups;
3242 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3243 for (i=0;i<ngroups;i++)
3244 DEBUG(3,("%d ",igroups[i]));
3250 /****************************************************************************
3251 make a connection to a service
3252 ****************************************************************************/
3253 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3257 struct passwd *pass = NULL;
3258 connection_struct *pcon;
3261 static BOOL first_connection = True;
3265 snum = find_service(service);
3268 if (strequal(service,"IPC$"))
3270 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3274 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3278 if (strequal(service,HOMES_NAME))
3280 if (*user && Get_Pwnam(user,True))
3281 return(make_connection(user,user,password,pwlen,dev,vuid));
3283 if (validated_username(vuid))
3285 strcpy(user,validated_username(vuid));
3286 return(make_connection(user,user,password,pwlen,dev,vuid));
3290 if (!lp_snum_ok(snum) || !check_access(snum)) {
3294 /* you can only connect to the IPC$ service as an ipc device */
3295 if (strequal(service,"IPC$"))
3298 if (*dev == '?' || !*dev)
3300 if (lp_print_ok(snum))
3301 strcpy(dev,"LPT1:");
3306 /* if the request is as a printer and you can't print then refuse */
3308 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3309 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3313 /* lowercase the user name */
3316 /* add it as a possible user name */
3317 add_session_user(service);
3319 /* shall we let them in? */
3320 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3322 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3326 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3329 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3333 pcon = &Connections[cnum];
3334 bzero((char *)pcon,sizeof(*pcon));
3336 /* find out some info about the user */
3337 pass = Get_Pwnam(user,True);
3341 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3345 pcon->read_only = lp_readonly(snum);
3349 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3350 string_sub(list,"%S",service);
3352 if (user_in_list(user,list))
3353 pcon->read_only = True;
3355 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3356 string_sub(list,"%S",service);
3358 if (user_in_list(user,list))
3359 pcon->read_only = False;
3362 /* admin user check */
3364 /* JRA - original code denied admin user if the share was
3365 marked read_only. Changed as I don't think this is needed,
3366 but old code left in case there is a problem here.
3368 if (user_in_list(user,lp_admin_users(snum))
3370 && !pcon->read_only)
3375 pcon->admin_user = True;
3376 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3379 pcon->admin_user = False;
3381 pcon->force_user = force;
3383 pcon->uid = pass->pw_uid;
3384 pcon->gid = pass->pw_gid;
3385 pcon->num_files_open = 0;
3386 pcon->lastused = time(NULL);
3387 pcon->service = snum;
3389 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3390 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3391 pcon->dirptr = NULL;
3392 pcon->veto_list = NULL;
3393 pcon->hide_list = NULL;
3394 string_set(&pcon->dirpath,"");
3395 string_set(&pcon->user,user);
3398 if (*lp_force_group(snum))
3403 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3404 /* default service may be a group name */
3405 string_sub(gname,"%S",service);
3406 gptr = (struct group *)getgrnam(gname);
3410 pcon->gid = gptr->gr_gid;
3411 DEBUG(3,("Forced group %s\n",gname));
3414 DEBUG(1,("Couldn't find group %s\n",gname));
3418 if (*lp_force_user(snum))
3420 struct passwd *pass2;
3422 fstrcpy(fuser,lp_force_user(snum));
3423 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3426 pcon->uid = pass2->pw_uid;
3427 string_set(&pcon->user,fuser);
3428 fstrcpy(user,fuser);
3429 pcon->force_user = True;
3430 DEBUG(3,("Forced user %s\n",fuser));
3433 DEBUG(1,("Couldn't find user %s\n",fuser));
3438 pstrcpy(s,lp_pathname(snum));
3439 standard_sub(cnum,s);
3440 string_set(&pcon->connectpath,s);
3441 DEBUG(3,("Connect path is %s\n",s));
3444 /* groups stuff added by ih */
3446 pcon->igroups = NULL;
3447 pcon->groups = NULL;
3452 /* Find all the groups this uid is in and store them. Used by become_user() */
3453 setup_groups(pcon->user,pcon->uid,pcon->gid,
3454 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3456 /* check number of connections */
3457 if (!claim_connection(cnum,
3458 lp_servicename(SNUM(cnum)),
3459 lp_max_connections(SNUM(cnum)),False))
3461 DEBUG(1,("too many connections - rejected\n"));
3465 if (lp_status(SNUM(cnum)))
3466 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3468 first_connection = False;
3473 /* execute any "root preexec = " line */
3474 if (*lp_rootpreexec(SNUM(cnum)))
3477 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3478 standard_sub(cnum,cmd);
3479 DEBUG(5,("cmd=%s\n",cmd));
3480 smbrun(cmd,NULL,False);
3483 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3485 DEBUG(0,("Can't become connected user!\n"));
3487 if (!IS_IPC(cnum)) {
3488 yield_connection(cnum,
3489 lp_servicename(SNUM(cnum)),
3490 lp_max_connections(SNUM(cnum)));
3491 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3496 if (ChDir(pcon->connectpath) != 0)
3498 DEBUG(0,("Can't change directory to %s (%s)\n",
3499 pcon->connectpath,strerror(errno)));
3502 if (!IS_IPC(cnum)) {
3503 yield_connection(cnum,
3504 lp_servicename(SNUM(cnum)),
3505 lp_max_connections(SNUM(cnum)));
3506 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3511 string_set(&pcon->origpath,pcon->connectpath);
3513 #if SOFTLINK_OPTIMISATION
3514 /* resolve any soft links early */
3517 pstrcpy(s,pcon->connectpath);
3519 string_set(&pcon->connectpath,s);
3520 ChDir(pcon->connectpath);
3524 num_connections_open++;
3525 add_session_user(user);
3527 /* execute any "preexec = " line */
3528 if (*lp_preexec(SNUM(cnum)))
3531 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3532 standard_sub(cnum,cmd);
3533 smbrun(cmd,NULL,False);
3536 /* we've finished with the sensitive stuff */
3539 /* Add veto/hide lists */
3540 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3542 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3543 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3547 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3551 lp_servicename(SNUM(cnum)),user,
3561 /****************************************************************************
3562 find first available file slot
3563 ****************************************************************************/
3564 int find_free_file(void )
3567 /* we start at 1 here for an obscure reason I can't now remember,
3568 but I think is important :-) */
3569 for (i=1;i<MAX_OPEN_FILES;i++)
3572 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3576 /****************************************************************************
3577 find first available connection slot, starting from a random position.
3578 The randomisation stops problems with the server dieing and clients
3579 thinking the server is still available.
3580 ****************************************************************************/
3581 static int find_free_connection(int hash )
3585 hash = (hash % (MAX_CONNECTIONS-2))+1;
3589 for (i=hash+1;i!=hash;)
3591 if (!Connections[i].open && Connections[i].used == used)
3593 DEBUG(3,("found free connection number %d\n",i));
3597 if (i == MAX_CONNECTIONS)
3607 DEBUG(1,("ERROR! Out of connection structures\n"));
3612 /****************************************************************************
3613 reply for the core protocol
3614 ****************************************************************************/
3615 int reply_corep(char *outbuf)
3617 int outsize = set_message(outbuf,1,0,True);
3619 Protocol = PROTOCOL_CORE;
3625 /****************************************************************************
3626 reply for the coreplus protocol
3627 ****************************************************************************/
3628 int reply_coreplus(char *outbuf)
3630 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3631 int outsize = set_message(outbuf,13,0,True);
3632 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3633 readbraw and writebraw (possibly) */
3634 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3635 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3637 Protocol = PROTOCOL_COREPLUS;
3643 /****************************************************************************
3644 reply for the lanman 1.0 protocol
3645 ****************************************************************************/
3646 int reply_lanman1(char *outbuf)
3648 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3650 BOOL doencrypt = SMBENCRYPT();
3651 time_t t = time(NULL);
3653 if (lp_security()>=SEC_USER) secword |= 1;
3654 if (doencrypt) secword |= 2;
3656 set_message(outbuf,13,doencrypt?8:0,True);
3657 SSVAL(outbuf,smb_vwv1,secword);
3658 /* Create a token value and add it to the outgoing packet. */
3660 generate_next_challenge(smb_buf(outbuf));
3662 Protocol = PROTOCOL_LANMAN1;
3664 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3665 SSVAL(outbuf,smb_vwv2,max_recv);
3666 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3667 SSVAL(outbuf,smb_vwv4,1);
3668 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3669 readbraw writebraw (possibly) */
3670 SIVAL(outbuf,smb_vwv6,getpid());
3671 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3673 put_dos_date(outbuf,smb_vwv8,t);
3675 return (smb_len(outbuf)+4);
3679 /****************************************************************************
3680 reply for the lanman 2.0 protocol
3681 ****************************************************************************/
3682 int reply_lanman2(char *outbuf)
3684 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3686 BOOL doencrypt = SMBENCRYPT();
3687 time_t t = time(NULL);
3688 struct cli_state *cli = NULL;
3692 if (lp_security() == SEC_SERVER) {
3693 cli = server_cryptkey();
3697 DEBUG(3,("using password server validation\n"));
3698 doencrypt = ((cli->sec_mode & 2) != 0);
3701 if (lp_security()>=SEC_USER) secword |= 1;
3702 if (doencrypt) secword |= 2;
3707 generate_next_challenge(cryptkey);
3709 memcpy(cryptkey, cli->cryptkey, 8);
3710 set_challenge(cli->cryptkey);
3714 set_message(outbuf,13,crypt_len,True);
3715 SSVAL(outbuf,smb_vwv1,secword);
3716 SIVAL(outbuf,smb_vwv6,getpid());
3718 memcpy(smb_buf(outbuf), cryptkey, 8);
3720 Protocol = PROTOCOL_LANMAN2;
3722 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3723 SSVAL(outbuf,smb_vwv2,max_recv);
3724 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3725 SSVAL(outbuf,smb_vwv4,1);
3726 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3727 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3728 put_dos_date(outbuf,smb_vwv8,t);
3730 return (smb_len(outbuf)+4);
3734 /****************************************************************************
3735 reply for the nt protocol
3736 ****************************************************************************/
3737 int reply_nt1(char *outbuf)
3739 /* dual names + lock_and_read + nt SMBs + remote API calls */
3740 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3742 other valid capabilities which we may support at some time...
3743 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3744 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3748 BOOL doencrypt = SMBENCRYPT();
3749 time_t t = time(NULL);
3751 struct cli_state *cli = NULL;
3755 if (lp_security() == SEC_SERVER) {
3756 cli = server_cryptkey();
3760 DEBUG(3,("using password server validation\n"));
3761 doencrypt = ((cli->sec_mode & 2) != 0);
3767 generate_next_challenge(cryptkey);
3769 memcpy(cryptkey, cli->cryptkey, 8);
3770 set_challenge(cli->cryptkey);
3774 if (lp_readraw() && lp_writeraw()) {
3775 capabilities |= CAP_RAW_MODE;
3778 if (lp_security() >= SEC_USER) secword |= 1;
3779 if (doencrypt) secword |= 2;
3781 /* decide where (if) to put the encryption challenge, and
3782 follow it with the OEM'd domain name
3784 data_len = crypt_len + strlen(myworkgroup) + 1;
3786 set_message(outbuf,17,data_len,True);
3787 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3789 CVAL(outbuf,smb_vwv1) = secword;
3790 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3792 memcpy(smb_buf(outbuf), cryptkey, 8);
3794 Protocol = PROTOCOL_NT1;
3796 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3797 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3798 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3799 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3800 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3801 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3802 put_long_date(outbuf+smb_vwv11+1,t);
3803 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3804 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3806 return (smb_len(outbuf)+4);
3809 /* these are the protocol lists used for auto architecture detection:
3812 protocol [PC NETWORK PROGRAM 1.0]
3813 protocol [XENIX CORE]
3814 protocol [MICROSOFT NETWORKS 1.03]
3815 protocol [LANMAN1.0]
3816 protocol [Windows for Workgroups 3.1a]
3817 protocol [LM1.2X002]
3818 protocol [LANMAN2.1]
3819 protocol [NT LM 0.12]
3822 protocol [PC NETWORK PROGRAM 1.0]
3823 protocol [XENIX CORE]
3824 protocol [MICROSOFT NETWORKS 1.03]
3825 protocol [LANMAN1.0]
3826 protocol [Windows for Workgroups 3.1a]
3827 protocol [LM1.2X002]
3828 protocol [LANMAN2.1]
3829 protocol [NT LM 0.12]
3832 protocol [PC NETWORK PROGRAM 1.0]
3833 protocol [XENIX CORE]
3834 protocol [LANMAN1.0]
3835 protocol [LM1.2X002]
3836 protocol [LANMAN2.1]
3840 * Modified to recognize the architecture of the remote machine better.
3842 * This appears to be the matrix of which protocol is used by which
3844 Protocol WfWg Win95 WinNT OS/2
3845 PC NETWORK PROGRAM 1.0 1 1 1 1
3847 MICROSOFT NETWORKS 3.0 2 2
3849 MICROSOFT NETWORKS 1.03 3
3852 Windows for Workgroups 3.1a 5 5 5
3857 * tim@fsg.com 09/29/95
3860 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3861 #define ARCH_WIN95 0x2
3862 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3863 #define ARCH_WINNT 0x8
3864 #define ARCH_SAMBA 0x10
3866 #define ARCH_ALL 0x1F
3868 /* List of supported protocols, most desired first */
3872 int (*proto_reply_fn)(char *);
3874 } supported_protocols[] = {
3875 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3876 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3877 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3878 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3879 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3880 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3881 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3882 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3883 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3888 /****************************************************************************
3890 ****************************************************************************/
3891 static int reply_negprot(char *inbuf,char *outbuf)
3893 int outsize = set_message(outbuf,1,0,True);
3898 int bcc = SVAL(smb_buf(inbuf),-2);
3899 int arch = ARCH_ALL;
3901 p = smb_buf(inbuf)+1;
3902 while (p < (smb_buf(inbuf) + bcc))
3905 DEBUG(3,("Requested protocol [%s]\n",p));
3906 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3907 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3908 else if (strcsequal(p,"DOS LM1.2X002"))
3909 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3910 else if (strcsequal(p,"DOS LANMAN2.1"))
3911 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3912 else if (strcsequal(p,"NT LM 0.12"))
3913 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3914 else if (strcsequal(p,"LANMAN2.1"))
3915 arch &= ( ARCH_WINNT | ARCH_OS2 );
3916 else if (strcsequal(p,"LM1.2X002"))
3917 arch &= ( ARCH_WINNT | ARCH_OS2 );
3918 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3920 else if (strcsequal(p,"XENIX CORE"))
3921 arch &= ( ARCH_WINNT | ARCH_OS2 );
3922 else if (strcsequal(p,"Samba")) {
3932 set_remote_arch(RA_SAMBA);
3935 set_remote_arch(RA_WFWG);
3938 set_remote_arch(RA_WIN95);
3941 set_remote_arch(RA_WINNT);
3944 set_remote_arch(RA_OS2);
3947 set_remote_arch(RA_UNKNOWN);
3951 /* possibly reload - change of architecture */
3952 reload_services(True);
3954 /* a special case to stop password server loops */
3955 if (Index == 1 && strequal(remote_machine,myhostname) &&
3956 lp_security()==SEC_SERVER)
3957 exit_server("Password server loop!");
3959 /* Check for protocols, most desirable first */
3960 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3962 p = smb_buf(inbuf)+1;
3964 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3965 while (p < (smb_buf(inbuf) + bcc))
3967 if (strequal(p,supported_protocols[protocol].proto_name))
3976 SSVAL(outbuf,smb_vwv0,choice);
3978 extern fstring remote_proto;
3979 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3980 reload_services(True);
3981 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3982 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3985 DEBUG(0,("No protocol supported !\n"));
3987 SSVAL(outbuf,smb_vwv0,choice);
3989 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3995 /****************************************************************************
3996 close all open files for a connection
3997 ****************************************************************************/
3998 static void close_open_files(int cnum)
4001 for (i=0;i<MAX_OPEN_FILES;i++)
4002 if( Files[i].cnum == cnum && Files[i].open) {
4003 close_file(i,False);
4009 /****************************************************************************
4011 ****************************************************************************/
4012 void close_cnum(int cnum, uint16 vuid)
4014 DirCacheFlush(SNUM(cnum));
4018 if (!OPEN_CNUM(cnum))
4020 DEBUG(0,("Can't close cnum %d\n",cnum));
4024 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4026 remote_machine,client_addr(),
4027 lp_servicename(SNUM(cnum))));
4029 yield_connection(cnum,
4030 lp_servicename(SNUM(cnum)),
4031 lp_max_connections(SNUM(cnum)));
4033 if (lp_status(SNUM(cnum)))
4034 yield_connection(cnum,"STATUS.",MAXSTATUS);
4036 close_open_files(cnum);
4037 dptr_closecnum(cnum);
4039 /* execute any "postexec = " line */
4040 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4043 strcpy(cmd,lp_postexec(SNUM(cnum)));
4044 standard_sub(cnum,cmd);
4045 smbrun(cmd,NULL,False);
4050 /* execute any "root postexec = " line */
4051 if (*lp_rootpostexec(SNUM(cnum)))
4054 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4055 standard_sub(cnum,cmd);
4056 smbrun(cmd,NULL,False);
4059 Connections[cnum].open = False;
4060 num_connections_open--;
4061 if (Connections[cnum].ngroups && Connections[cnum].groups)
4063 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4064 free(Connections[cnum].groups);
4065 free(Connections[cnum].igroups);
4066 Connections[cnum].groups = NULL;
4067 Connections[cnum].igroups = NULL;
4068 Connections[cnum].ngroups = 0;
4071 free_namearray(Connections[cnum].veto_list);
4072 free_namearray(Connections[cnum].hide_list);
4074 string_set(&Connections[cnum].user,"");
4075 string_set(&Connections[cnum].dirpath,"");
4076 string_set(&Connections[cnum].connectpath,"");
4080 /****************************************************************************
4081 simple routines to do connection counting
4082 ****************************************************************************/
4083 BOOL yield_connection(int cnum,char *name,int max_connections)
4085 struct connect_record crec;
4088 int mypid = getpid();
4091 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4093 if (max_connections <= 0)
4096 bzero(&crec,sizeof(crec));
4098 pstrcpy(fname,lp_lockdir());
4099 standard_sub(cnum,fname);
4100 trim_string(fname,"","/");
4104 strcat(fname,".LCK");
4106 f = fopen(fname,"r+");
4109 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4113 fseek(f,0,SEEK_SET);
4115 /* find a free spot */
4116 for (i=0;i<max_connections;i++)
4118 if (fread(&crec,sizeof(crec),1,f) != 1)
4120 DEBUG(2,("Entry not found in lock file %s\n",fname));
4124 if (crec.pid == mypid && crec.cnum == cnum)
4128 if (crec.pid != mypid || crec.cnum != cnum)
4131 DEBUG(2,("Entry not found in lock file %s\n",fname));
4135 bzero((void *)&crec,sizeof(crec));
4137 /* remove our mark */
4138 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4139 fwrite(&crec,sizeof(crec),1,f) != 1)
4141 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4146 DEBUG(3,("Yield successful\n"));
4153 /****************************************************************************
4154 simple routines to do connection counting
4155 ****************************************************************************/
4156 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4158 struct connect_record crec;
4161 int snum = SNUM(cnum);
4165 if (max_connections <= 0)
4168 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4170 pstrcpy(fname,lp_lockdir());
4171 standard_sub(cnum,fname);
4172 trim_string(fname,"","/");
4174 if (!directory_exist(fname,NULL))
4179 strcat(fname,".LCK");
4181 if (!file_exist(fname,NULL))
4183 int oldmask = umask(022);
4184 f = fopen(fname,"w");
4189 total_recs = file_size(fname) / sizeof(crec);
4191 f = fopen(fname,"r+");
4195 DEBUG(1,("couldn't open lock file %s\n",fname));
4199 /* find a free spot */
4200 for (i=0;i<max_connections;i++)
4203 if (i>=total_recs ||
4204 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4205 fread(&crec,sizeof(crec),1,f) != 1)
4207 if (foundi < 0) foundi = i;
4211 if (Clear && crec.pid && !process_exists(crec.pid))
4213 fseek(f,i*sizeof(crec),SEEK_SET);
4214 bzero((void *)&crec,sizeof(crec));
4215 fwrite(&crec,sizeof(crec),1,f);
4216 if (foundi < 0) foundi = i;
4219 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4228 DEBUG(3,("no free locks in %s\n",fname));
4233 /* fill in the crec */
4234 bzero((void *)&crec,sizeof(crec));
4235 crec.magic = 0x280267;
4236 crec.pid = getpid();
4238 crec.uid = Connections[cnum].uid;
4239 crec.gid = Connections[cnum].gid;
4240 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4241 crec.start = time(NULL);
4243 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4244 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4247 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4248 fwrite(&crec,sizeof(crec),1,f) != 1)
4259 /*******************************************************************
4260 prepare to dump a core file - carefully!
4261 ********************************************************************/
4262 static BOOL dump_core(void)
4266 pstrcpy(dname,debugf);
4267 if ((p=strrchr(dname,'/'))) *p=0;
4268 strcat(dname,"/corefiles");
4270 sys_chown(dname,getuid(),getgid());
4272 if (chdir(dname)) return(False);
4275 #ifndef NO_GETRLIMIT
4279 getrlimit(RLIMIT_CORE, &rlp);
4280 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4281 setrlimit(RLIMIT_CORE, &rlp);
4282 getrlimit(RLIMIT_CORE, &rlp);
4283 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4289 DEBUG(0,("Dumping core in %s\n",dname));
4294 /****************************************************************************
4296 ****************************************************************************/
4297 void exit_server(char *reason)
4299 static int firsttime=1;
4302 if (!firsttime) exit(0);
4306 DEBUG(2,("Closing connections\n"));
4307 for (i=0;i<MAX_CONNECTIONS;i++)
4308 if (Connections[i].open)
4309 close_cnum(i,(uint16)-1);
4311 if (dcelogin_atmost_once)
4315 int oldlevel = DEBUGLEVEL;
4317 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4319 show_msg(last_inbuf);
4320 DEBUGLEVEL = oldlevel;
4321 DEBUG(0,("===============================================================\n"));
4323 if (dump_core()) return;
4329 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4333 /****************************************************************************
4334 do some standard substitutions in a string
4335 ****************************************************************************/
4336 void standard_sub(int cnum,char *str)
4338 if (VALID_CNUM(cnum)) {
4341 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4343 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4344 string_sub(p,"%H",home);
4348 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4349 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4350 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4351 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4352 case '\0' : p++; break; /* don't run off the end of the string */
4353 default : p+=2; break;
4357 standard_sub_basic(str);
4361 These flags determine some of the permissions required to do an operation
4363 Note that I don't set NEED_WRITE on some write operations because they
4364 are used by some brain-dead clients when printing, and I don't want to
4365 force write permissions on print services.
4367 #define AS_USER (1<<0)
4368 #define NEED_WRITE (1<<1)
4369 #define TIME_INIT (1<<2)
4370 #define CAN_IPC (1<<3)
4371 #define AS_GUEST (1<<5)
4375 define a list of possible SMB messages and their corresponding
4376 functions. Any message that has a NULL function is unimplemented -
4377 please feel free to contribute implementations!
4379 struct smb_message_struct
4393 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4394 {SMBtcon,"SMBtcon",reply_tcon,0},
4395 {SMBtdis,"SMBtdis",reply_tdis,0},
4396 {SMBexit,"SMBexit",reply_exit,0},
4397 {SMBioctl,"SMBioctl",reply_ioctl,0},
4398 {SMBecho,"SMBecho",reply_echo,0},
4399 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4400 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4401 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4402 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4403 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4404 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4405 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4406 {SMBopen,"SMBopen",reply_open,AS_USER},
4408 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4409 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4410 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4412 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4413 {SMBread,"SMBread",reply_read,AS_USER},
4414 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4415 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4416 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4417 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4418 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4419 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4421 /* this is a Pathworks specific call, allowing the
4422 changing of the root path */
4423 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4425 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4426 {SMBflush,"SMBflush",reply_flush,AS_USER},
4427 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4428 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4429 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4430 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4431 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4432 {SMBlock,"SMBlock",reply_lock,AS_USER},
4433 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4435 /* CORE+ PROTOCOL FOLLOWS */
4437 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4438 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4439 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4440 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4441 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4443 /* LANMAN1.0 PROTOCOL FOLLOWS */
4445 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4446 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4447 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4448 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4449 {SMBwritec,"SMBwritec",NULL,AS_USER},
4450 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4451 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4452 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4453 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4454 {SMBioctls,"SMBioctls",NULL,AS_USER},
4455 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4456 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4458 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4459 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4460 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4461 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4463 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4464 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4465 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4467 /* LANMAN2.0 PROTOCOL FOLLOWS */
4468 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4469 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4470 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4471 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4473 /* messaging routines */
4474 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4475 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4476 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4477 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4479 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4481 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4482 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4483 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4484 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4487 /****************************************************************************
4488 return a string containing the function name of a SMB command
4489 ****************************************************************************/
4490 char *smb_fn_name(int type)
4492 static char *unknown_name = "SMBunknown";
4493 static int num_smb_messages =
4494 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4497 for (match=0;match<num_smb_messages;match++)
4498 if (smb_messages[match].code == type)
4501 if (match == num_smb_messages)
4502 return(unknown_name);
4504 return(smb_messages[match].name);
4508 /****************************************************************************
4509 do a switch on the message type, and return the response size
4510 ****************************************************************************/
4511 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4515 static int num_smb_messages =
4516 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4520 struct timeval msg_start_time;
4521 struct timeval msg_end_time;
4522 static unsigned long total_time = 0;
4524 GetTimeOfDay(&msg_start_time);
4531 last_message = type;
4533 /* make sure this is an SMB packet */
4534 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4536 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4540 for (match=0;match<num_smb_messages;match++)
4541 if (smb_messages[match].code == type)
4544 if (match == num_smb_messages)
4546 DEBUG(0,("Unknown message type %d!\n",type));
4547 outsize = reply_unknown(inbuf,outbuf);
4551 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4552 if (smb_messages[match].fn)
4554 int cnum = SVAL(inbuf,smb_tid);
4555 int flags = smb_messages[match].flags;
4556 uint16 session_tag = SVAL(inbuf,smb_uid);
4558 /* does this protocol need to be run as root? */
4559 if (!(flags & AS_USER))
4562 /* does this protocol need to be run as the connected user? */
4563 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4564 if (flags & AS_GUEST)
4567 return(ERROR(ERRSRV,ERRinvnid));
4569 /* this code is to work around a bug is MS client 3 without
4570 introducing a security hole - it needs to be able to do
4571 print queue checks as guest if it isn't logged in properly */
4572 if (flags & AS_USER)
4575 /* does it need write permission? */
4576 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4577 return(ERROR(ERRSRV,ERRaccess));
4579 /* ipc services are limited */
4580 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4581 return(ERROR(ERRSRV,ERRaccess));
4583 /* load service specific parameters */
4584 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4585 return(ERROR(ERRSRV,ERRaccess));
4587 /* does this protocol need to be run as guest? */
4588 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4589 return(ERROR(ERRSRV,ERRaccess));
4593 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4597 outsize = reply_unknown(inbuf,outbuf);
4602 GetTimeOfDay(&msg_end_time);
4603 if (!(smb_messages[match].flags & TIME_INIT))
4605 smb_messages[match].time = 0;
4606 smb_messages[match].flags |= TIME_INIT;
4609 unsigned long this_time =
4610 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4611 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4612 smb_messages[match].time += this_time;
4613 total_time += this_time;
4615 DEBUG(2,("TIME %s %d usecs %g pct\n",
4616 smb_fn_name(type),smb_messages[match].time,
4617 (100.0*smb_messages[match].time) / total_time));
4624 /****************************************************************************
4625 construct a chained reply and add it to the already made reply
4626 **************************************************************************/
4627 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4629 static char *orig_inbuf;
4630 static char *orig_outbuf;
4631 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4632 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4633 char *inbuf2, *outbuf2;
4635 char inbuf_saved[smb_wct];
4636 char outbuf_saved[smb_wct];
4637 extern int chain_size;
4638 int wct = CVAL(outbuf,smb_wct);
4639 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4641 /* maybe its not chained */
4642 if (smb_com2 == 0xFF) {
4643 CVAL(outbuf,smb_vwv0) = 0xFF;
4647 if (chain_size == 0) {
4648 /* this is the first part of the chain */
4650 orig_outbuf = outbuf;
4653 /* we need to tell the client where the next part of the reply will be */
4654 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4655 CVAL(outbuf,smb_vwv0) = smb_com2;
4657 /* remember how much the caller added to the chain, only counting stuff
4658 after the parameter words */
4659 chain_size += outsize - smb_wct;
4661 /* work out pointers into the original packets. The
4662 headers on these need to be filled in */
4663 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4664 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4666 /* remember the original command type */
4667 smb_com1 = CVAL(orig_inbuf,smb_com);
4669 /* save the data which will be overwritten by the new headers */
4670 memcpy(inbuf_saved,inbuf2,smb_wct);
4671 memcpy(outbuf_saved,outbuf2,smb_wct);
4673 /* give the new packet the same header as the last part of the SMB */
4674 memmove(inbuf2,inbuf,smb_wct);
4676 /* create the in buffer */
4677 CVAL(inbuf2,smb_com) = smb_com2;
4679 /* create the out buffer */
4680 bzero(outbuf2,smb_size);
4681 set_message(outbuf2,0,0,True);
4682 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4684 memcpy(outbuf2+4,inbuf2+4,4);
4685 CVAL(outbuf2,smb_rcls) = SUCCESS;
4686 CVAL(outbuf2,smb_reh) = 0;
4687 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4689 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4690 SSVAL(outbuf2,smb_err,SUCCESS);
4691 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4692 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4693 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4694 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4696 DEBUG(3,("Chained message\n"));
4699 /* process the request */
4700 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4701 bufsize-chain_size);
4703 /* copy the new reply and request headers over the old ones, but
4704 preserve the smb_com field */
4705 memmove(orig_outbuf,outbuf2,smb_wct);
4706 CVAL(orig_outbuf,smb_com) = smb_com1;
4708 /* restore the saved data, being careful not to overwrite any
4709 data from the reply header */
4710 memcpy(inbuf2,inbuf_saved,smb_wct);
4712 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4713 if (ofs < 0) ofs = 0;
4714 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4722 /****************************************************************************
4723 construct a reply to the incoming packet
4724 ****************************************************************************/
4725 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4727 int type = CVAL(inbuf,smb_com);
4729 int msg_type = CVAL(inbuf,0);
4730 extern int chain_size;
4732 smb_last_time = time(NULL);
4738 bzero(outbuf,smb_size);
4741 return(reply_special(inbuf,outbuf));
4743 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4744 set_message(outbuf,0,0,True);
4746 memcpy(outbuf+4,inbuf+4,4);
4747 CVAL(outbuf,smb_rcls) = SUCCESS;
4748 CVAL(outbuf,smb_reh) = 0;
4749 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4751 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4752 SSVAL(outbuf,smb_err,SUCCESS);
4753 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4754 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4755 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4756 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4758 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4760 outsize += chain_size;
4763 smb_setlen(outbuf,outsize - 4);
4767 /****************************************************************************
4768 process commands from the client
4769 ****************************************************************************/
4770 static void process(void)
4774 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4775 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4776 if ((InBuffer == NULL) || (OutBuffer == NULL))
4779 InBuffer += SMB_ALIGNMENT;
4780 OutBuffer += SMB_ALIGNMENT;
4783 DEBUG(3,("priming nmbd\n"));
4786 ip = *interpret_addr2("localhost");
4787 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4789 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4793 /* re-initialise the timezone */
4798 int deadtime = lp_deadtime()*60;
4800 int last_keepalive=0;
4801 int service_load_counter = 0;
4802 BOOL got_smb = False;
4805 deadtime = DEFAULT_SMBD_TIMEOUT;
4807 #if USE_READ_PREDICTION
4808 if (lp_readprediction())
4809 do_read_prediction();
4814 for (counter=SMBD_SELECT_LOOP;
4815 !receive_message_or_smb(Client,oplock_sock,
4816 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4817 counter += SMBD_SELECT_LOOP)
4821 BOOL allidle = True;
4822 extern int keepalive;
4824 if (counter > 365 * 3600) /* big number of seconds. */
4827 service_load_counter = 0;
4830 if (smb_read_error == READ_EOF)
4832 DEBUG(3,("end of file from client\n"));
4836 if (smb_read_error == READ_ERROR)
4838 DEBUG(3,("receive_smb error (%s) exiting\n",
4845 /* become root again if waiting */
4848 /* check for smb.conf reload */
4849 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4851 service_load_counter = counter;
4853 /* reload services, if files have changed. */
4854 reload_services(True);
4857 /* automatic timeout if all connections are closed */
4858 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4860 DEBUG(2,("%s Closing idle connection\n",timestring()));
4864 if (keepalive && (counter-last_keepalive)>keepalive)
4866 struct cli_state *cli = server_client();
4867 if (!send_keepalive(Client)) {
4868 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4871 /* also send a keepalive to the password server if its still
4873 if (cli && cli->initialised)
4874 send_keepalive(cli->fd);
4875 last_keepalive = counter;
4878 /* check for connection timeouts */
4879 for (i=0;i<MAX_CONNECTIONS;i++)
4880 if (Connections[i].open)
4882 /* close dirptrs on connections that are idle */
4883 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4886 if (Connections[i].num_files_open > 0 ||
4887 (t-Connections[i].lastused)<deadtime)
4891 if (allidle && num_connections_open>0)
4893 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4899 process_smb(InBuffer, OutBuffer);
4901 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4906 /****************************************************************************
4907 initialise connect, service and file structs
4908 ****************************************************************************/
4909 static void init_structs(void )
4912 get_myname(myhostname,NULL);
4914 for (i=0;i<MAX_CONNECTIONS;i++)
4916 Connections[i].open = False;
4917 Connections[i].num_files_open=0;
4918 Connections[i].lastused=0;
4919 Connections[i].used=False;
4920 string_init(&Connections[i].user,"");
4921 string_init(&Connections[i].dirpath,"");
4922 string_init(&Connections[i].connectpath,"");
4923 string_init(&Connections[i].origpath,"");
4926 for (i=0;i<MAX_OPEN_FILES;i++)
4928 Files[i].open = False;
4929 string_init(&Files[i].name,"");
4933 for (i=0;i<MAX_OPEN_FILES;i++)
4935 file_fd_struct *fd_ptr = &FileFd[i];
4936 fd_ptr->ref_count = 0;
4937 fd_ptr->dev = (int32)-1;
4938 fd_ptr->inode = (int32)-1;
4940 fd_ptr->fd_readonly = -1;
4941 fd_ptr->fd_writeonly = -1;
4942 fd_ptr->real_open_flags = -1;
4946 init_rpc_pipe_hnd();
4949 /* for LSA handles */
4950 init_lsa_policy_hnd();
4956 /****************************************************************************
4957 usage on the program
4958 ****************************************************************************/
4959 static void usage(char *pname)
4961 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4963 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4964 printf("Version %s\n",VERSION);
4965 printf("\t-D become a daemon\n");
4966 printf("\t-p port listen on the specified port\n");
4967 printf("\t-d debuglevel set the debuglevel\n");
4968 printf("\t-l log basename. Basename for log/debug files\n");
4969 printf("\t-s services file. Filename of services file\n");
4970 printf("\t-P passive only\n");
4971 printf("\t-a overwrite log file, don't append\n");
4976 /****************************************************************************
4978 ****************************************************************************/
4979 int main(int argc,char *argv[])
4981 extern BOOL append_log;
4982 /* shall I run as a daemon */
4983 BOOL is_daemon = False;
4984 int port = SMB_PORT;
4986 extern char *optarg;
4987 char pidFile[100] = { 0 };
4989 #ifdef NEED_AUTH_PARAMETERS
4990 set_auth_parameters(argc,argv);
5001 strcpy(debugf,SMBLOGFILE);
5003 setup_logging(argv[0],False);
5005 charset_initialise();
5007 /* make absolutely sure we run as root - to handle cases whre people
5008 are crazy enough to have it setuid */
5018 fault_setup(exit_server);
5019 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5021 /* we want total control over the permissions on created files,
5022 so set our umask to 0 */
5029 /* this is for people who can't start the program correctly */
5030 while (argc > 1 && (*argv[1] != '-'))
5036 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5040 strncpy(pidFile, optarg, sizeof(pidFile));
5043 strcpy(user_socket_options,optarg);
5046 strcpy(scope,optarg);
5050 extern BOOL passive;
5055 strcpy(servicesf,optarg);
5058 strcpy(debugf,optarg);
5062 extern BOOL append_log;
5063 append_log = !append_log;
5073 DEBUGLEVEL = atoi(optarg);
5076 port = atoi(optarg);
5089 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5090 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5092 #ifndef NO_GETRLIMIT
5093 #ifdef RLIMIT_NOFILE
5096 getrlimit(RLIMIT_NOFILE, &rlp);
5097 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5098 setrlimit(RLIMIT_NOFILE, &rlp);
5099 getrlimit(RLIMIT_NOFILE, &rlp);
5100 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5106 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5107 getuid(),getgid(),geteuid(),getegid()));
5109 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5111 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5117 if (!reload_services(False))
5120 codepage_initialise(lp_client_code_page());
5122 strcpy(myworkgroup, lp_workgroup());
5124 #ifndef NO_SIGNAL_TEST
5125 signal(SIGHUP,SIGNAL_CAST sig_hup);
5128 DEBUG(3,("%s loaded services\n",timestring()));
5130 if (!is_daemon && !is_a_socket(0))
5132 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5138 DEBUG(3,("%s becoming a daemon\n",timestring()));
5142 if (!directory_exist(lp_lockdir(), NULL)) {
5143 mkdir(lp_lockdir(), 0755);
5151 if ((fd = open(pidFile,
5155 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5157 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5160 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5162 DEBUG(0,("ERROR: smbd is already running\n"));
5165 sprintf(buf, "%u\n", (unsigned int) getpid());
5166 if (write(fd, buf, strlen(buf)) < 0)
5168 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5171 /* Leave pid file open & locked for the duration... */
5174 if (!open_sockets(is_daemon,port))
5177 if (!locking_init(0))
5180 /* possibly reload the services file. */
5181 reload_services(True);
5183 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5187 if (sys_chroot(lp_rootdir()) == 0)
5188 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5191 /* Setup the oplock IPC socket. */
5192 if(!open_oplock_ipc())
5198 exit_server("normal exit");