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 extern time_t smb_last_time;
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;
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);
218 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
222 /* hide files with a name starting with a . */
223 if (lp_hide_dot_files(SNUM(cnum)))
225 char *p = strrchr(path,'/');
231 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
235 /* Optimization : Only call is_hidden_path if it's not already
237 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
242 DEBUG(8,("dos_mode returning "));
244 if (result & aHIDDEN) DEBUG(8, ("h"));
245 if (result & aRONLY ) DEBUG(8, ("r"));
246 if (result & aSYSTEM) DEBUG(8, ("s"));
247 if (result & aDIR ) DEBUG(8, ("d"));
248 if (result & aARCH ) DEBUG(8, ("a"));
256 /*******************************************************************
257 chmod a file - but preserve some bits
258 ********************************************************************/
259 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
268 if (sys_stat(fname,st)) return(-1);
271 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
273 if (dos_mode(cnum,fname,st) == dosmode) return(0);
275 unixmode = unix_mode(cnum,dosmode);
277 /* preserve the s bits */
278 mask |= (S_ISUID | S_ISGID);
280 /* preserve the t bit */
285 /* possibly preserve the x bits */
286 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
287 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
288 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
290 unixmode |= (st->st_mode & mask);
292 /* if we previously had any r bits set then leave them alone */
293 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
294 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
298 /* if we previously had any w bits set then leave them alone
299 if the new mode is not rdonly */
300 if (!IS_DOS_READONLY(dosmode) &&
301 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
302 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
306 return(sys_chmod(fname,unixmode));
310 /****************************************************************************
311 check if two filenames are equal
313 this needs to be careful about whether we are case sensitive
314 ****************************************************************************/
315 static BOOL fname_equal(char *name1, char *name2)
317 int l1 = strlen(name1);
318 int l2 = strlen(name2);
320 /* handle filenames ending in a single dot */
321 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
325 ret = fname_equal(name1,name2);
330 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
334 ret = fname_equal(name1,name2);
339 /* now normal filename handling */
341 return(strcmp(name1,name2) == 0);
343 return(strequal(name1,name2));
347 /****************************************************************************
348 mangle the 2nd name and check if it is then equal to the first name
349 ****************************************************************************/
350 static BOOL mangled_equal(char *name1, char *name2)
354 if (is_8_3(name2, True))
357 strcpy(tmpname,name2);
358 mangle_name_83(tmpname);
360 return(strequal(name1,tmpname));
364 /****************************************************************************
365 scan a directory to find a filename, matching without case sensitivity
367 If the name looks like a mangled name then try via the mangling functions
368 ****************************************************************************/
369 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
376 mangled = is_mangled(name);
378 /* handle null paths */
382 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
388 check_mangled_stack(name);
390 /* open the directory */
391 if (!(cur_dir = OpenDir(cnum, path, True)))
393 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
397 /* now scan for matching names */
398 while ((dname = ReadDirName(cur_dir)))
401 (strequal(dname,".") || strequal(dname,"..")))
404 pstrcpy(name2,dname);
405 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
407 if ((mangled && mangled_equal(name,name2))
408 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
410 /* we've found the file, change it's name and return */
411 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
422 /****************************************************************************
423 This routine is called to convert names from the dos namespace to unix
424 namespace. It needs to handle any case conversions, mangling, format
427 We assume that we have already done a chdir() to the right "root" directory
430 The function will return False if some part of the name except for the last
431 part cannot be resolved
433 If the saved_last_component != 0, then the unmodified last component
434 of the pathname is returned there. This is used in an exceptional
435 case in reply_mv (so far). If saved_last_component == 0 then nothing
438 The bad_path arg is set to True if the filename walk failed. This is
439 used to pick the correct error code to return between ENOENT and ENOTDIR
440 as Windows applications depend on ERRbadpath being returned if a component
441 of a pathname does not exist.
442 ****************************************************************************/
443 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
453 if(saved_last_component)
454 *saved_last_component = 0;
456 /* convert to basic unix format - removing \ chars and cleaning it up */
458 unix_clean_name(name);
460 /* names must be relative to the root of the service - trim any leading /.
461 also trim trailing /'s */
462 trim_string(name,"/","/");
465 * Ensure saved_last_component is valid even if file exists.
467 if(saved_last_component) {
468 end = strrchr(name, '/');
470 strcpy(saved_last_component, end + 1);
472 strcpy(saved_last_component, name);
475 if (!case_sensitive &&
476 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
479 /* check if it's a printer file */
480 if (Connections[cnum].printer)
482 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
486 sprintf(name2,"%.6s.XXXXXX",remote_machine);
487 /* sanitise the name */
488 for (s=name2 ; *s ; s++)
489 if (!issafe(*s)) *s = '_';
490 strcpy(name,(char *)mktemp(name2));
495 /* stat the name - if it exists then we are all done! */
496 if (sys_stat(name,&st) == 0)
501 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
503 /* a special case - if we don't have any mangling chars and are case
504 sensitive then searching won't help */
505 if (case_sensitive && !is_mangled(name) &&
506 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
509 /* now we need to recursively match the name against the real
510 directory structure */
513 while (strncmp(start,"./",2) == 0)
516 /* now match each part of the path name separately, trying the names
517 as is first, then trying to scan the directory for matching names */
518 for (;start;start = (end?end+1:(char *)NULL))
520 /* pinpoint the end of this section of the filename */
521 end = strchr(start, '/');
523 /* chop the name at this point */
526 if(saved_last_component != 0)
527 strcpy(saved_last_component, end ? end + 1 : start);
529 /* check if the name exists up to this point */
530 if (sys_stat(name, &st) == 0)
532 /* it exists. it must either be a directory or this must be
533 the last part of the path for it to be OK */
534 if (end && !(st.st_mode & S_IFDIR))
536 /* an intermediate part of the name isn't a directory */
537 DEBUG(5,("Not a dir %s\n",start));
548 /* remember the rest of the pathname so it can be restored
550 if (end) pstrcpy(rest,end+1);
552 /* try to find this part of the path in the directory */
553 if (strchr(start,'?') || strchr(start,'*') ||
554 !scan_directory(dirpath, start, cnum, end?True:False))
558 /* an intermediate part of the name can't be found */
559 DEBUG(5,("Intermediate not found %s\n",start));
561 /* We need to return the fact that the intermediate
562 name resolution failed. This is used to return an
563 error of ERRbadpath rather than ERRbadfile. Some
564 Windows applications depend on the difference between
571 /* just the last part of the name doesn't exist */
572 /* we may need to strupper() or strlower() it in case
573 this conversion is being used for file creation
575 /* if the filename is of mixed case then don't normalise it */
576 if (!case_preserve &&
577 (!strhasupper(start) || !strhaslower(start)))
580 /* check on the mangled stack to see if we can recover the
581 base of the filename */
582 if (is_mangled(start))
583 check_mangled_stack(start);
585 DEBUG(5,("New file %s\n",start));
589 /* restore the rest of the string */
592 strcpy(start+strlen(start)+1,rest);
593 end = start + strlen(start);
597 /* add to the dirpath that we have resolved so far */
598 if (*dirpath) strcat(dirpath,"/");
599 strcat(dirpath,start);
601 /* restore the / that we wiped out earlier */
605 /* the name has been resolved */
606 DEBUG(5,("conversion finished %s\n",name));
611 /****************************************************************************
612 normalise for DOS usage
613 ****************************************************************************/
614 static void disk_norm(int *bsize,int *dfree,int *dsize)
616 /* check if the disk is beyond the max disk size */
617 int maxdisksize = lp_maxdisksize();
619 /* convert to blocks - and don't overflow */
620 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
621 if (*dsize > maxdisksize) *dsize = maxdisksize;
622 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
627 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
632 if (*bsize > WORDMAX )
635 if (*dsize > WORDMAX)
637 if (*dfree > WORDMAX)
644 /****************************************************************************
645 return number of 1K blocks available on a path and total number
646 ****************************************************************************/
647 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
649 char *df_command = lp_dfree_command();
670 /* possibly use system() to get the result */
671 if (df_command && *df_command)
677 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
678 sprintf(syscmd,"%s %s",df_command,path);
679 standard_sub_basic(syscmd);
681 ret = smbrun(syscmd,outfile,False);
682 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
685 FILE *f = fopen(outfile,"r");
691 fscanf(f,"%d %d %d",dsize,dfree,bsize);
695 DEBUG(0,("Can't open %s\n",outfile));
699 disk_norm(bsize,dfree,dsize);
700 dfree_retval = ((*bsize)/1024)*(*dfree);
702 /* Ensure we return the min value between the users quota and
703 what's free on the disk. Thanks to Albrecht Gebhardt
704 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
706 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
708 disk_norm(&bsizeq, &dfreeq, &dsizeq);
709 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
710 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
711 dfree_retval : dfreeq_retval ;
712 /* maybe dfree and dfreeq are calculated using different bsizes
713 so convert dfree from bsize into bsizeq */
714 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
715 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
720 return(dfree_retval);
724 DEBUG(1,("Warning - no statfs function\n"));
728 if (statfs(path,&fs,sizeof(fs),0) != 0)
731 if (statvfs(path, &fs))
734 if (statfs(path,&fs,sizeof(fs)) == -1)
736 if (statfs(path,&fs) == -1)
738 #endif /* USE_STATVFS */
741 DEBUG(3,("dfree call failed code errno=%d\n",errno));
745 return(((*bsize)/1024)*(*dfree));
750 *dfree = fs.fd_req.bfree;
751 *dsize = fs.fd_req.btot;
754 *bsize = fs.f_frsize;
757 /* eg: osf1 has f_fsize = fundamental filesystem block size,
758 f_bsize = optimal transfer block size (MX: 94-04-19) */
763 #endif /* USE_STATVFS */
768 *dfree = fs.f_bavail;
770 *dsize = fs.f_blocks;
773 #if defined(SCO) || defined(ISC) || defined(MIPS)
777 /* handle rediculous bsize values - some OSes are broken */
778 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
780 disk_norm(bsize,dfree,dsize);
786 DEBUG(0,("dfree seems to be broken on your system\n"));
787 *dsize = 20*1024*1024/(*bsize);
788 *dfree = MAX(1,*dfree);
790 dfree_retval = ((*bsize)/1024)*(*dfree);
792 /* Ensure we return the min value between the users quota and
793 what's free on the disk. Thanks to Albrecht Gebhardt
794 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
796 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
798 disk_norm(&bsizeq, &dfreeq, &dsizeq);
799 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
800 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
801 dfree_retval : dfreeq_retval ;
802 /* maybe dfree and dfreeq are calculated using different bsizes
803 so convert dfree from bsize into bsizeq */
804 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
805 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
810 return(dfree_retval);
815 /****************************************************************************
816 wrap it to get filenames right
817 ****************************************************************************/
818 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
820 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
825 /****************************************************************************
826 check a filename - possibly caling reducename
828 This is called by every routine before it allows an operation on a filename.
829 It does any final confirmation necessary to ensure that the filename is
830 a valid one for the user to access.
831 ****************************************************************************/
832 BOOL check_name(char *name,int cnum)
838 if( IS_VETO_PATH(cnum, name))
840 DEBUG(5,("file path name %s vetoed\n",name));
844 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
846 /* Check if we are allowing users to follow symlinks */
847 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
848 University of Geneva */
850 if (!lp_symlinks(SNUM(cnum)))
853 if ( (sys_lstat(name,&statbuf) != -1) &&
854 (S_ISLNK(statbuf.st_mode)) )
856 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
862 DEBUG(5,("check_name on %s failed\n",name));
867 /****************************************************************************
868 check a filename - possibly caling reducename
869 ****************************************************************************/
870 static void check_for_pipe(char *fname)
872 /* special case of pipe opens */
876 if (strstr(s,"pipe/"))
878 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
879 unix_ERR_class = ERRSRV;
880 unix_ERR_code = ERRaccess;
884 /****************************************************************************
885 fd support routines - attempt to do a sys_open
886 ****************************************************************************/
887 static int fd_attempt_open(char *fname, int flags, int mode)
889 int fd = sys_open(fname,flags,mode);
891 /* Fix for files ending in '.' */
892 if((fd == -1) && (errno == ENOENT) &&
893 (strchr(fname,'.')==NULL))
896 fd = sys_open(fname,flags,mode);
899 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
900 if ((fd == -1) && (errno == ENAMETOOLONG))
903 char *p = strrchr(fname, '/');
905 if (p == fname) /* name is "/xxx" */
907 max_len = pathconf("/", _PC_NAME_MAX);
910 else if ((p == NULL) || (p == fname))
913 max_len = pathconf(".", _PC_NAME_MAX);
918 max_len = pathconf(fname, _PC_NAME_MAX);
922 if (strlen(p) > max_len)
924 char tmp = p[max_len];
927 if ((fd = sys_open(fname,flags,mode)) == -1)
935 /****************************************************************************
936 fd support routines - attempt to find an already open file by dev
937 and inode - increments the ref_count of the returned file_fd_struct *.
938 ****************************************************************************/
939 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
942 file_fd_struct *fd_ptr;
947 for(i = 0; i <= max_file_fd_used; i++) {
949 if((fd_ptr->ref_count > 0) &&
950 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
951 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
954 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
955 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
962 /****************************************************************************
963 fd support routines - attempt to find a empty slot in the FileFd array.
964 Increments the ref_count of the returned entry.
965 ****************************************************************************/
966 static file_fd_struct *fd_get_new()
969 file_fd_struct *fd_ptr;
971 for(i = 0; i < MAX_OPEN_FILES; i++) {
973 if(fd_ptr->ref_count == 0) {
974 fd_ptr->dev = (uint32)-1;
975 fd_ptr->inode = (uint32)-1;
977 fd_ptr->fd_readonly = -1;
978 fd_ptr->fd_writeonly = -1;
979 fd_ptr->real_open_flags = -1;
981 /* Increment max used counter if neccessary, cuts down
982 on search time when re-using */
983 if(i > max_file_fd_used)
984 max_file_fd_used = i;
985 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
986 i, fd_ptr->dev, fd_ptr->inode));
990 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
995 /****************************************************************************
996 fd support routines - attempt to re-open an already open fd as O_RDWR.
997 Save the already open fd (we cannot close due to POSIX file locking braindamage.
998 ****************************************************************************/
999 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1001 int fd = sys_open( fname, O_RDWR, mode);
1006 if(fd_ptr->real_open_flags == O_RDONLY)
1007 fd_ptr->fd_readonly = fd_ptr->fd;
1008 if(fd_ptr->real_open_flags == O_WRONLY)
1009 fd_ptr->fd_writeonly = fd_ptr->fd;
1012 fd_ptr->real_open_flags = O_RDWR;
1015 /****************************************************************************
1016 fd support routines - attempt to close the file referenced by this fd.
1017 Decrements the ref_count and returns it.
1018 ****************************************************************************/
1019 static int fd_attempt_close(file_fd_struct *fd_ptr)
1021 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1022 fd_ptr - &FileFd[0],
1023 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1024 fd_ptr->real_open_flags,
1025 fd_ptr->ref_count));
1026 if(fd_ptr->ref_count > 0) {
1027 fd_ptr->ref_count--;
1028 if(fd_ptr->ref_count == 0) {
1029 if(fd_ptr->fd != -1)
1031 if(fd_ptr->fd_readonly != -1)
1032 close(fd_ptr->fd_readonly);
1033 if(fd_ptr->fd_writeonly != -1)
1034 close(fd_ptr->fd_writeonly);
1036 fd_ptr->fd_readonly = -1;
1037 fd_ptr->fd_writeonly = -1;
1038 fd_ptr->real_open_flags = -1;
1039 fd_ptr->dev = (uint32)-1;
1040 fd_ptr->inode = (uint32)-1;
1043 return fd_ptr->ref_count;
1046 /****************************************************************************
1048 ****************************************************************************/
1049 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1051 extern struct current_user current_user;
1053 struct stat statbuf;
1054 file_fd_struct *fd_ptr;
1055 files_struct *fsp = &Files[fnum];
1059 fsp->granted_oplock = False;
1062 pstrcpy(fname,fname1);
1064 /* check permissions */
1065 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1067 DEBUG(3,("Permission denied opening %s\n",fname));
1068 check_for_pipe(fname);
1072 /* this handles a bug in Win95 - it doesn't say to create the file when it
1074 if (Connections[cnum].printer)
1078 if (flags == O_WRONLY)
1079 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1082 #if UTIME_WORKAROUND
1083 /* XXXX - is this OK?? */
1084 /* this works around a utime bug but can cause other problems */
1085 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1090 * Ensure we have a valid struct stat so we can search the
1094 if(stat(fname, &statbuf) < 0) {
1095 if(errno != ENOENT) {
1096 DEBUG(3,("Error doing stat on file %s (%s)\n",
1097 fname,strerror(errno)));
1099 check_for_pipe(fname);
1109 * Check to see if we have this file already
1110 * open. If we do, just use the already open fd and increment the
1111 * reference count (fd_get_already_open increments the ref_count).
1113 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1115 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1117 /* File was already open. */
1118 if((flags & O_CREAT) && (flags & O_EXCL)) {
1119 fd_ptr->ref_count--;
1125 * If not opened O_RDWR try
1126 * and do that here - a chmod may have been done
1127 * between the last open and now.
1129 if(fd_ptr->real_open_flags != O_RDWR)
1130 fd_attempt_reopen(fname, mode, fd_ptr);
1133 * Ensure that if we wanted write access
1134 * it has been opened for write, and if we wanted read it
1135 * was open for read.
1137 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1138 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1139 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1140 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1141 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1142 check_for_pipe(fname);
1143 fd_ptr->ref_count--;
1149 /* We need to allocate a new file_fd_struct (this increments the
1151 if((fd_ptr = fd_get_new()) == 0)
1154 * Whatever the requested flags, attempt read/write access,
1155 * as we don't know what flags future file opens may require.
1156 * If this fails, try again with the required flags.
1157 * Even if we open read/write when only read access was
1158 * requested the setting of the can_write flag in
1159 * the file_struct will protect us from errant
1160 * write requests. We never need to worry about O_APPEND
1161 * as this is not set anywhere in Samba.
1163 fd_ptr->real_open_flags = O_RDWR;
1164 /* Set the flags as needed without the read/write modes. */
1165 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1166 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1168 * On some systems opening a file for R/W access on a read only
1169 * filesystems sets errno to EROFS.
1172 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1173 #else /* No EROFS */
1174 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1176 if(flags & O_WRONLY) {
1177 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1178 fd_ptr->real_open_flags = O_WRONLY;
1180 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1181 fd_ptr->real_open_flags = O_RDONLY;
1186 if ((fd_ptr->fd >=0) &&
1187 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1191 pstrcpy(dname,fname);
1192 p = strrchr(dname,'/');
1194 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1195 lp_minprintspace(SNUM(cnum))) {
1196 fd_attempt_close(fd_ptr);
1198 if(fd_ptr->ref_count == 0)
1207 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1208 fname,strerror(errno),flags));
1209 /* Ensure the ref_count is decremented. */
1210 fd_attempt_close(fd_ptr);
1211 check_for_pipe(fname);
1215 if (fd_ptr->fd >= 0)
1219 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1220 /* Error - backout !! */
1221 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1222 fd_ptr->fd, fname,strerror(errno)));
1223 /* Ensure the ref_count is decremented. */
1224 fd_attempt_close(fd_ptr);
1229 /* Set the correct entries in fd_ptr. */
1230 fd_ptr->dev = (uint32)sbuf->st_dev;
1231 fd_ptr->inode = (uint32)sbuf->st_ino;
1233 fsp->fd_ptr = fd_ptr;
1234 Connections[cnum].num_files_open++;
1235 fsp->mode = sbuf->st_mode;
1236 GetTimeOfDay(&fsp->open_time);
1237 fsp->uid = current_user.id;
1241 fsp->mmap_ptr = NULL;
1243 fsp->can_lock = True;
1244 fsp->can_read = ((flags & O_WRONLY)==0);
1245 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1246 fsp->share_mode = 0;
1247 fsp->print_file = Connections[cnum].printer;
1248 fsp->modified = False;
1249 fsp->granted_oplock = False;
1251 string_set(&fsp->name,dos_to_unix(fname,False));
1252 fsp->wbmpx_ptr = NULL;
1255 * If the printer is marked as postscript output a leading
1256 * file identifier to ensure the file is treated as a raw
1258 * This has a similar effect as CtrlD=0 in WIN.INI file.
1259 * tim@fsg.com 09/06/94
1261 if (fsp->print_file && POSTSCRIPT(cnum) &&
1264 DEBUG(3,("Writing postscript line\n"));
1265 write_file(fnum,"%!\n",3);
1268 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1269 timestring(),Connections[cnum].user,fname,
1270 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1271 Connections[cnum].num_files_open,fnum));
1276 /* mmap it if read-only */
1277 if (!fsp->can_write)
1279 fsp->mmap_size = file_size(fname);
1280 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1281 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1283 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1285 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1286 fsp->mmap_ptr = NULL;
1292 /*******************************************************************
1294 ********************************************************************/
1295 void sync_file(int fnum)
1298 fsync(Files[fnum].fd_ptr->fd);
1302 /****************************************************************************
1303 run a file if it is a magic script
1304 ****************************************************************************/
1305 static void check_magic(int fnum,int cnum)
1307 if (!*lp_magicscript(SNUM(cnum)))
1310 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1314 if (!(p = strrchr(Files[fnum].name,'/')))
1315 p = Files[fnum].name;
1319 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1325 pstring magic_output;
1327 pstrcpy(fname,Files[fnum].name);
1329 if (*lp_magicoutput(SNUM(cnum)))
1330 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1332 sprintf(magic_output,"%s.out",fname);
1335 ret = smbrun(fname,magic_output,False);
1336 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1342 /****************************************************************************
1343 close a file - possibly invalidating the read prediction
1344 ****************************************************************************/
1345 void close_file(int fnum)
1347 files_struct *fs_p = &Files[fnum];
1348 int cnum = fs_p->cnum;
1349 uint32 dev = fs_p->fd_ptr->dev;
1350 uint32 inode = fs_p->fd_ptr->inode;
1351 share_lock_token token;
1353 invalidate_read_prediction(fs_p->fd_ptr->fd);
1355 Connections[cnum].num_files_open--;
1358 free((char *)fs_p->wbmpx_ptr);
1359 fs_p->wbmpx_ptr = NULL;
1365 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1366 fs_p->mmap_ptr = NULL;
1370 if (lp_share_modes(SNUM(cnum)))
1372 lock_share_entry( cnum, dev, inode, &token);
1373 del_share_mode(token, fnum);
1376 fd_attempt_close(fs_p->fd_ptr);
1378 if (lp_share_modes(SNUM(cnum)))
1379 unlock_share_entry( cnum, dev, inode, token);
1381 /* NT uses smbclose to start a print - weird */
1382 if (fs_p->print_file)
1385 /* check for magic scripts */
1386 check_magic(fnum,cnum);
1388 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1389 timestring(),Connections[cnum].user,fs_p->name,
1390 Connections[cnum].num_files_open));
1393 enum {AFAIL,AREAD,AWRITE,AALL};
1395 /*******************************************************************
1396 reproduce the share mode access table
1397 ********************************************************************/
1398 static int access_table(int new_deny,int old_deny,int old_mode,
1399 int share_pid,char *fname)
1401 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1403 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1405 if (old_deny == new_deny && share_pid == pid)
1408 if (old_mode == 0) return(AREAD);
1410 /* the new smbpub.zip spec says that if the file extension is
1411 .com, .dll, .exe or .sym then allow the open. I will force
1412 it to read-only as this seems sensible although the spec is
1413 a little unclear on this. */
1414 if ((fname = strrchr(fname,'.'))) {
1415 if (strequal(fname,".com") ||
1416 strequal(fname,".dll") ||
1417 strequal(fname,".exe") ||
1418 strequal(fname,".sym"))
1428 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1429 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1430 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1433 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1434 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1435 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1438 if (old_deny==DENY_WRITE) return(AREAD);
1439 if (old_deny==DENY_READ) return(AWRITE);
1440 if (old_deny==DENY_NONE) return(AALL);
1446 /*******************************************************************
1447 check if the share mode on a file allows it to be deleted or unlinked
1448 return True if sharing doesn't prevent the operation
1449 ********************************************************************/
1450 BOOL check_file_sharing(int cnum,char *fname)
1454 min_share_mode_entry *old_shares = 0;
1455 int num_share_modes;
1457 share_lock_token token;
1461 if(!lp_share_modes(SNUM(cnum)))
1464 if (stat(fname,&sbuf) == -1) return(True);
1466 dev = (uint32)sbuf.st_dev;
1467 inode = (uint32)sbuf.st_ino;
1469 lock_share_entry(cnum, dev, inode, &token);
1470 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1473 * Check if the share modes will give us access.
1476 if(num_share_modes != 0)
1483 broke_oplock = False;
1484 for(i = 0; i < num_share_modes; i++)
1486 min_share_mode_entry *share_entry = &old_shares[i];
1489 * Break oplocks before checking share modes. See comment in
1490 * open_file_shared for details.
1491 * Check if someone has an oplock on this file. If so we must
1492 * break it before continuing.
1494 if(share_entry->op_type & BATCH_OPLOCK)
1497 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1498 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1500 /* Oplock break.... */
1501 unlock_share_entry(cnum, dev, inode, token);
1502 if(request_oplock_break(share_entry, dev, inode) == False)
1504 free((char *)old_shares);
1505 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1506 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1509 lock_share_entry(cnum, dev, inode, &token);
1510 broke_oplock = True;
1514 /* someone else has a share lock on it, check to see
1516 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1523 free((char *)old_shares);
1524 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1526 } while(broke_oplock);
1529 /* XXXX exactly what share mode combinations should be allowed for
1530 deleting/renaming? */
1531 /* If we got here then either there were no share modes or
1532 all share modes were DENY_DOS and the pid == getpid() */
1537 unlock_share_entry(cnum, dev, inode, token);
1538 if(old_shares != NULL)
1539 free((char *)old_shares);
1543 /****************************************************************************
1545 Helper for open_file_shared.
1546 Truncate a file after checking locking; close file if locked.
1547 **************************************************************************/
1548 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1551 if (Files[fnum].can_write){
1552 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1553 /* If share modes are in force for this connection we
1554 have the share entry locked. Unlock it before closing. */
1555 if (*share_locked && lp_share_modes(SNUM(cnum)))
1556 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1557 Files[fnum].fd_ptr->inode, token);
1559 /* Share mode no longer locked. */
1560 *share_locked = False;
1562 unix_ERR_class = ERRDOS;
1563 unix_ERR_code = ERRlock;
1566 ftruncate(Files[fnum].fd_ptr->fd,0);
1570 /****************************************************************************
1571 check if we can open a file with a share mode
1572 ****************************************************************************/
1573 int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
1574 BOOL fcbopen, int *flags)
1576 int old_open_mode = share->share_mode &0xF;
1577 int old_deny_mode = (share->share_mode >>4)&7;
1579 if (old_deny_mode > 4 || old_open_mode > 2)
1581 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1582 deny_mode,old_deny_mode,old_open_mode,fname));
1587 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1590 if ((access_allowed == AFAIL) ||
1591 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1592 (access_allowed == AREAD && *flags == O_WRONLY) ||
1593 (access_allowed == AWRITE && *flags == O_RDONLY))
1595 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1596 deny_mode,old_deny_mode,old_open_mode,
1597 share->pid,fname, access_allowed));
1601 if (access_allowed == AREAD)
1604 if (access_allowed == AWRITE)
1611 /****************************************************************************
1612 open a file with a share mode
1613 ****************************************************************************/
1614 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1615 int mode,int oplock_request, int *Access,int *action)
1617 files_struct *fs_p = &Files[fnum];
1620 int deny_mode = (share_mode>>4)&7;
1622 BOOL file_existed = file_exist(fname,&sbuf);
1623 BOOL share_locked = False;
1624 BOOL fcbopen = False;
1625 share_lock_token token;
1628 int num_share_modes = 0;
1633 /* this is for OS/2 EAs - try and say we don't support them */
1634 if (strstr(fname,".+,;=[]."))
1636 unix_ERR_class = ERRDOS;
1637 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1639 unix_ERR_code = ERRcannotopen;
1640 #else /* OS2_WPS_FIX */
1641 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1642 #endif /* OS2_WPS_FIX */
1647 if ((ofun & 0x3) == 0 && file_existed)
1655 if ((ofun & 0x3) == 2)
1658 /* note that we ignore the append flag as
1659 append does not mean the same thing under dos and unix */
1661 switch (share_mode&0xF)
1678 if (flags != O_RDONLY && file_existed &&
1679 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1689 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1691 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1696 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1698 if (lp_share_modes(SNUM(cnum)))
1701 min_share_mode_entry *old_shares = 0;
1705 dev = (uint32)sbuf.st_dev;
1706 inode = (uint32)sbuf.st_ino;
1707 lock_share_entry(cnum, dev, inode, &token);
1708 share_locked = True;
1709 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1713 * Check if the share modes will give us access.
1716 if(share_locked && (num_share_modes != 0))
1723 broke_oplock = False;
1724 for(i = 0; i < num_share_modes; i++)
1726 min_share_mode_entry *share_entry = &old_shares[i];
1729 * By observation of NetBench, oplocks are broken *before* share
1730 * modes are checked. This allows a file to be closed by the client
1731 * if the share mode would deny access and the client has an oplock.
1732 * Check if someone has an oplock on this file. If so we must break
1733 * it before continuing.
1735 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1738 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1739 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1741 /* Oplock break.... */
1742 unlock_share_entry(cnum, dev, inode, token);
1743 if(request_oplock_break(share_entry, dev, inode) == False)
1745 free((char *)old_shares);
1746 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1747 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1749 unix_ERR_class = ERRDOS;
1750 unix_ERR_code = ERRbadshare;
1753 lock_share_entry(cnum, dev, inode, &token);
1754 broke_oplock = True;
1758 /* someone else has a share lock on it, check to see
1760 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1762 free((char *)old_shares);
1763 unlock_share_entry(cnum, dev, inode, token);
1765 unix_ERR_class = ERRDOS;
1766 unix_ERR_code = ERRbadshare;
1774 free((char *)old_shares);
1775 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1777 } while(broke_oplock);
1781 free((char *)old_shares);
1784 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1785 flags,flags2,mode));
1787 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1788 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1791 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1798 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1800 /* We created the file - thus we must now lock the share entry before creating it. */
1801 dev = fs_p->fd_ptr->dev;
1802 inode = fs_p->fd_ptr->inode;
1803 lock_share_entry(cnum, dev, inode, &token);
1804 share_locked = True;
1820 fs_p->share_mode = (deny_mode<<4) | open_mode;
1823 (*Access) = open_mode;
1827 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1828 if (!file_existed) *action = 2;
1829 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1831 /* We must create the share mode entry before truncate as
1832 truncate can fail due to locking and have to close the
1833 file (which expects the share_mode_entry to be there).
1835 if (lp_share_modes(SNUM(cnum)))
1838 /* JRA. Currently this only services Exlcusive and batch
1839 oplocks (no other opens on this file). This needs to
1840 be extended to level II oplocks (multiple reader
1843 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
1845 fs_p->granted_oplock = True;
1846 global_oplocks_open++;
1849 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1850 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1858 set_share_mode(token, fnum, port, oplock_request);
1861 if ((flags2&O_TRUNC) && file_existed)
1862 truncate_unless_locked(fnum,cnum,token,&share_locked);
1865 if (share_locked && lp_share_modes(SNUM(cnum)))
1866 unlock_share_entry( cnum, dev, inode, token);
1869 /****************************************************************************
1870 seek a file. Try to avoid the seek if possible
1871 ****************************************************************************/
1872 int seek_file(int fnum,uint32 pos)
1875 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1878 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1880 return(Files[fnum].pos);
1883 /****************************************************************************
1885 ****************************************************************************/
1886 int read_file(int fnum,char *data,uint32 pos,int n)
1890 if (!Files[fnum].can_write)
1892 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1900 if (Files[fnum].mmap_ptr)
1902 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1905 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1917 if (seek_file(fnum,pos) != pos)
1919 DEBUG(3,("Failed to seek to %d\n",pos));
1924 readret = read(Files[fnum].fd_ptr->fd,data,n);
1925 if (readret > 0) ret += readret;
1932 /****************************************************************************
1934 ****************************************************************************/
1935 int write_file(int fnum,char *data,int n)
1937 if (!Files[fnum].can_write) {
1942 if (!Files[fnum].modified) {
1944 Files[fnum].modified = True;
1945 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1946 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1947 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1948 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1953 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1957 /****************************************************************************
1958 load parameters specific to a connection/service
1959 ****************************************************************************/
1960 BOOL become_service(int cnum,BOOL do_chdir)
1962 extern char magic_char;
1963 static int last_cnum = -1;
1966 if (!OPEN_CNUM(cnum))
1972 Connections[cnum].lastused = smb_last_time;
1977 ChDir(Connections[cnum].connectpath) != 0 &&
1978 ChDir(Connections[cnum].origpath) != 0)
1980 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1981 Connections[cnum].connectpath,cnum));
1985 if (cnum == last_cnum)
1990 case_default = lp_defaultcase(snum);
1991 case_preserve = lp_preservecase(snum);
1992 short_case_preserve = lp_shortpreservecase(snum);
1993 case_mangle = lp_casemangle(snum);
1994 case_sensitive = lp_casesensitive(snum);
1995 magic_char = lp_magicchar(snum);
1996 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2001 /****************************************************************************
2002 find a service entry
2003 ****************************************************************************/
2004 int find_service(char *service)
2008 string_sub(service,"\\","/");
2010 iService = lp_servicenumber(service);
2012 /* now handle the special case of a home directory */
2015 char *phome_dir = get_home_dir(service);
2016 DEBUG(3,("checking for home directory %s gave %s\n",service,
2017 phome_dir?phome_dir:"(NULL)"));
2021 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2023 lp_add_home(service,iHomeService,phome_dir);
2024 iService = lp_servicenumber(service);
2029 /* If we still don't have a service, attempt to add it as a printer. */
2032 int iPrinterService;
2034 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2038 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2040 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2042 DEBUG(3,("%s is a valid printer name\n", service));
2043 DEBUG(3,("adding %s as a printer service\n", service));
2044 lp_add_printer(service,iPrinterService);
2045 iService = lp_servicenumber(service);
2047 DEBUG(0,("failed to add %s as a printer service!\n", service));
2050 DEBUG(3,("%s is not a valid printer name\n", service));
2054 /* just possibly it's a default service? */
2057 char *defservice = lp_defaultservice();
2058 if (defservice && *defservice && !strequal(defservice,service)) {
2059 iService = find_service(defservice);
2060 if (iService >= 0) {
2061 string_sub(service,"_","/");
2062 iService = lp_add_service(service,iService);
2068 if (!VALID_SNUM(iService))
2070 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2075 DEBUG(3,("find_service() failed to find service %s\n", service));
2081 /****************************************************************************
2082 create an error packet from a cached error.
2083 ****************************************************************************/
2084 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2086 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2088 int32 eclass = wbmpx->wr_errclass;
2089 int32 err = wbmpx->wr_error;
2091 /* We can now delete the auxiliary struct */
2092 free((char *)wbmpx);
2093 Files[fnum].wbmpx_ptr = NULL;
2094 return error_packet(inbuf,outbuf,eclass,err,line);
2103 } unix_smb_errmap[] =
2105 {EPERM,ERRDOS,ERRnoaccess},
2106 {EACCES,ERRDOS,ERRnoaccess},
2107 {ENOENT,ERRDOS,ERRbadfile},
2108 {ENOTDIR,ERRDOS,ERRbadpath},
2109 {EIO,ERRHRD,ERRgeneral},
2110 {EBADF,ERRSRV,ERRsrverror},
2111 {EINVAL,ERRSRV,ERRsrverror},
2112 {EEXIST,ERRDOS,ERRfilexists},
2113 {ENFILE,ERRDOS,ERRnofids},
2114 {EMFILE,ERRDOS,ERRnofids},
2115 {ENOSPC,ERRHRD,ERRdiskfull},
2117 {EDQUOT,ERRHRD,ERRdiskfull},
2120 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2123 {EXDEV,ERRDOS,ERRdiffdevice},
2125 {EROFS,ERRHRD,ERRnowrite},
2129 /****************************************************************************
2130 create an error packet from errno
2131 ****************************************************************************/
2132 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2134 int eclass=def_class;
2138 if (unix_ERR_class != SUCCESS)
2140 eclass = unix_ERR_class;
2141 ecode = unix_ERR_code;
2142 unix_ERR_class = SUCCESS;
2147 while (unix_smb_errmap[i].smbclass != 0)
2149 if (unix_smb_errmap[i].unixerror == errno)
2151 eclass = unix_smb_errmap[i].smbclass;
2152 ecode = unix_smb_errmap[i].smbcode;
2159 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2163 /****************************************************************************
2164 create an error packet. Normally called using the ERROR() macro
2165 ****************************************************************************/
2166 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2168 int outsize = set_message(outbuf,0,0,True);
2170 cmd = CVAL(inbuf,smb_com);
2172 CVAL(outbuf,smb_rcls) = error_class;
2173 SSVAL(outbuf,smb_err,error_code);
2175 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2178 (int)CVAL(inbuf,smb_com),
2179 smb_fn_name(CVAL(inbuf,smb_com)),
2184 DEBUG(3,("error string = %s\n",strerror(errno)));
2190 #ifndef SIGCLD_IGNORE
2191 /****************************************************************************
2192 this prevents zombie child processes
2193 ****************************************************************************/
2194 static int sig_cld()
2196 static int depth = 0;
2199 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2205 BlockSignals(True,SIGCLD);
2206 DEBUG(5,("got SIGCLD\n"));
2209 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2213 /* Stevens, Adv. Unix Prog. says that on system V you must call
2214 wait before reinstalling the signal handler, because the kernel
2215 calls the handler from within the signal-call when there is a
2216 child that has exited. This would lead to an infinite recursion
2217 if done vice versa. */
2219 #ifndef DONT_REINSTALL_SIG
2220 #ifdef SIGCLD_IGNORE
2221 signal(SIGCLD, SIG_IGN);
2223 signal(SIGCLD, SIGNAL_CAST sig_cld);
2228 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2231 BlockSignals(False,SIGCLD);
2236 /****************************************************************************
2237 this is called when the client exits abruptly
2238 **************************************************************************/
2239 static int sig_pipe()
2241 extern int password_client;
2242 BlockSignals(True,SIGPIPE);
2244 if (password_client != -1) {
2245 DEBUG(3,("lost connection to password server\n"));
2246 close(password_client);
2247 password_client = -1;
2248 #ifndef DONT_REINSTALL_SIG
2249 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2251 BlockSignals(False,SIGPIPE);
2255 exit_server("Got sigpipe\n");
2259 /****************************************************************************
2260 open the socket communication
2261 ****************************************************************************/
2262 static BOOL open_sockets(BOOL is_daemon,int port)
2269 struct sockaddr addr;
2270 int in_addrlen = sizeof(addr);
2273 #ifdef SIGCLD_IGNORE
2274 signal(SIGCLD, SIG_IGN);
2276 signal(SIGCLD, SIGNAL_CAST sig_cld);
2279 /* open an incoming socket */
2280 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2284 /* ready to listen */
2285 if (listen(s, 5) == -1)
2287 DEBUG(0,("listen: %s\n",strerror(errno)));
2295 /* now accept incoming connections - forking a new process
2296 for each incoming connection */
2297 DEBUG(2,("waiting for a connection\n"));
2300 Client = accept(s,&addr,&in_addrlen);
2302 if (Client == -1 && errno == EINTR)
2307 DEBUG(0,("accept: %s\n",strerror(errno)));
2311 #ifdef NO_FORK_DEBUG
2312 #ifndef NO_SIGNAL_TEST
2313 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2314 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2318 if (Client != -1 && fork()==0)
2320 /* Child code ... */
2321 #ifndef NO_SIGNAL_TEST
2322 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2323 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2325 /* close the listening socket */
2328 /* close our standard file descriptors */
2332 set_socket_options(Client,"SO_KEEPALIVE");
2333 set_socket_options(Client,user_socket_options);
2335 /* Reset global variables in util.c so that
2336 client substitutions will be done correctly
2339 reset_globals_after_fork();
2342 close(Client); /* The parent doesn't need this socket */
2348 /* We will abort gracefully when the client or remote system
2350 #ifndef NO_SIGNAL_TEST
2351 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2355 /* close our standard file descriptors */
2358 set_socket_options(Client,"SO_KEEPALIVE");
2359 set_socket_options(Client,user_socket_options);
2365 /****************************************************************************
2366 process an smb from the client - split out from the process() code so
2367 it can be used by the oplock break code.
2368 ****************************************************************************/
2370 static void process_smb(char *inbuf, char *outbuf)
2373 static int trans_num;
2374 int msg_type = CVAL(inbuf,0);
2375 int32 len = smb_len(inbuf);
2376 int nread = len + 4;
2378 if (trans_num == 0) {
2379 /* on the first packet, check the global hosts allow/ hosts
2380 deny parameters before doing any parsing of the packet
2381 passed to us by the client. This prevents attacks on our
2382 parsing code from hosts not in the hosts allow list */
2383 if (!check_access(-1)) {
2384 /* send a negative session response "not listining on calling
2386 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2387 DEBUG(1,("%s Connection denied from %s\n",
2388 timestring(),client_addr()));
2389 send_smb(Client,(char *)buf);
2390 exit_server("connection denied");
2394 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2395 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2398 if(trans_num == 1 && VT_Check(inbuf))
2408 nread = construct_reply(inbuf,outbuf,nread,max_send);
2412 if (CVAL(outbuf,0) == 0)
2415 if (nread != smb_len(outbuf) + 4)
2417 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2418 nread, smb_len(outbuf)));
2421 send_smb(Client,outbuf);
2426 /****************************************************************************
2427 open the oplock IPC socket communication
2428 ****************************************************************************/
2429 static BOOL open_oplock_ipc()
2431 struct sockaddr_in sock_name;
2432 int len = sizeof(sock_name);
2434 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2436 /* Open a lookback UDP socket on a random port. */
2437 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2438 if (oplock_sock == -1)
2440 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2441 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2446 /* Find out the transient UDP port we have been allocated. */
2447 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2449 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2456 oplock_port = ntohs(sock_name.sin_port);
2458 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2459 getpid(), oplock_port));
2464 /****************************************************************************
2465 process an oplock break message.
2466 ****************************************************************************/
2467 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2473 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2474 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2476 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2478 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2479 msg_len, from_port));
2481 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2482 only valid request. */
2484 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2486 case OPLOCK_BREAK_CMD:
2487 /* Ensure that the msg length is correct. */
2488 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2490 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2491 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2495 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2496 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2497 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2498 struct timeval tval;
2499 struct sockaddr_in toaddr;
2501 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2502 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2504 DEBUG(5,("process_local_message: oplock break request from \
2505 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2508 * If we have no record of any currently open oplocks,
2509 * it's not an error, as a close command may have
2510 * just been issued on the file that was oplocked.
2511 * Just return success in this case.
2514 if(global_oplocks_open != 0)
2516 if(oplock_break(dev, inode, &tval) == False)
2518 DEBUG(0,("process_local_message: oplock break failed - \
2519 not returning udp message.\n"));
2525 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2526 oplocks. Returning success.\n"));
2529 /* Send the message back after OR'ing in the 'REPLY' bit. */
2530 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2532 bzero((char *)&toaddr,sizeof(toaddr));
2533 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2534 toaddr.sin_port = htons(from_port);
2535 toaddr.sin_family = AF_INET;
2537 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2538 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2540 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2541 remotepid, strerror(errno)));
2545 DEBUG(5,("process_local_message: oplock break reply sent to \
2546 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2547 from_port, dev, inode));
2552 * Keep this as a debug case - eventually we can remove it.
2555 DEBUG(0,("process_local_message: Received unsolicited break \
2556 reply - dumping info.\n"));
2558 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2560 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2561 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2566 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2567 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2568 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2570 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2571 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2577 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2578 (unsigned int)SVAL(msg_start,0)));
2584 /****************************************************************************
2585 Process an oplock break directly.
2586 ****************************************************************************/
2587 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2590 static char *inbuf = NULL;
2591 static char *outbuf = NULL;
2592 files_struct *fsp = NULL;
2595 BOOL shutdown_server = False;
2597 DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \
2598 global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
2602 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2604 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2607 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2608 if(outbuf == NULL) {
2609 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2616 /* We need to search the file open table for the
2617 entry containing this dev and inode, and ensure
2618 we have an oplock on it. */
2619 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2624 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2625 (fsp->open_time.tv_sec == tval->tv_sec) &&
2626 (fsp->open_time.tv_usec == tval->tv_usec))
2633 /* The file could have been closed in the meantime - return success. */
2634 DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2635 allowing break to succeed.\n", dev, inode, fnum));
2639 /* Ensure we have an oplock on the file */
2641 /* There is a potential race condition in that an oplock could
2642 have been broken due to another udp request, and yet there are
2643 still oplock break messages being sent in the udp message
2644 queue for this file. So return true if we don't have an oplock,
2645 as we may have just freed it.
2648 if(!fsp->granted_oplock)
2650 DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2651 Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode));
2655 /* Now comes the horrid part. We must send an oplock break to the client,
2656 and then process incoming messages until we get a close or oplock release.
2659 /* Prepare the SMBlockingX message. */
2660 bzero(outbuf,smb_size);
2661 set_message(outbuf,8,0,True);
2663 SCVAL(outbuf,smb_com,SMBlockingX);
2664 SSVAL(outbuf,smb_tid,fsp->cnum);
2665 SSVAL(outbuf,smb_pid,0xFFFF);
2666 SSVAL(outbuf,smb_uid,0);
2667 SSVAL(outbuf,smb_mid,0xFFFF);
2668 SCVAL(outbuf,smb_vwv0,0xFF);
2669 SSVAL(outbuf,smb_vwv2,fnum);
2670 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2671 /* Change this when we have level II oplocks. */
2672 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2674 send_smb(Client, outbuf);
2676 global_oplock_break = True;
2678 /* Process incoming messages. */
2680 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2681 seconds we should just die.... */
2683 start_time = time(NULL);
2685 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2687 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2690 * Die if we got an error.
2693 if (smb_read_error == READ_EOF)
2694 DEBUG(0,("oplock_break: end of file from client\n"));
2696 if (smb_read_error == READ_ERROR)
2697 DEBUG(0,("oplock_break: receive_smb error (%s)\n",
2700 if (smb_read_error == READ_TIMEOUT)
2701 DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n",
2702 OPLOCK_BREAK_TIMEOUT));
2704 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2705 inode = %x).\n", fsp->name, fnum, dev, inode));
2706 shutdown_server = True;
2709 process_smb(inbuf, outbuf);
2711 /* We only need this in case a readraw crossed on the wire. */
2712 if(global_oplock_break)
2713 global_oplock_break = False;
2716 * Die if we go over the time limit.
2719 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2721 DEBUG(0,("oplock_break: no break received from client within \
2722 %d seconds.\n", OPLOCK_BREAK_TIMEOUT));
2723 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2724 inode = %x).\n", fsp->name, fnum, dev, inode));
2725 shutdown_server = True;
2731 * If the client did not respond we must die.
2736 DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n"));
2739 exit_server("oplock break failure");
2744 /* The lockingX reply will have removed the oplock flag
2745 from the sharemode. */
2747 fsp->granted_oplock = False;
2750 global_oplocks_open--;
2752 /* Santity check - remove this later. JRA */
2753 if(global_oplocks_open < 0)
2755 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2756 global_oplocks_open));
2760 DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2761 global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open));
2766 /****************************************************************************
2767 Send an oplock break message to another smbd process. If the oplock is held
2768 by the local smbd then call the oplock break function directly.
2769 ****************************************************************************/
2771 BOOL request_oplock_break(min_share_mode_entry *share_entry,
2772 uint32 dev, uint32 inode)
2774 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2775 struct sockaddr_in addr_out;
2778 if(pid == share_entry->pid)
2780 /* We are breaking our own oplock, make sure it's us. */
2781 if(share_entry->op_port != oplock_port)
2783 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2784 should be %d\n", pid, share_entry->op_port, oplock_port));
2788 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2790 /* Call oplock break direct. */
2791 return oplock_break(dev, inode, &share_entry->time);
2794 /* We need to send a OPLOCK_BREAK_CMD message to the
2795 port in the share mode entry. */
2797 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2798 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2799 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2800 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2801 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2802 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2804 /* set the address and port */
2805 bzero((char *)&addr_out,sizeof(addr_out));
2806 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2807 addr_out.sin_port = htons( share_entry->op_port );
2808 addr_out.sin_family = AF_INET;
2810 DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \
2811 for dev = %x, inode = %x\n", share_entry->pid, share_entry->op_port, dev, inode));
2813 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2814 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2816 DEBUG(0,("request_oplock_break: failed when sending a oplock break message \
2817 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2818 share_entry->pid, share_entry->op_port, dev, inode,
2824 * Now we must await the oplock broken message coming back
2825 * from the target smbd process. Timeout if it fails to
2826 * return in OPLOCK_BREAK_TIMEOUT seconds.
2827 * While we get messages that aren't ours, loop.
2832 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
2833 int32 reply_msg_len;
2834 int16 reply_from_port;
2835 char *reply_msg_start;
2837 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
2838 OPLOCK_BREAK_TIMEOUT * 1000) == False)
2840 if(smb_read_error == READ_TIMEOUT)
2841 DEBUG(0,("request_oplock_break: no response received to oplock break request to \
2842 pid %d on port %d for dev = %x, inode = %x\n", share_entry->pid,
2843 share_entry->op_port, dev, inode));
2845 DEBUG(0,("request_oplock_break: error in response received to oplock break request to \
2846 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry->pid,
2847 share_entry->op_port, dev, inode, strerror(errno)));
2852 * If the response we got was not an answer to our message, but
2853 * was a completely different request, push it onto the pending
2854 * udp message stack so that we can deal with it in the main loop.
2855 * It may be another oplock break request to us.
2859 * Local note from JRA. There exists the possibility of a denial
2860 * of service attack here by allowing non-root processes running
2861 * on a local machine sending many of these pending messages to
2862 * a smbd port. Currently I'm not sure how to restrict the messages
2863 * I will queue (although I could add a limit to the queue) to
2864 * those received by root processes only. There should be a
2865 * way to make this bulletproof....
2868 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
2869 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
2871 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
2873 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
2876 DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n"));
2880 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
2881 (reply_from_port != share_entry->op_port) ||
2882 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
2883 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
2884 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
2886 DEBUG(3,("request_oplock_break: received other message whilst awaiting \
2887 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
2888 share_entry->pid, share_entry->op_port, dev, inode));
2889 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
2897 DEBUG(3,("request_oplock_break: broke oplock.\n"));
2902 /****************************************************************************
2903 check if a snum is in use
2904 ****************************************************************************/
2905 BOOL snum_used(int snum)
2908 for (i=0;i<MAX_CONNECTIONS;i++)
2909 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2914 /****************************************************************************
2915 reload the services file
2916 **************************************************************************/
2917 BOOL reload_services(BOOL test)
2924 pstrcpy(fname,lp_configfile());
2925 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2927 pstrcpy(servicesf,fname);
2934 if (test && !lp_file_list_changed())
2937 lp_killunused(snum_used);
2939 ret = lp_load(servicesf,False);
2941 /* perhaps the config filename is now set */
2943 reload_services(True);
2952 set_socket_options(Client,"SO_KEEPALIVE");
2953 set_socket_options(Client,user_socket_options);
2957 create_mangled_stack(lp_mangledstack());
2959 /* this forces service parameters to be flushed */
2960 become_service(-1,True);
2967 /****************************************************************************
2968 this prevents zombie child processes
2969 ****************************************************************************/
2970 static int sig_hup()
2972 BlockSignals(True,SIGHUP);
2973 DEBUG(0,("Got SIGHUP\n"));
2974 reload_services(False);
2975 #ifndef DONT_REINSTALL_SIG
2976 signal(SIGHUP,SIGNAL_CAST sig_hup);
2978 BlockSignals(False,SIGHUP);
2982 /****************************************************************************
2983 Setup the groups a user belongs to.
2984 ****************************************************************************/
2985 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2986 int **p_igroups, gid_t **p_groups)
2988 if (-1 == initgroups(user,gid))
2992 DEBUG(0,("Unable to initgroups!\n"));
2993 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2994 DEBUG(0,("This is probably a problem with the account %s\n",user));
3002 ngroups = getgroups(0,&grp);
3005 igroups = (int *)malloc(sizeof(int)*ngroups);
3006 for (i=0;i<ngroups;i++)
3007 igroups[i] = 0x42424242;
3008 ngroups = getgroups(ngroups,(gid_t *)igroups);
3010 if (igroups[0] == 0x42424242)
3013 *p_ngroups = ngroups;
3015 /* The following bit of code is very strange. It is due to the
3016 fact that some OSes use int* and some use gid_t* for
3017 getgroups, and some (like SunOS) use both, one in prototypes,
3018 and one in man pages and the actual code. Thus we detect it
3019 dynamically using some very ugly code */
3022 /* does getgroups return ints or gid_t ?? */
3023 static BOOL groups_use_ints = True;
3025 if (groups_use_ints &&
3027 SVAL(igroups,2) == 0x4242)
3028 groups_use_ints = False;
3030 for (i=0;groups_use_ints && i<ngroups;i++)
3031 if (igroups[i] == 0x42424242)
3032 groups_use_ints = False;
3034 if (groups_use_ints)
3036 *p_igroups = igroups;
3037 *p_groups = (gid_t *)igroups;
3041 gid_t *groups = (gid_t *)igroups;
3042 igroups = (int *)malloc(sizeof(int)*ngroups);
3043 for (i=0;i<ngroups;i++)
3044 igroups[i] = groups[i];
3045 *p_igroups = igroups;
3046 *p_groups = (gid_t *)groups;
3049 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3050 for (i=0;i<ngroups;i++)
3051 DEBUG(3,("%d ",igroups[i]));
3057 /****************************************************************************
3058 make a connection to a service
3059 ****************************************************************************/
3060 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3064 struct passwd *pass = NULL;
3065 connection_struct *pcon;
3068 static BOOL first_connection = True;
3072 snum = find_service(service);
3075 if (strequal(service,"IPC$"))
3077 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3081 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3085 if (strequal(service,HOMES_NAME))
3087 if (*user && Get_Pwnam(user,True))
3088 return(make_connection(user,user,password,pwlen,dev,vuid));
3090 if (validated_username(vuid))
3092 strcpy(user,validated_username(vuid));
3093 return(make_connection(user,user,password,pwlen,dev,vuid));
3097 if (!lp_snum_ok(snum) || !check_access(snum)) {
3101 /* you can only connect to the IPC$ service as an ipc device */
3102 if (strequal(service,"IPC$"))
3105 if (*dev == '?' || !*dev)
3107 if (lp_print_ok(snum))
3108 strcpy(dev,"LPT1:");
3113 /* if the request is as a printer and you can't print then refuse */
3115 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3116 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3120 /* lowercase the user name */
3123 /* add it as a possible user name */
3124 add_session_user(service);
3126 /* shall we let them in? */
3127 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3129 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3133 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3136 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3140 pcon = &Connections[cnum];
3141 bzero((char *)pcon,sizeof(*pcon));
3143 /* find out some info about the user */
3144 pass = Get_Pwnam(user,True);
3148 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3152 pcon->read_only = lp_readonly(snum);
3156 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3157 string_sub(list,"%S",service);
3159 if (user_in_list(user,list))
3160 pcon->read_only = True;
3162 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3163 string_sub(list,"%S",service);
3165 if (user_in_list(user,list))
3166 pcon->read_only = False;
3169 /* admin user check */
3171 /* JRA - original code denied admin user if the share was
3172 marked read_only. Changed as I don't think this is needed,
3173 but old code left in case there is a problem here.
3175 if (user_in_list(user,lp_admin_users(snum))
3177 && !pcon->read_only)
3182 pcon->admin_user = True;
3183 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3186 pcon->admin_user = False;
3188 pcon->force_user = force;
3190 pcon->uid = pass->pw_uid;
3191 pcon->gid = pass->pw_gid;
3192 pcon->num_files_open = 0;
3193 pcon->lastused = time(NULL);
3194 pcon->service = snum;
3196 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3197 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3198 pcon->dirptr = NULL;
3199 pcon->veto_list = NULL;
3200 pcon->hide_list = NULL;
3201 string_set(&pcon->dirpath,"");
3202 string_set(&pcon->user,user);
3205 if (*lp_force_group(snum))
3210 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3211 /* default service may be a group name */
3212 string_sub(gname,"%S",service);
3213 gptr = (struct group *)getgrnam(gname);
3217 pcon->gid = gptr->gr_gid;
3218 DEBUG(3,("Forced group %s\n",gname));
3221 DEBUG(1,("Couldn't find group %s\n",gname));
3225 if (*lp_force_user(snum))
3227 struct passwd *pass2;
3229 fstrcpy(fuser,lp_force_user(snum));
3230 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3233 pcon->uid = pass2->pw_uid;
3234 string_set(&pcon->user,fuser);
3235 fstrcpy(user,fuser);
3236 pcon->force_user = True;
3237 DEBUG(3,("Forced user %s\n",fuser));
3240 DEBUG(1,("Couldn't find user %s\n",fuser));
3245 pstrcpy(s,lp_pathname(snum));
3246 standard_sub(cnum,s);
3247 string_set(&pcon->connectpath,s);
3248 DEBUG(3,("Connect path is %s\n",s));
3251 /* groups stuff added by ih */
3253 pcon->groups = NULL;
3257 /* Find all the groups this uid is in and store them. Used by become_user() */
3258 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
3260 /* check number of connections */
3261 if (!claim_connection(cnum,
3262 lp_servicename(SNUM(cnum)),
3263 lp_max_connections(SNUM(cnum)),False))
3265 DEBUG(1,("too many connections - rejected\n"));
3269 if (lp_status(SNUM(cnum)))
3270 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3272 first_connection = False;
3277 /* execute any "root preexec = " line */
3278 if (*lp_rootpreexec(SNUM(cnum)))
3281 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3282 standard_sub(cnum,cmd);
3283 DEBUG(5,("cmd=%s\n",cmd));
3284 smbrun(cmd,NULL,False);
3287 if (!become_user(cnum,pcon->vuid))
3289 DEBUG(0,("Can't become connected user!\n"));
3291 if (!IS_IPC(cnum)) {
3292 yield_connection(cnum,
3293 lp_servicename(SNUM(cnum)),
3294 lp_max_connections(SNUM(cnum)));
3295 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3300 if (ChDir(pcon->connectpath) != 0)
3302 DEBUG(0,("Can't change directory to %s (%s)\n",
3303 pcon->connectpath,strerror(errno)));
3306 if (!IS_IPC(cnum)) {
3307 yield_connection(cnum,
3308 lp_servicename(SNUM(cnum)),
3309 lp_max_connections(SNUM(cnum)));
3310 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3315 string_set(&pcon->origpath,pcon->connectpath);
3317 #if SOFTLINK_OPTIMISATION
3318 /* resolve any soft links early */
3321 pstrcpy(s,pcon->connectpath);
3323 string_set(&pcon->connectpath,s);
3324 ChDir(pcon->connectpath);
3328 num_connections_open++;
3329 add_session_user(user);
3331 /* execute any "preexec = " line */
3332 if (*lp_preexec(SNUM(cnum)))
3335 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3336 standard_sub(cnum,cmd);
3337 smbrun(cmd,NULL,False);
3340 /* we've finished with the sensitive stuff */
3343 /* Add veto/hide lists */
3344 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3346 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3347 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3351 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3355 lp_servicename(SNUM(cnum)),user,
3365 /****************************************************************************
3366 find first available file slot
3367 ****************************************************************************/
3368 int find_free_file(void )
3371 /* we start at 1 here for an obscure reason I can't now remember,
3372 but I think is important :-) */
3373 for (i=1;i<MAX_OPEN_FILES;i++)
3376 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3380 /****************************************************************************
3381 find first available connection slot, starting from a random position.
3382 The randomisation stops problems with the server dieing and clients
3383 thinking the server is still available.
3384 ****************************************************************************/
3385 static int find_free_connection(int hash )
3389 hash = (hash % (MAX_CONNECTIONS-2))+1;
3393 for (i=hash+1;i!=hash;)
3395 if (!Connections[i].open && Connections[i].used == used)
3397 DEBUG(3,("found free connection number %d\n",i));
3401 if (i == MAX_CONNECTIONS)
3411 DEBUG(1,("ERROR! Out of connection structures\n"));
3416 /****************************************************************************
3417 reply for the core protocol
3418 ****************************************************************************/
3419 int reply_corep(char *outbuf)
3421 int outsize = set_message(outbuf,1,0,True);
3423 Protocol = PROTOCOL_CORE;
3429 /****************************************************************************
3430 reply for the coreplus protocol
3431 ****************************************************************************/
3432 int reply_coreplus(char *outbuf)
3434 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3435 int outsize = set_message(outbuf,13,0,True);
3436 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3437 readbraw and writebraw (possibly) */
3438 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3439 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3441 Protocol = PROTOCOL_COREPLUS;
3447 /****************************************************************************
3448 reply for the lanman 1.0 protocol
3449 ****************************************************************************/
3450 int reply_lanman1(char *outbuf)
3452 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3454 BOOL doencrypt = SMBENCRYPT();
3455 time_t t = time(NULL);
3456 /* We need to save and restore this as it can be destroyed
3457 if we call another server if security=server
3458 Thanks to Paul Nelson @ Thursby for pointing this out.
3460 uint16 mid = SVAL(outbuf, smb_mid);
3462 if (lp_security()>=SEC_USER) secword |= 1;
3463 if (doencrypt) secword |= 2;
3465 set_message(outbuf,13,doencrypt?8:0,True);
3466 SSVAL(outbuf,smb_vwv1,secword);
3467 /* Create a token value and add it to the outgoing packet. */
3469 generate_next_challenge(smb_buf(outbuf));
3471 Protocol = PROTOCOL_LANMAN1;
3473 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3474 DEBUG(3,("using password server validation\n"));
3475 if (doencrypt) set_challenge(smb_buf(outbuf));
3478 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3479 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3480 SSVAL(outbuf,smb_vwv2,max_recv);
3481 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3482 SSVAL(outbuf,smb_vwv4,1);
3483 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3484 readbraw writebraw (possibly) */
3485 SIVAL(outbuf,smb_vwv6,getpid());
3486 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3488 put_dos_date(outbuf,smb_vwv8,t);
3490 return (smb_len(outbuf)+4);
3494 /****************************************************************************
3495 reply for the lanman 2.0 protocol
3496 ****************************************************************************/
3497 int reply_lanman2(char *outbuf)
3499 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3501 BOOL doencrypt = SMBENCRYPT();
3502 time_t t = time(NULL);
3503 /* We need to save and restore this as it can be destroyed
3504 if we call another server if security=server
3505 Thanks to Paul Nelson @ Thursby for pointing this out.
3507 uint16 mid = SVAL(outbuf, smb_mid);
3509 if (lp_security()>=SEC_USER) secword |= 1;
3510 if (doencrypt) secword |= 2;
3512 set_message(outbuf,13,doencrypt?8:0,True);
3513 SSVAL(outbuf,smb_vwv1,secword);
3514 /* Create a token value and add it to the outgoing packet. */
3516 generate_next_challenge(smb_buf(outbuf));
3518 SIVAL(outbuf,smb_vwv6,getpid());
3520 Protocol = PROTOCOL_LANMAN2;
3522 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3523 DEBUG(3,("using password server validation\n"));
3524 if (doencrypt) set_challenge(smb_buf(outbuf));
3527 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3528 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3529 SSVAL(outbuf,smb_vwv2,max_recv);
3530 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3531 SSVAL(outbuf,smb_vwv4,1);
3532 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3533 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3534 put_dos_date(outbuf,smb_vwv8,t);
3536 return (smb_len(outbuf)+4);
3540 /****************************************************************************
3541 reply for the nt protocol
3542 ****************************************************************************/
3543 int reply_nt1(char *outbuf)
3545 /* dual names + lock_and_read + nt SMBs + remote API calls */
3546 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3548 other valid capabilities which we may support at some time...
3549 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3550 CAP_LARGE_FILES|CAP_LARGE_READX|
3551 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3555 BOOL doencrypt = SMBENCRYPT();
3556 time_t t = time(NULL);
3559 char challenge_len = 8;
3560 /* We need to save and restore this as it can be destroyed
3561 if we call another server if security=server
3562 Thanks to Paul Nelson @ Thursby for pointing this out.
3564 uint16 mid = SVAL(outbuf, smb_mid);
3566 if (lp_readraw() && lp_writeraw())
3568 capabilities |= CAP_RAW_MODE;
3571 if (lp_security()>=SEC_USER) secword |= 1;
3572 if (doencrypt) secword |= 2;
3574 /* decide where (if) to put the encryption challenge, and
3575 follow it with the OEM'd domain name
3577 encrypt_len = doencrypt?challenge_len:0;
3579 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3581 data_len = encrypt_len + strlen(myworkgroup) + 1;
3584 set_message(outbuf,17,data_len,True);
3587 /* put the OEM'd domain name */
3588 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3590 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3593 CVAL(outbuf,smb_vwv1) = secword;
3594 /* Create a token value and add it to the outgoing packet. */
3597 generate_next_challenge(smb_buf(outbuf));
3599 /* Tell the nt machine how long the challenge is. */
3600 SSVALS(outbuf,smb_vwv16+1,challenge_len);
3603 Protocol = PROTOCOL_NT1;
3605 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3606 DEBUG(3,("using password server validation\n"));
3607 if (doencrypt) set_challenge(smb_buf(outbuf));
3610 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3611 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3612 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3613 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3614 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3615 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3616 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3617 put_long_date(outbuf+smb_vwv11+1,t);
3618 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3619 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3621 return (smb_len(outbuf)+4);
3624 /* these are the protocol lists used for auto architecture detection:
3627 protocol [PC NETWORK PROGRAM 1.0]
3628 protocol [XENIX CORE]
3629 protocol [MICROSOFT NETWORKS 1.03]
3630 protocol [LANMAN1.0]
3631 protocol [Windows for Workgroups 3.1a]
3632 protocol [LM1.2X002]
3633 protocol [LANMAN2.1]
3634 protocol [NT LM 0.12]
3637 protocol [PC NETWORK PROGRAM 1.0]
3638 protocol [XENIX CORE]
3639 protocol [MICROSOFT NETWORKS 1.03]
3640 protocol [LANMAN1.0]
3641 protocol [Windows for Workgroups 3.1a]
3642 protocol [LM1.2X002]
3643 protocol [LANMAN2.1]
3644 protocol [NT LM 0.12]
3647 protocol [PC NETWORK PROGRAM 1.0]
3648 protocol [XENIX CORE]
3649 protocol [LANMAN1.0]
3650 protocol [LM1.2X002]
3651 protocol [LANMAN2.1]
3655 * Modified to recognize the architecture of the remote machine better.
3657 * This appears to be the matrix of which protocol is used by which
3659 Protocol WfWg Win95 WinNT OS/2
3660 PC NETWORK PROGRAM 1.0 1 1 1 1
3662 MICROSOFT NETWORKS 3.0 2 2
3664 MICROSOFT NETWORKS 1.03 3
3667 Windows for Workgroups 3.1a 5 5 5
3672 * tim@fsg.com 09/29/95
3675 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3676 #define ARCH_WIN95 0x2
3677 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3678 #define ARCH_WINNT 0x8
3679 #define ARCH_SAMBA 0x10
3681 #define ARCH_ALL 0x1F
3683 /* List of supported protocols, most desired first */
3687 int (*proto_reply_fn)(char *);
3689 } supported_protocols[] = {
3690 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3691 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3692 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3693 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3694 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3695 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3696 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3697 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3698 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3703 /****************************************************************************
3705 ****************************************************************************/
3706 static int reply_negprot(char *inbuf,char *outbuf)
3708 int outsize = set_message(outbuf,1,0,True);
3713 int bcc = SVAL(smb_buf(inbuf),-2);
3714 int arch = ARCH_ALL;
3716 p = smb_buf(inbuf)+1;
3717 while (p < (smb_buf(inbuf) + bcc))
3720 DEBUG(3,("Requested protocol [%s]\n",p));
3721 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3722 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3723 else if (strcsequal(p,"DOS LM1.2X002"))
3724 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3725 else if (strcsequal(p,"DOS LANMAN2.1"))
3726 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3727 else if (strcsequal(p,"NT LM 0.12"))
3728 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3729 else if (strcsequal(p,"LANMAN2.1"))
3730 arch &= ( ARCH_WINNT | ARCH_OS2 );
3731 else if (strcsequal(p,"LM1.2X002"))
3732 arch &= ( ARCH_WINNT | ARCH_OS2 );
3733 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3735 else if (strcsequal(p,"XENIX CORE"))
3736 arch &= ( ARCH_WINNT | ARCH_OS2 );
3737 else if (strcsequal(p,"Samba")) {
3747 set_remote_arch(RA_SAMBA);
3750 set_remote_arch(RA_WFWG);
3753 set_remote_arch(RA_WIN95);
3756 set_remote_arch(RA_WINNT);
3759 set_remote_arch(RA_OS2);
3762 set_remote_arch(RA_UNKNOWN);
3766 /* possibly reload - change of architecture */
3767 reload_services(True);
3769 /* a special case to stop password server loops */
3770 if (Index == 1 && strequal(remote_machine,myhostname) &&
3771 lp_security()==SEC_SERVER)
3772 exit_server("Password server loop!");
3774 /* Check for protocols, most desirable first */
3775 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3777 p = smb_buf(inbuf)+1;
3779 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3780 while (p < (smb_buf(inbuf) + bcc))
3782 if (strequal(p,supported_protocols[protocol].proto_name))
3791 SSVAL(outbuf,smb_vwv0,choice);
3793 extern fstring remote_proto;
3794 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3795 reload_services(True);
3796 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3797 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3800 DEBUG(0,("No protocol supported !\n"));
3802 SSVAL(outbuf,smb_vwv0,choice);
3804 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3810 /****************************************************************************
3811 close all open files for a connection
3812 ****************************************************************************/
3813 static void close_open_files(int cnum)
3816 for (i=0;i<MAX_OPEN_FILES;i++)
3817 if( Files[i].cnum == cnum && Files[i].open) {
3824 /****************************************************************************
3826 ****************************************************************************/
3827 void close_cnum(int cnum, uint16 vuid)
3829 DirCacheFlush(SNUM(cnum));
3833 if (!OPEN_CNUM(cnum))
3835 DEBUG(0,("Can't close cnum %d\n",cnum));
3839 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3841 remote_machine,client_addr(),
3842 lp_servicename(SNUM(cnum))));
3844 yield_connection(cnum,
3845 lp_servicename(SNUM(cnum)),
3846 lp_max_connections(SNUM(cnum)));
3848 if (lp_status(SNUM(cnum)))
3849 yield_connection(cnum,"STATUS.",MAXSTATUS);
3851 close_open_files(cnum);
3852 dptr_closecnum(cnum);
3854 /* execute any "postexec = " line */
3855 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3858 strcpy(cmd,lp_postexec(SNUM(cnum)));
3859 standard_sub(cnum,cmd);
3860 smbrun(cmd,NULL,False);
3865 /* execute any "root postexec = " line */
3866 if (*lp_rootpostexec(SNUM(cnum)))
3869 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3870 standard_sub(cnum,cmd);
3871 smbrun(cmd,NULL,False);
3874 Connections[cnum].open = False;
3875 num_connections_open--;
3876 if (Connections[cnum].ngroups && Connections[cnum].groups)
3878 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3879 free(Connections[cnum].groups);
3880 free(Connections[cnum].igroups);
3881 Connections[cnum].groups = NULL;
3882 Connections[cnum].igroups = NULL;
3883 Connections[cnum].ngroups = 0;
3886 free_namearray(Connections[cnum].veto_list);
3887 free_namearray(Connections[cnum].hide_list);
3889 string_set(&Connections[cnum].user,"");
3890 string_set(&Connections[cnum].dirpath,"");
3891 string_set(&Connections[cnum].connectpath,"");
3895 /****************************************************************************
3896 simple routines to do connection counting
3897 ****************************************************************************/
3898 BOOL yield_connection(int cnum,char *name,int max_connections)
3900 struct connect_record crec;
3903 int mypid = getpid();
3906 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3908 if (max_connections <= 0)
3911 bzero(&crec,sizeof(crec));
3913 pstrcpy(fname,lp_lockdir());
3914 standard_sub(cnum,fname);
3915 trim_string(fname,"","/");
3919 strcat(fname,".LCK");
3921 f = fopen(fname,"r+");
3924 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3928 fseek(f,0,SEEK_SET);
3930 /* find a free spot */
3931 for (i=0;i<max_connections;i++)
3933 if (fread(&crec,sizeof(crec),1,f) != 1)
3935 DEBUG(2,("Entry not found in lock file %s\n",fname));
3939 if (crec.pid == mypid && crec.cnum == cnum)
3943 if (crec.pid != mypid || crec.cnum != cnum)
3946 DEBUG(2,("Entry not found in lock file %s\n",fname));
3950 bzero((void *)&crec,sizeof(crec));
3952 /* remove our mark */
3953 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3954 fwrite(&crec,sizeof(crec),1,f) != 1)
3956 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3961 DEBUG(3,("Yield successful\n"));
3968 /****************************************************************************
3969 simple routines to do connection counting
3970 ****************************************************************************/
3971 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3973 struct connect_record crec;
3976 int snum = SNUM(cnum);
3980 if (max_connections <= 0)
3983 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3985 pstrcpy(fname,lp_lockdir());
3986 standard_sub(cnum,fname);
3987 trim_string(fname,"","/");
3989 if (!directory_exist(fname,NULL))
3994 strcat(fname,".LCK");
3996 if (!file_exist(fname,NULL))
3998 int oldmask = umask(022);
3999 f = fopen(fname,"w");
4004 total_recs = file_size(fname) / sizeof(crec);
4006 f = fopen(fname,"r+");
4010 DEBUG(1,("couldn't open lock file %s\n",fname));
4014 /* find a free spot */
4015 for (i=0;i<max_connections;i++)
4018 if (i>=total_recs ||
4019 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4020 fread(&crec,sizeof(crec),1,f) != 1)
4022 if (foundi < 0) foundi = i;
4026 if (Clear && crec.pid && !process_exists(crec.pid))
4028 fseek(f,i*sizeof(crec),SEEK_SET);
4029 bzero((void *)&crec,sizeof(crec));
4030 fwrite(&crec,sizeof(crec),1,f);
4031 if (foundi < 0) foundi = i;
4034 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4043 DEBUG(3,("no free locks in %s\n",fname));
4048 /* fill in the crec */
4049 bzero((void *)&crec,sizeof(crec));
4050 crec.magic = 0x280267;
4051 crec.pid = getpid();
4053 crec.uid = Connections[cnum].uid;
4054 crec.gid = Connections[cnum].gid;
4055 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4056 crec.start = time(NULL);
4058 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4059 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4062 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4063 fwrite(&crec,sizeof(crec),1,f) != 1)
4074 /*******************************************************************
4075 prepare to dump a core file - carefully!
4076 ********************************************************************/
4077 static BOOL dump_core(void)
4081 pstrcpy(dname,debugf);
4082 if ((p=strrchr(dname,'/'))) *p=0;
4083 strcat(dname,"/corefiles");
4085 sys_chown(dname,getuid(),getgid());
4087 if (chdir(dname)) return(False);
4090 #ifndef NO_GETRLIMIT
4094 getrlimit(RLIMIT_CORE, &rlp);
4095 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4096 setrlimit(RLIMIT_CORE, &rlp);
4097 getrlimit(RLIMIT_CORE, &rlp);
4098 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4104 DEBUG(0,("Dumping core in %s\n",dname));
4109 /****************************************************************************
4111 ****************************************************************************/
4112 void exit_server(char *reason)
4114 static int firsttime=1;
4117 if (!firsttime) exit(0);
4121 DEBUG(2,("Closing connections\n"));
4122 for (i=0;i<MAX_CONNECTIONS;i++)
4123 if (Connections[i].open)
4124 close_cnum(i,(uint16)-1);
4126 if (dcelogin_atmost_once)
4130 int oldlevel = DEBUGLEVEL;
4132 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4134 show_msg(last_inbuf);
4135 DEBUGLEVEL = oldlevel;
4136 DEBUG(0,("===============================================================\n"));
4138 if (dump_core()) return;
4142 #ifdef FAST_SHARE_MODES
4143 stop_share_mode_mgmt();
4144 #endif /* FAST_SHARE_MODES */
4146 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4150 /****************************************************************************
4151 do some standard substitutions in a string
4152 ****************************************************************************/
4153 void standard_sub(int cnum,char *str)
4155 if (VALID_CNUM(cnum)) {
4158 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4160 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4161 string_sub(p,"%H",home);
4165 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4166 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4167 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4168 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4169 case '\0' : p++; break; /* don't run off the end of the string */
4170 default : p+=2; break;
4174 standard_sub_basic(str);
4178 These flags determine some of the permissions required to do an operation
4180 Note that I don't set NEED_WRITE on some write operations because they
4181 are used by some brain-dead clients when printing, and I don't want to
4182 force write permissions on print services.
4184 #define AS_USER (1<<0)
4185 #define NEED_WRITE (1<<1)
4186 #define TIME_INIT (1<<2)
4187 #define CAN_IPC (1<<3)
4188 #define AS_GUEST (1<<5)
4192 define a list of possible SMB messages and their corresponding
4193 functions. Any message that has a NULL function is unimplemented -
4194 please feel free to contribute implementations!
4196 struct smb_message_struct
4210 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4211 {SMBtcon,"SMBtcon",reply_tcon,0},
4212 {SMBtdis,"SMBtdis",reply_tdis,0},
4213 {SMBexit,"SMBexit",reply_exit,0},
4214 {SMBioctl,"SMBioctl",reply_ioctl,0},
4215 {SMBecho,"SMBecho",reply_echo,0},
4216 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4217 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4218 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4219 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4220 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4221 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4222 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4223 {SMBopen,"SMBopen",reply_open,AS_USER},
4225 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4226 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4227 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4229 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4230 {SMBread,"SMBread",reply_read,AS_USER},
4231 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4232 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4233 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4234 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4235 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4236 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4238 /* this is a Pathworks specific call, allowing the
4239 changing of the root path */
4240 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4242 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4243 {SMBflush,"SMBflush",reply_flush,AS_USER},
4244 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4245 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4246 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4247 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4248 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4249 {SMBlock,"SMBlock",reply_lock,AS_USER},
4250 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4252 /* CORE+ PROTOCOL FOLLOWS */
4254 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4255 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4256 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4257 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4258 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4260 /* LANMAN1.0 PROTOCOL FOLLOWS */
4262 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4263 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4264 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4265 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4266 {SMBwritec,"SMBwritec",NULL,AS_USER},
4267 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4268 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4269 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4270 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4271 {SMBioctls,"SMBioctls",NULL,AS_USER},
4272 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4273 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4275 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4276 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4277 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4278 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4280 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4281 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4282 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4284 /* LANMAN2.0 PROTOCOL FOLLOWS */
4285 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4286 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4287 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4288 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4290 /* messaging routines */
4291 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4292 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4293 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4294 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4296 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4298 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4299 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4300 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4301 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4304 /****************************************************************************
4305 return a string containing the function name of a SMB command
4306 ****************************************************************************/
4307 char *smb_fn_name(int type)
4309 static char *unknown_name = "SMBunknown";
4310 static int num_smb_messages =
4311 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4314 for (match=0;match<num_smb_messages;match++)
4315 if (smb_messages[match].code == type)
4318 if (match == num_smb_messages)
4319 return(unknown_name);
4321 return(smb_messages[match].name);
4325 /****************************************************************************
4326 do a switch on the message type, and return the response size
4327 ****************************************************************************/
4328 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4332 static int num_smb_messages =
4333 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4337 struct timeval msg_start_time;
4338 struct timeval msg_end_time;
4339 static unsigned long total_time = 0;
4341 GetTimeOfDay(&msg_start_time);
4348 last_message = type;
4350 /* make sure this is an SMB packet */
4351 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4353 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4357 for (match=0;match<num_smb_messages;match++)
4358 if (smb_messages[match].code == type)
4361 if (match == num_smb_messages)
4363 DEBUG(0,("Unknown message type %d!\n",type));
4364 outsize = reply_unknown(inbuf,outbuf);
4368 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4369 if (smb_messages[match].fn)
4371 int cnum = SVAL(inbuf,smb_tid);
4372 int flags = smb_messages[match].flags;
4373 uint16 session_tag = SVAL(inbuf,smb_uid);
4375 /* does this protocol need to be run as root? */
4376 if (!(flags & AS_USER))
4379 /* does this protocol need to be run as the connected user? */
4380 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
4381 if (flags & AS_GUEST)
4384 return(ERROR(ERRSRV,ERRinvnid));
4386 /* this code is to work around a bug is MS client 3 without
4387 introducing a security hole - it needs to be able to do
4388 print queue checks as guest if it isn't logged in properly */
4389 if (flags & AS_USER)
4392 /* does it need write permission? */
4393 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4394 return(ERROR(ERRSRV,ERRaccess));
4396 /* ipc services are limited */
4397 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4398 return(ERROR(ERRSRV,ERRaccess));
4400 /* load service specific parameters */
4401 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4402 return(ERROR(ERRSRV,ERRaccess));
4404 /* does this protocol need to be run as guest? */
4405 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4406 return(ERROR(ERRSRV,ERRaccess));
4410 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4414 outsize = reply_unknown(inbuf,outbuf);
4419 GetTimeOfDay(&msg_end_time);
4420 if (!(smb_messages[match].flags & TIME_INIT))
4422 smb_messages[match].time = 0;
4423 smb_messages[match].flags |= TIME_INIT;
4426 unsigned long this_time =
4427 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4428 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4429 smb_messages[match].time += this_time;
4430 total_time += this_time;
4432 DEBUG(2,("TIME %s %d usecs %g pct\n",
4433 smb_fn_name(type),smb_messages[match].time,
4434 (100.0*smb_messages[match].time) / total_time));
4441 /****************************************************************************
4442 construct a chained reply and add it to the already made reply
4443 **************************************************************************/
4444 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4446 static char *orig_inbuf;
4447 static char *orig_outbuf;
4448 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4449 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4450 char *inbuf2, *outbuf2;
4452 char inbuf_saved[smb_wct];
4453 char outbuf_saved[smb_wct];
4454 extern int chain_size;
4455 int wct = CVAL(outbuf,smb_wct);
4456 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4458 /* maybe its not chained */
4459 if (smb_com2 == 0xFF) {
4460 CVAL(outbuf,smb_vwv0) = 0xFF;
4464 if (chain_size == 0) {
4465 /* this is the first part of the chain */
4467 orig_outbuf = outbuf;
4470 /* we need to tell the client where the next part of the reply will be */
4471 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4472 CVAL(outbuf,smb_vwv0) = smb_com2;
4474 /* remember how much the caller added to the chain, only counting stuff
4475 after the parameter words */
4476 chain_size += outsize - smb_wct;
4478 /* work out pointers into the original packets. The
4479 headers on these need to be filled in */
4480 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4481 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4483 /* remember the original command type */
4484 smb_com1 = CVAL(orig_inbuf,smb_com);
4486 /* save the data which will be overwritten by the new headers */
4487 memcpy(inbuf_saved,inbuf2,smb_wct);
4488 memcpy(outbuf_saved,outbuf2,smb_wct);
4490 /* give the new packet the same header as the last part of the SMB */
4491 memmove(inbuf2,inbuf,smb_wct);
4493 /* create the in buffer */
4494 CVAL(inbuf2,smb_com) = smb_com2;
4496 /* create the out buffer */
4497 bzero(outbuf2,smb_size);
4498 set_message(outbuf2,0,0,True);
4499 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4501 memcpy(outbuf2+4,inbuf2+4,4);
4502 CVAL(outbuf2,smb_rcls) = SUCCESS;
4503 CVAL(outbuf2,smb_reh) = 0;
4504 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4506 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4507 SSVAL(outbuf2,smb_err,SUCCESS);
4508 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4509 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4510 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4511 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4513 DEBUG(3,("Chained message\n"));
4516 /* process the request */
4517 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4518 bufsize-chain_size);
4520 /* copy the new reply and request headers over the old ones, but
4521 preserve the smb_com field */
4522 memmove(orig_outbuf,outbuf2,smb_wct);
4523 CVAL(orig_outbuf,smb_com) = smb_com1;
4525 /* restore the saved data, being careful not to overwrite any
4526 data from the reply header */
4527 memcpy(inbuf2,inbuf_saved,smb_wct);
4529 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4530 if (ofs < 0) ofs = 0;
4531 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4539 /****************************************************************************
4540 construct a reply to the incoming packet
4541 ****************************************************************************/
4542 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4544 int type = CVAL(inbuf,smb_com);
4546 int msg_type = CVAL(inbuf,0);
4547 extern int chain_size;
4549 smb_last_time = time(NULL);
4554 bzero(outbuf,smb_size);
4557 return(reply_special(inbuf,outbuf));
4559 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4560 set_message(outbuf,0,0,True);
4562 memcpy(outbuf+4,inbuf+4,4);
4563 CVAL(outbuf,smb_rcls) = SUCCESS;
4564 CVAL(outbuf,smb_reh) = 0;
4565 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4567 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4568 SSVAL(outbuf,smb_err,SUCCESS);
4569 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4570 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4571 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4572 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4574 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4576 outsize += chain_size;
4579 smb_setlen(outbuf,outsize - 4);
4583 /****************************************************************************
4584 process commands from the client
4585 ****************************************************************************/
4586 static void process(void)
4590 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4591 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4592 if ((InBuffer == NULL) || (OutBuffer == NULL))
4595 InBuffer += SMB_ALIGNMENT;
4596 OutBuffer += SMB_ALIGNMENT;
4599 DEBUG(3,("priming nmbd\n"));
4602 ip = *interpret_addr2("localhost");
4603 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4605 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4611 int deadtime = lp_deadtime()*60;
4613 int last_keepalive=0;
4614 int service_load_counter = 0;
4615 BOOL got_smb = False;
4618 deadtime = DEFAULT_SMBD_TIMEOUT;
4620 if (lp_readprediction())
4621 do_read_prediction();
4625 for (counter=SMBD_SELECT_LOOP;
4626 !receive_message_or_smb(Client,oplock_sock,
4627 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4628 counter += SMBD_SELECT_LOOP)
4632 BOOL allidle = True;
4633 extern int keepalive;
4635 if (counter > 365 * 3600) /* big number of seconds. */
4638 service_load_counter = 0;
4641 if (smb_read_error == READ_EOF)
4643 DEBUG(3,("end of file from client\n"));
4647 if (smb_read_error == READ_ERROR)
4649 DEBUG(3,("receive_smb error (%s) exiting\n",
4656 /* become root again if waiting */
4659 /* check for smb.conf reload */
4660 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4662 service_load_counter = counter;
4664 /* reload services, if files have changed. */
4665 reload_services(True);
4668 /* automatic timeout if all connections are closed */
4669 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4671 DEBUG(2,("%s Closing idle connection\n",timestring()));
4675 if (keepalive && (counter-last_keepalive)>keepalive)
4677 extern int password_client;
4678 if (!send_keepalive(Client))
4680 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4683 /* also send a keepalive to the password server if its still
4685 if (password_client != -1)
4686 send_keepalive(password_client);
4687 last_keepalive = counter;
4690 /* check for connection timeouts */
4691 for (i=0;i<MAX_CONNECTIONS;i++)
4692 if (Connections[i].open)
4694 /* close dirptrs on connections that are idle */
4695 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4698 if (Connections[i].num_files_open > 0 ||
4699 (t-Connections[i].lastused)<deadtime)
4703 if (allidle && num_connections_open>0)
4705 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4711 process_smb(InBuffer, OutBuffer);
4713 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4718 /****************************************************************************
4719 initialise connect, service and file structs
4720 ****************************************************************************/
4721 static void init_structs(void )
4724 get_myname(myhostname,NULL);
4726 for (i=0;i<MAX_CONNECTIONS;i++)
4728 Connections[i].open = False;
4729 Connections[i].num_files_open=0;
4730 Connections[i].lastused=0;
4731 Connections[i].used=False;
4732 string_init(&Connections[i].user,"");
4733 string_init(&Connections[i].dirpath,"");
4734 string_init(&Connections[i].connectpath,"");
4735 string_init(&Connections[i].origpath,"");
4738 for (i=0;i<MAX_OPEN_FILES;i++)
4740 Files[i].open = False;
4741 string_init(&Files[i].name,"");
4745 for (i=0;i<MAX_OPEN_FILES;i++)
4747 file_fd_struct *fd_ptr = &FileFd[i];
4748 fd_ptr->ref_count = 0;
4749 fd_ptr->dev = (int32)-1;
4750 fd_ptr->inode = (int32)-1;
4752 fd_ptr->fd_readonly = -1;
4753 fd_ptr->fd_writeonly = -1;
4754 fd_ptr->real_open_flags = -1;
4760 /****************************************************************************
4761 usage on the program
4762 ****************************************************************************/
4763 static void usage(char *pname)
4765 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4767 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4768 printf("Version %s\n",VERSION);
4769 printf("\t-D become a daemon\n");
4770 printf("\t-p port listen on the specified port\n");
4771 printf("\t-d debuglevel set the debuglevel\n");
4772 printf("\t-l log basename. Basename for log/debug files\n");
4773 printf("\t-s services file. Filename of services file\n");
4774 printf("\t-P passive only\n");
4775 printf("\t-a overwrite log file, don't append\n");
4780 /****************************************************************************
4782 ****************************************************************************/
4783 int main(int argc,char *argv[])
4785 extern BOOL append_log;
4786 /* shall I run as a daemon */
4787 BOOL is_daemon = False;
4788 int port = SMB_PORT;
4790 extern char *optarg;
4791 char pidFile[100] = { 0 };
4793 #ifdef NEED_AUTH_PARAMETERS
4794 set_auth_parameters(argc,argv);
4805 strcpy(debugf,SMBLOGFILE);
4807 setup_logging(argv[0],False);
4809 charset_initialise();
4811 /* make absolutely sure we run as root - to handle cases whre people
4812 are crazy enough to have it setuid */
4822 fault_setup(exit_server);
4823 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4825 /* we want total control over the permissions on created files,
4826 so set our umask to 0 */
4833 /* this is for people who can't start the program correctly */
4834 while (argc > 1 && (*argv[1] != '-'))
4840 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4844 strncpy(pidFile, optarg, sizeof(pidFile));
4847 strcpy(user_socket_options,optarg);
4850 strcpy(scope,optarg);
4854 extern BOOL passive;
4859 strcpy(servicesf,optarg);
4862 strcpy(debugf,optarg);
4866 extern BOOL append_log;
4867 append_log = !append_log;
4877 DEBUGLEVEL = atoi(optarg);
4880 port = atoi(optarg);
4893 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4894 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4896 #ifndef NO_GETRLIMIT
4897 #ifdef RLIMIT_NOFILE
4900 getrlimit(RLIMIT_NOFILE, &rlp);
4901 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4902 setrlimit(RLIMIT_NOFILE, &rlp);
4903 getrlimit(RLIMIT_NOFILE, &rlp);
4904 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4910 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4911 getuid(),getgid(),geteuid(),getegid()));
4913 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4915 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4921 if (!reload_services(False))
4924 codepage_initialise(lp_client_code_page());
4926 strcpy(myworkgroup, lp_workgroup());
4928 #ifndef NO_SIGNAL_TEST
4929 signal(SIGHUP,SIGNAL_CAST sig_hup);
4932 DEBUG(3,("%s loaded services\n",timestring()));
4934 if (!is_daemon && !is_a_socket(0))
4936 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4942 DEBUG(3,("%s becoming a daemon\n",timestring()));
4951 if ((fd = open(pidFile,
4955 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4957 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4960 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4962 DEBUG(0,("ERROR: smbd is already running\n"));
4965 sprintf(buf, "%u\n", (unsigned int) getpid());
4966 if (write(fd, buf, strlen(buf)) < 0)
4968 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4971 /* Leave pid file open & locked for the duration... */
4974 if (!open_sockets(is_daemon,port))
4977 #ifdef FAST_SHARE_MODES
4978 if (!start_share_mode_mgmt())
4980 #endif /* FAST_SHARE_MODES */
4982 /* possibly reload the services file. */
4983 reload_services(True);
4985 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4989 if (sys_chroot(lp_rootdir()) == 0)
4990 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4993 /* Setup the oplock IPC socket. */
4994 if(!open_oplock_ipc())
5000 exit_server("normal exit");