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);
219 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
224 /* hide files with a name starting with a . */
225 if (lp_hide_dot_files(SNUM(cnum)))
227 char *p = strrchr(path,'/');
233 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
237 /* Optimization : Only call is_hidden_path if it's not already
239 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
244 DEBUG(8,("dos_mode returning "));
246 if (result & aHIDDEN) DEBUG(8, ("h"));
247 if (result & aRONLY ) DEBUG(8, ("r"));
248 if (result & aSYSTEM) DEBUG(8, ("s"));
249 if (result & aDIR ) DEBUG(8, ("d"));
250 if (result & aARCH ) DEBUG(8, ("a"));
258 /*******************************************************************
259 chmod a file - but preserve some bits
260 ********************************************************************/
261 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
270 if (sys_stat(fname,st)) return(-1);
273 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
275 if (dos_mode(cnum,fname,st) == dosmode) return(0);
277 unixmode = unix_mode(cnum,dosmode);
279 /* preserve the s bits */
280 mask |= (S_ISUID | S_ISGID);
282 /* preserve the t bit */
287 /* possibly preserve the x bits */
288 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
289 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
290 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
292 unixmode |= (st->st_mode & mask);
294 /* if we previously had any r bits set then leave them alone */
295 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
296 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
300 /* if we previously had any w bits set then leave them alone
301 if the new mode is not rdonly */
302 if (!IS_DOS_READONLY(dosmode) &&
303 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
304 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
308 return(sys_chmod(fname,unixmode));
312 /****************************************************************************
313 check if two filenames are equal
315 this needs to be careful about whether we are case sensitive
316 ****************************************************************************/
317 static BOOL fname_equal(char *name1, char *name2)
319 int l1 = strlen(name1);
320 int l2 = strlen(name2);
322 /* handle filenames ending in a single dot */
323 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
327 ret = fname_equal(name1,name2);
332 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
336 ret = fname_equal(name1,name2);
341 /* now normal filename handling */
343 return(strcmp(name1,name2) == 0);
345 return(strequal(name1,name2));
349 /****************************************************************************
350 mangle the 2nd name and check if it is then equal to the first name
351 ****************************************************************************/
352 static BOOL mangled_equal(char *name1, char *name2)
356 if (is_8_3(name2, True))
359 strcpy(tmpname,name2);
360 mangle_name_83(tmpname);
362 return(strequal(name1,tmpname));
366 /****************************************************************************
367 scan a directory to find a filename, matching without case sensitivity
369 If the name looks like a mangled name then try via the mangling functions
370 ****************************************************************************/
371 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
378 mangled = is_mangled(name);
380 /* handle null paths */
384 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
390 check_mangled_stack(name);
392 /* open the directory */
393 if (!(cur_dir = OpenDir(cnum, path, True)))
395 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
399 /* now scan for matching names */
400 while ((dname = ReadDirName(cur_dir)))
403 (strequal(dname,".") || strequal(dname,"..")))
406 pstrcpy(name2,dname);
407 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
409 if ((mangled && mangled_equal(name,name2))
410 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
412 /* we've found the file, change it's name and return */
413 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
424 /****************************************************************************
425 This routine is called to convert names from the dos namespace to unix
426 namespace. It needs to handle any case conversions, mangling, format
429 We assume that we have already done a chdir() to the right "root" directory
432 The function will return False if some part of the name except for the last
433 part cannot be resolved
435 If the saved_last_component != 0, then the unmodified last component
436 of the pathname is returned there. This is used in an exceptional
437 case in reply_mv (so far). If saved_last_component == 0 then nothing
440 The bad_path arg is set to True if the filename walk failed. This is
441 used to pick the correct error code to return between ENOENT and ENOTDIR
442 as Windows applications depend on ERRbadpath being returned if a component
443 of a pathname does not exist.
444 ****************************************************************************/
445 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
455 if(saved_last_component)
456 *saved_last_component = 0;
458 /* convert to basic unix format - removing \ chars and cleaning it up */
460 unix_clean_name(name);
462 /* names must be relative to the root of the service - trim any leading /.
463 also trim trailing /'s */
464 trim_string(name,"/","/");
467 * Ensure saved_last_component is valid even if file exists.
469 if(saved_last_component) {
470 end = strrchr(name, '/');
472 strcpy(saved_last_component, end + 1);
474 strcpy(saved_last_component, name);
477 if (!case_sensitive &&
478 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
481 /* check if it's a printer file */
482 if (Connections[cnum].printer)
484 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
488 sprintf(name2,"%.6s.XXXXXX",remote_machine);
489 /* sanitise the name */
490 for (s=name2 ; *s ; s++)
491 if (!issafe(*s)) *s = '_';
492 strcpy(name,(char *)mktemp(name2));
497 /* stat the name - if it exists then we are all done! */
498 if (sys_stat(name,&st) == 0)
503 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
505 /* a special case - if we don't have any mangling chars and are case
506 sensitive then searching won't help */
507 if (case_sensitive && !is_mangled(name) &&
508 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
511 /* now we need to recursively match the name against the real
512 directory structure */
515 while (strncmp(start,"./",2) == 0)
518 /* now match each part of the path name separately, trying the names
519 as is first, then trying to scan the directory for matching names */
520 for (;start;start = (end?end+1:(char *)NULL))
522 /* pinpoint the end of this section of the filename */
523 end = strchr(start, '/');
525 /* chop the name at this point */
528 if(saved_last_component != 0)
529 strcpy(saved_last_component, end ? end + 1 : start);
531 /* check if the name exists up to this point */
532 if (sys_stat(name, &st) == 0)
534 /* it exists. it must either be a directory or this must be
535 the last part of the path for it to be OK */
536 if (end && !(st.st_mode & S_IFDIR))
538 /* an intermediate part of the name isn't a directory */
539 DEBUG(5,("Not a dir %s\n",start));
550 /* remember the rest of the pathname so it can be restored
552 if (end) pstrcpy(rest,end+1);
554 /* try to find this part of the path in the directory */
555 if (strchr(start,'?') || strchr(start,'*') ||
556 !scan_directory(dirpath, start, cnum, end?True:False))
560 /* an intermediate part of the name can't be found */
561 DEBUG(5,("Intermediate not found %s\n",start));
563 /* We need to return the fact that the intermediate
564 name resolution failed. This is used to return an
565 error of ERRbadpath rather than ERRbadfile. Some
566 Windows applications depend on the difference between
573 /* just the last part of the name doesn't exist */
574 /* we may need to strupper() or strlower() it in case
575 this conversion is being used for file creation
577 /* if the filename is of mixed case then don't normalise it */
578 if (!case_preserve &&
579 (!strhasupper(start) || !strhaslower(start)))
582 /* check on the mangled stack to see if we can recover the
583 base of the filename */
584 if (is_mangled(start))
585 check_mangled_stack(start);
587 DEBUG(5,("New file %s\n",start));
591 /* restore the rest of the string */
594 strcpy(start+strlen(start)+1,rest);
595 end = start + strlen(start);
599 /* add to the dirpath that we have resolved so far */
600 if (*dirpath) strcat(dirpath,"/");
601 strcat(dirpath,start);
603 /* restore the / that we wiped out earlier */
607 /* the name has been resolved */
608 DEBUG(5,("conversion finished %s\n",name));
613 /****************************************************************************
614 normalise for DOS usage
615 ****************************************************************************/
616 static void disk_norm(int *bsize,int *dfree,int *dsize)
618 /* check if the disk is beyond the max disk size */
619 int maxdisksize = lp_maxdisksize();
621 /* convert to blocks - and don't overflow */
622 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
623 if (*dsize > maxdisksize) *dsize = maxdisksize;
624 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
629 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
634 if (*bsize > WORDMAX )
637 if (*dsize > WORDMAX)
639 if (*dfree > WORDMAX)
646 /****************************************************************************
647 return number of 1K blocks available on a path and total number
648 ****************************************************************************/
649 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
651 char *df_command = lp_dfree_command();
672 /* possibly use system() to get the result */
673 if (df_command && *df_command)
679 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
680 sprintf(syscmd,"%s %s",df_command,path);
681 standard_sub_basic(syscmd);
683 ret = smbrun(syscmd,outfile,False);
684 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
687 FILE *f = fopen(outfile,"r");
693 fscanf(f,"%d %d %d",dsize,dfree,bsize);
697 DEBUG(0,("Can't open %s\n",outfile));
701 disk_norm(bsize,dfree,dsize);
702 dfree_retval = ((*bsize)/1024)*(*dfree);
704 /* Ensure we return the min value between the users quota and
705 what's free on the disk. Thanks to Albrecht Gebhardt
706 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
708 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
710 disk_norm(&bsizeq, &dfreeq, &dsizeq);
711 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
712 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
713 dfree_retval : dfreeq_retval ;
714 /* maybe dfree and dfreeq are calculated using different bsizes
715 so convert dfree from bsize into bsizeq */
716 /* avoid overflows due to multiplication, so do not:
717 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
718 bsize and bsizeq are powers of 2 so its better to
719 to divide them getting a multiplication or division factor
720 for dfree. Rene Nieuwenhuizen (07-10-1997) */
721 if (*bsize >= bsizeq)
722 *dfree = *dfree * (*bsize / bsizeq);
724 *dfree = *dfree / (bsizeq / *bsize);
725 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
730 return(dfree_retval);
734 DEBUG(1,("Warning - no statfs function\n"));
738 if (statfs(path,&fs,sizeof(fs),0) != 0)
741 if (statvfs(path, &fs))
744 if (statfs(path,&fs,sizeof(fs)) == -1)
746 if (statfs(path,&fs) == -1)
748 #endif /* USE_STATVFS */
751 DEBUG(3,("dfree call failed code errno=%d\n",errno));
755 return(((*bsize)/1024)*(*dfree));
760 *dfree = fs.fd_req.bfree;
761 *dsize = fs.fd_req.btot;
764 *bsize = fs.f_frsize;
767 /* eg: osf1 has f_fsize = fundamental filesystem block size,
768 f_bsize = optimal transfer block size (MX: 94-04-19) */
773 #endif /* USE_STATVFS */
778 *dfree = fs.f_bavail;
780 *dsize = fs.f_blocks;
783 #if defined(SCO) || defined(ISC) || defined(MIPS)
787 /* handle rediculous bsize values - some OSes are broken */
788 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
790 disk_norm(bsize,dfree,dsize);
796 DEBUG(0,("dfree seems to be broken on your system\n"));
797 *dsize = 20*1024*1024/(*bsize);
798 *dfree = MAX(1,*dfree);
800 dfree_retval = ((*bsize)/1024)*(*dfree);
802 /* Ensure we return the min value between the users quota and
803 what's free on the disk. Thanks to Albrecht Gebhardt
804 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
806 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
808 disk_norm(&bsizeq, &dfreeq, &dsizeq);
809 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
810 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
811 dfree_retval : dfreeq_retval ;
812 /* maybe dfree and dfreeq are calculated using different bsizes
813 so convert dfree from bsize into bsizeq */
814 /* avoid overflows due to multiplication, so do not:
815 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
816 bsize and bsizeq are powers of 2 so its better to
817 to divide them getting a multiplication or division factor
818 for dfree. Rene Nieuwenhuizen (07-10-1997) */
819 if (*bsize >= bsizeq)
820 *dfree = *dfree * (*bsize / bsizeq);
822 *dfree = *dfree / (bsizeq / *bsize);
823 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
828 return(dfree_retval);
833 /****************************************************************************
834 wrap it to get filenames right
835 ****************************************************************************/
836 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
838 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
843 /****************************************************************************
844 check a filename - possibly caling reducename
846 This is called by every routine before it allows an operation on a filename.
847 It does any final confirmation necessary to ensure that the filename is
848 a valid one for the user to access.
849 ****************************************************************************/
850 BOOL check_name(char *name,int cnum)
856 if( IS_VETO_PATH(cnum, name))
858 DEBUG(5,("file path name %s vetoed\n",name));
862 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
864 /* Check if we are allowing users to follow symlinks */
865 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
866 University of Geneva */
869 if (!lp_symlinks(SNUM(cnum)))
872 if ( (sys_lstat(name,&statbuf) != -1) &&
873 (S_ISLNK(statbuf.st_mode)) )
875 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
882 DEBUG(5,("check_name on %s failed\n",name));
887 /****************************************************************************
888 check a filename - possibly caling reducename
889 ****************************************************************************/
890 static void check_for_pipe(char *fname)
892 /* special case of pipe opens */
896 if (strstr(s,"pipe/"))
898 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
899 unix_ERR_class = ERRSRV;
900 unix_ERR_code = ERRaccess;
904 /****************************************************************************
905 fd support routines - attempt to do a sys_open
906 ****************************************************************************/
907 static int fd_attempt_open(char *fname, int flags, int mode)
909 int fd = sys_open(fname,flags,mode);
911 /* Fix for files ending in '.' */
912 if((fd == -1) && (errno == ENOENT) &&
913 (strchr(fname,'.')==NULL))
916 fd = sys_open(fname,flags,mode);
919 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
920 if ((fd == -1) && (errno == ENAMETOOLONG))
923 char *p = strrchr(fname, '/');
925 if (p == fname) /* name is "/xxx" */
927 max_len = pathconf("/", _PC_NAME_MAX);
930 else if ((p == NULL) || (p == fname))
933 max_len = pathconf(".", _PC_NAME_MAX);
938 max_len = pathconf(fname, _PC_NAME_MAX);
942 if (strlen(p) > max_len)
944 char tmp = p[max_len];
947 if ((fd = sys_open(fname,flags,mode)) == -1)
955 /****************************************************************************
956 fd support routines - attempt to find an already open file by dev
957 and inode - increments the ref_count of the returned file_fd_struct *.
958 ****************************************************************************/
959 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
962 file_fd_struct *fd_ptr;
967 for(i = 0; i <= max_file_fd_used; i++) {
969 if((fd_ptr->ref_count > 0) &&
970 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
971 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
974 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
975 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
982 /****************************************************************************
983 fd support routines - attempt to find a empty slot in the FileFd array.
984 Increments the ref_count of the returned entry.
985 ****************************************************************************/
986 static file_fd_struct *fd_get_new()
989 file_fd_struct *fd_ptr;
991 for(i = 0; i < MAX_OPEN_FILES; i++) {
993 if(fd_ptr->ref_count == 0) {
994 fd_ptr->dev = (uint32)-1;
995 fd_ptr->inode = (uint32)-1;
997 fd_ptr->fd_readonly = -1;
998 fd_ptr->fd_writeonly = -1;
999 fd_ptr->real_open_flags = -1;
1000 fd_ptr->ref_count++;
1001 /* Increment max used counter if neccessary, cuts down
1002 on search time when re-using */
1003 if(i > max_file_fd_used)
1004 max_file_fd_used = i;
1005 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1006 i, fd_ptr->dev, fd_ptr->inode));
1010 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1015 /****************************************************************************
1016 fd support routines - attempt to re-open an already open fd as O_RDWR.
1017 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1018 ****************************************************************************/
1019 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1021 int fd = sys_open( fname, O_RDWR, mode);
1026 if(fd_ptr->real_open_flags == O_RDONLY)
1027 fd_ptr->fd_readonly = fd_ptr->fd;
1028 if(fd_ptr->real_open_flags == O_WRONLY)
1029 fd_ptr->fd_writeonly = fd_ptr->fd;
1032 fd_ptr->real_open_flags = O_RDWR;
1035 /****************************************************************************
1036 fd support routines - attempt to close the file referenced by this fd.
1037 Decrements the ref_count and returns it.
1038 ****************************************************************************/
1039 static int fd_attempt_close(file_fd_struct *fd_ptr)
1041 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1042 fd_ptr - &FileFd[0],
1043 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1044 fd_ptr->real_open_flags,
1045 fd_ptr->ref_count));
1046 if(fd_ptr->ref_count > 0) {
1047 fd_ptr->ref_count--;
1048 if(fd_ptr->ref_count == 0) {
1049 if(fd_ptr->fd != -1)
1051 if(fd_ptr->fd_readonly != -1)
1052 close(fd_ptr->fd_readonly);
1053 if(fd_ptr->fd_writeonly != -1)
1054 close(fd_ptr->fd_writeonly);
1056 fd_ptr->fd_readonly = -1;
1057 fd_ptr->fd_writeonly = -1;
1058 fd_ptr->real_open_flags = -1;
1059 fd_ptr->dev = (uint32)-1;
1060 fd_ptr->inode = (uint32)-1;
1063 return fd_ptr->ref_count;
1066 /****************************************************************************
1068 ****************************************************************************/
1069 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1071 extern struct current_user current_user;
1073 struct stat statbuf;
1074 file_fd_struct *fd_ptr;
1075 files_struct *fsp = &Files[fnum];
1079 fsp->granted_oplock = False;
1082 pstrcpy(fname,fname1);
1084 /* check permissions */
1085 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1087 DEBUG(3,("Permission denied opening %s\n",fname));
1088 check_for_pipe(fname);
1092 /* this handles a bug in Win95 - it doesn't say to create the file when it
1094 if (Connections[cnum].printer)
1098 if (flags == O_WRONLY)
1099 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1102 #if UTIME_WORKAROUND
1103 /* XXXX - is this OK?? */
1104 /* this works around a utime bug but can cause other problems */
1105 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1110 * Ensure we have a valid struct stat so we can search the
1114 if(stat(fname, &statbuf) < 0) {
1115 if(errno != ENOENT) {
1116 DEBUG(3,("Error doing stat on file %s (%s)\n",
1117 fname,strerror(errno)));
1119 check_for_pipe(fname);
1129 * Check to see if we have this file already
1130 * open. If we do, just use the already open fd and increment the
1131 * reference count (fd_get_already_open increments the ref_count).
1133 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1135 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1137 /* File was already open. */
1138 if((flags & O_CREAT) && (flags & O_EXCL)) {
1139 fd_ptr->ref_count--;
1145 * If not opened O_RDWR try
1146 * and do that here - a chmod may have been done
1147 * between the last open and now.
1149 if(fd_ptr->real_open_flags != O_RDWR)
1150 fd_attempt_reopen(fname, mode, fd_ptr);
1153 * Ensure that if we wanted write access
1154 * it has been opened for write, and if we wanted read it
1155 * was open for read.
1157 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1158 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1159 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1160 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1161 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1162 check_for_pipe(fname);
1163 fd_ptr->ref_count--;
1169 /* We need to allocate a new file_fd_struct (this increments the
1171 if((fd_ptr = fd_get_new()) == 0)
1174 * Whatever the requested flags, attempt read/write access,
1175 * as we don't know what flags future file opens may require.
1176 * If this fails, try again with the required flags.
1177 * Even if we open read/write when only read access was
1178 * requested the setting of the can_write flag in
1179 * the file_struct will protect us from errant
1180 * write requests. We never need to worry about O_APPEND
1181 * as this is not set anywhere in Samba.
1183 fd_ptr->real_open_flags = O_RDWR;
1184 /* Set the flags as needed without the read/write modes. */
1185 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1186 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1188 * On some systems opening a file for R/W access on a read only
1189 * filesystems sets errno to EROFS.
1192 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1193 #else /* No EROFS */
1194 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1196 if(flags & O_WRONLY) {
1197 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1198 fd_ptr->real_open_flags = O_WRONLY;
1200 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1201 fd_ptr->real_open_flags = O_RDONLY;
1206 if ((fd_ptr->fd >=0) &&
1207 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1211 pstrcpy(dname,fname);
1212 p = strrchr(dname,'/');
1214 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1215 lp_minprintspace(SNUM(cnum))) {
1216 fd_attempt_close(fd_ptr);
1218 if(fd_ptr->ref_count == 0)
1227 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1228 fname,strerror(errno),flags));
1229 /* Ensure the ref_count is decremented. */
1230 fd_attempt_close(fd_ptr);
1231 check_for_pipe(fname);
1235 if (fd_ptr->fd >= 0)
1239 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1240 /* Error - backout !! */
1241 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1242 fd_ptr->fd, fname,strerror(errno)));
1243 /* Ensure the ref_count is decremented. */
1244 fd_attempt_close(fd_ptr);
1249 /* Set the correct entries in fd_ptr. */
1250 fd_ptr->dev = (uint32)sbuf->st_dev;
1251 fd_ptr->inode = (uint32)sbuf->st_ino;
1253 fsp->fd_ptr = fd_ptr;
1254 Connections[cnum].num_files_open++;
1255 fsp->mode = sbuf->st_mode;
1256 GetTimeOfDay(&fsp->open_time);
1257 fsp->uid = current_user.id;
1261 fsp->mmap_ptr = NULL;
1263 fsp->can_lock = True;
1264 fsp->can_read = ((flags & O_WRONLY)==0);
1265 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1266 fsp->share_mode = 0;
1267 fsp->print_file = Connections[cnum].printer;
1268 fsp->modified = False;
1269 fsp->granted_oplock = False;
1271 string_set(&fsp->name,dos_to_unix(fname,False));
1272 fsp->wbmpx_ptr = NULL;
1275 * If the printer is marked as postscript output a leading
1276 * file identifier to ensure the file is treated as a raw
1278 * This has a similar effect as CtrlD=0 in WIN.INI file.
1279 * tim@fsg.com 09/06/94
1281 if (fsp->print_file && POSTSCRIPT(cnum) &&
1284 DEBUG(3,("Writing postscript line\n"));
1285 write_file(fnum,"%!\n",3);
1288 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1289 timestring(),Connections[cnum].user,fname,
1290 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1291 Connections[cnum].num_files_open,fnum));
1296 /* mmap it if read-only */
1297 if (!fsp->can_write)
1299 fsp->mmap_size = file_size(fname);
1300 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1301 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1303 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1305 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1306 fsp->mmap_ptr = NULL;
1312 /*******************************************************************
1314 ********************************************************************/
1315 void sync_file(int fnum)
1318 fsync(Files[fnum].fd_ptr->fd);
1322 /****************************************************************************
1323 run a file if it is a magic script
1324 ****************************************************************************/
1325 static void check_magic(int fnum,int cnum)
1327 if (!*lp_magicscript(SNUM(cnum)))
1330 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1334 if (!(p = strrchr(Files[fnum].name,'/')))
1335 p = Files[fnum].name;
1339 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1345 pstring magic_output;
1347 pstrcpy(fname,Files[fnum].name);
1349 if (*lp_magicoutput(SNUM(cnum)))
1350 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1352 sprintf(magic_output,"%s.out",fname);
1355 ret = smbrun(fname,magic_output,False);
1356 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1362 /****************************************************************************
1363 close a file - possibly invalidating the read prediction
1364 ****************************************************************************/
1365 void close_file(int fnum)
1367 files_struct *fs_p = &Files[fnum];
1368 int cnum = fs_p->cnum;
1369 uint32 dev = fs_p->fd_ptr->dev;
1370 uint32 inode = fs_p->fd_ptr->inode;
1371 share_lock_token token;
1373 invalidate_read_prediction(fs_p->fd_ptr->fd);
1375 Connections[cnum].num_files_open--;
1378 free((char *)fs_p->wbmpx_ptr);
1379 fs_p->wbmpx_ptr = NULL;
1385 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1386 fs_p->mmap_ptr = NULL;
1390 if (lp_share_modes(SNUM(cnum)))
1392 lock_share_entry( cnum, dev, inode, &token);
1393 del_share_mode(token, fnum);
1396 fd_attempt_close(fs_p->fd_ptr);
1398 if (lp_share_modes(SNUM(cnum)))
1399 unlock_share_entry( cnum, dev, inode, token);
1401 /* NT uses smbclose to start a print - weird */
1402 if (fs_p->print_file)
1405 /* check for magic scripts */
1406 check_magic(fnum,cnum);
1408 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1409 timestring(),Connections[cnum].user,fs_p->name,
1410 Connections[cnum].num_files_open));
1413 enum {AFAIL,AREAD,AWRITE,AALL};
1415 /*******************************************************************
1416 reproduce the share mode access table
1417 ********************************************************************/
1418 static int access_table(int new_deny,int old_deny,int old_mode,
1419 int share_pid,char *fname)
1421 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1423 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1425 if (old_deny == new_deny && share_pid == pid)
1428 if (old_mode == 0) return(AREAD);
1430 /* the new smbpub.zip spec says that if the file extension is
1431 .com, .dll, .exe or .sym then allow the open. I will force
1432 it to read-only as this seems sensible although the spec is
1433 a little unclear on this. */
1434 if ((fname = strrchr(fname,'.'))) {
1435 if (strequal(fname,".com") ||
1436 strequal(fname,".dll") ||
1437 strequal(fname,".exe") ||
1438 strequal(fname,".sym"))
1448 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1449 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1450 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1453 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1454 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1455 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1458 if (old_deny==DENY_WRITE) return(AREAD);
1459 if (old_deny==DENY_READ) return(AWRITE);
1460 if (old_deny==DENY_NONE) return(AALL);
1466 /*******************************************************************
1467 check if the share mode on a file allows it to be deleted or unlinked
1468 return True if sharing doesn't prevent the operation
1469 ********************************************************************/
1470 BOOL check_file_sharing(int cnum,char *fname)
1474 min_share_mode_entry *old_shares = 0;
1475 int num_share_modes;
1477 share_lock_token token;
1481 if(!lp_share_modes(SNUM(cnum)))
1484 if (stat(fname,&sbuf) == -1) return(True);
1486 dev = (uint32)sbuf.st_dev;
1487 inode = (uint32)sbuf.st_ino;
1489 lock_share_entry(cnum, dev, inode, &token);
1490 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1493 * Check if the share modes will give us access.
1496 if(num_share_modes != 0)
1503 broke_oplock = False;
1504 for(i = 0; i < num_share_modes; i++)
1506 min_share_mode_entry *share_entry = &old_shares[i];
1509 * Break oplocks before checking share modes. See comment in
1510 * open_file_shared for details.
1511 * Check if someone has an oplock on this file. If so we must
1512 * break it before continuing.
1514 if(share_entry->op_type & BATCH_OPLOCK)
1517 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1518 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1520 /* Oplock break.... */
1521 unlock_share_entry(cnum, dev, inode, token);
1522 if(request_oplock_break(share_entry, dev, inode) == False)
1524 free((char *)old_shares);
1525 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1526 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1529 lock_share_entry(cnum, dev, inode, &token);
1530 broke_oplock = True;
1534 /* someone else has a share lock on it, check to see
1536 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1543 free((char *)old_shares);
1544 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1546 } while(broke_oplock);
1549 /* XXXX exactly what share mode combinations should be allowed for
1550 deleting/renaming? */
1551 /* If we got here then either there were no share modes or
1552 all share modes were DENY_DOS and the pid == getpid() */
1557 unlock_share_entry(cnum, dev, inode, token);
1558 if(old_shares != NULL)
1559 free((char *)old_shares);
1563 /****************************************************************************
1565 Helper for open_file_shared.
1566 Truncate a file after checking locking; close file if locked.
1567 **************************************************************************/
1568 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1571 if (Files[fnum].can_write){
1572 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1573 /* If share modes are in force for this connection we
1574 have the share entry locked. Unlock it before closing. */
1575 if (*share_locked && lp_share_modes(SNUM(cnum)))
1576 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1577 Files[fnum].fd_ptr->inode, token);
1579 /* Share mode no longer locked. */
1580 *share_locked = False;
1582 unix_ERR_class = ERRDOS;
1583 unix_ERR_code = ERRlock;
1586 ftruncate(Files[fnum].fd_ptr->fd,0);
1590 /****************************************************************************
1591 check if we can open a file with a share mode
1592 ****************************************************************************/
1593 int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
1594 BOOL fcbopen, int *flags)
1596 int old_open_mode = share->share_mode &0xF;
1597 int old_deny_mode = (share->share_mode >>4)&7;
1599 if (old_deny_mode > 4 || old_open_mode > 2)
1601 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1602 deny_mode,old_deny_mode,old_open_mode,fname));
1607 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1610 if ((access_allowed == AFAIL) ||
1611 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1612 (access_allowed == AREAD && *flags == O_WRONLY) ||
1613 (access_allowed == AWRITE && *flags == O_RDONLY))
1615 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1616 deny_mode,old_deny_mode,old_open_mode,
1617 share->pid,fname, access_allowed));
1621 if (access_allowed == AREAD)
1624 if (access_allowed == AWRITE)
1631 /****************************************************************************
1632 open a file with a share mode
1633 ****************************************************************************/
1634 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1635 int mode,int oplock_request, int *Access,int *action)
1637 files_struct *fs_p = &Files[fnum];
1640 int deny_mode = (share_mode>>4)&7;
1642 BOOL file_existed = file_exist(fname,&sbuf);
1643 BOOL share_locked = False;
1644 BOOL fcbopen = False;
1645 share_lock_token token;
1648 int num_share_modes = 0;
1653 /* this is for OS/2 EAs - try and say we don't support them */
1654 if (strstr(fname,".+,;=[]."))
1656 unix_ERR_class = ERRDOS;
1657 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1659 unix_ERR_code = ERRcannotopen;
1660 #else /* OS2_WPS_FIX */
1661 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1662 #endif /* OS2_WPS_FIX */
1667 if ((ofun & 0x3) == 0 && file_existed)
1675 if ((ofun & 0x3) == 2)
1678 /* note that we ignore the append flag as
1679 append does not mean the same thing under dos and unix */
1681 switch (share_mode&0xF)
1698 if (flags != O_RDONLY && file_existed &&
1699 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1709 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1711 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1716 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1718 if (lp_share_modes(SNUM(cnum)))
1721 min_share_mode_entry *old_shares = 0;
1725 dev = (uint32)sbuf.st_dev;
1726 inode = (uint32)sbuf.st_ino;
1727 lock_share_entry(cnum, dev, inode, &token);
1728 share_locked = True;
1729 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1733 * Check if the share modes will give us access.
1736 if(share_locked && (num_share_modes != 0))
1743 broke_oplock = False;
1744 for(i = 0; i < num_share_modes; i++)
1746 min_share_mode_entry *share_entry = &old_shares[i];
1749 * By observation of NetBench, oplocks are broken *before* share
1750 * modes are checked. This allows a file to be closed by the client
1751 * if the share mode would deny access and the client has an oplock.
1752 * Check if someone has an oplock on this file. If so we must break
1753 * it before continuing.
1755 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1758 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1759 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1761 /* Oplock break.... */
1762 unlock_share_entry(cnum, dev, inode, token);
1763 if(request_oplock_break(share_entry, dev, inode) == False)
1765 free((char *)old_shares);
1766 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1767 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1769 unix_ERR_class = ERRDOS;
1770 unix_ERR_code = ERRbadshare;
1773 lock_share_entry(cnum, dev, inode, &token);
1774 broke_oplock = True;
1778 /* someone else has a share lock on it, check to see
1780 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1782 free((char *)old_shares);
1783 unlock_share_entry(cnum, dev, inode, token);
1785 unix_ERR_class = ERRDOS;
1786 unix_ERR_code = ERRbadshare;
1794 free((char *)old_shares);
1795 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1797 } while(broke_oplock);
1801 free((char *)old_shares);
1804 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1805 flags,flags2,mode));
1807 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1808 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1811 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1818 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1820 /* We created the file - thus we must now lock the share entry before creating it. */
1821 dev = fs_p->fd_ptr->dev;
1822 inode = fs_p->fd_ptr->inode;
1823 lock_share_entry(cnum, dev, inode, &token);
1824 share_locked = True;
1840 fs_p->share_mode = (deny_mode<<4) | open_mode;
1843 (*Access) = open_mode;
1847 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1848 if (!file_existed) *action = 2;
1849 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1851 /* We must create the share mode entry before truncate as
1852 truncate can fail due to locking and have to close the
1853 file (which expects the share_mode_entry to be there).
1855 if (lp_share_modes(SNUM(cnum)))
1858 /* JRA. Currently this only services Exlcusive and batch
1859 oplocks (no other opens on this file). This needs to
1860 be extended to level II oplocks (multiple reader
1863 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
1865 fs_p->granted_oplock = True;
1866 global_oplocks_open++;
1869 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1870 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1878 set_share_mode(token, fnum, port, oplock_request);
1881 if ((flags2&O_TRUNC) && file_existed)
1882 truncate_unless_locked(fnum,cnum,token,&share_locked);
1885 if (share_locked && lp_share_modes(SNUM(cnum)))
1886 unlock_share_entry( cnum, dev, inode, token);
1889 /****************************************************************************
1890 seek a file. Try to avoid the seek if possible
1891 ****************************************************************************/
1892 int seek_file(int fnum,uint32 pos)
1895 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1898 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1900 return(Files[fnum].pos);
1903 /****************************************************************************
1905 ****************************************************************************/
1906 int read_file(int fnum,char *data,uint32 pos,int n)
1910 if (!Files[fnum].can_write)
1912 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1920 if (Files[fnum].mmap_ptr)
1922 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1925 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1937 if (seek_file(fnum,pos) != pos)
1939 DEBUG(3,("Failed to seek to %d\n",pos));
1944 readret = read(Files[fnum].fd_ptr->fd,data,n);
1945 if (readret > 0) ret += readret;
1952 /****************************************************************************
1954 ****************************************************************************/
1955 int write_file(int fnum,char *data,int n)
1957 if (!Files[fnum].can_write) {
1962 if (!Files[fnum].modified) {
1964 Files[fnum].modified = True;
1965 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1966 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1967 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1968 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1973 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1977 /****************************************************************************
1978 load parameters specific to a connection/service
1979 ****************************************************************************/
1980 BOOL become_service(int cnum,BOOL do_chdir)
1982 extern char magic_char;
1983 static int last_cnum = -1;
1986 if (!OPEN_CNUM(cnum))
1992 Connections[cnum].lastused = smb_last_time;
1997 ChDir(Connections[cnum].connectpath) != 0 &&
1998 ChDir(Connections[cnum].origpath) != 0)
2000 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2001 Connections[cnum].connectpath,cnum));
2005 if (cnum == last_cnum)
2010 case_default = lp_defaultcase(snum);
2011 case_preserve = lp_preservecase(snum);
2012 short_case_preserve = lp_shortpreservecase(snum);
2013 case_mangle = lp_casemangle(snum);
2014 case_sensitive = lp_casesensitive(snum);
2015 magic_char = lp_magicchar(snum);
2016 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2021 /****************************************************************************
2022 find a service entry
2023 ****************************************************************************/
2024 int find_service(char *service)
2028 string_sub(service,"\\","/");
2030 iService = lp_servicenumber(service);
2032 /* now handle the special case of a home directory */
2035 char *phome_dir = get_home_dir(service);
2036 DEBUG(3,("checking for home directory %s gave %s\n",service,
2037 phome_dir?phome_dir:"(NULL)"));
2041 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2043 lp_add_home(service,iHomeService,phome_dir);
2044 iService = lp_servicenumber(service);
2049 /* If we still don't have a service, attempt to add it as a printer. */
2052 int iPrinterService;
2054 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2058 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2060 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2062 DEBUG(3,("%s is a valid printer name\n", service));
2063 DEBUG(3,("adding %s as a printer service\n", service));
2064 lp_add_printer(service,iPrinterService);
2065 iService = lp_servicenumber(service);
2067 DEBUG(0,("failed to add %s as a printer service!\n", service));
2070 DEBUG(3,("%s is not a valid printer name\n", service));
2074 /* just possibly it's a default service? */
2077 char *defservice = lp_defaultservice();
2078 if (defservice && *defservice && !strequal(defservice,service)) {
2079 iService = find_service(defservice);
2080 if (iService >= 0) {
2081 string_sub(service,"_","/");
2082 iService = lp_add_service(service,iService);
2088 if (!VALID_SNUM(iService))
2090 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2095 DEBUG(3,("find_service() failed to find service %s\n", service));
2101 /****************************************************************************
2102 create an error packet from a cached error.
2103 ****************************************************************************/
2104 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2106 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2108 int32 eclass = wbmpx->wr_errclass;
2109 int32 err = wbmpx->wr_error;
2111 /* We can now delete the auxiliary struct */
2112 free((char *)wbmpx);
2113 Files[fnum].wbmpx_ptr = NULL;
2114 return error_packet(inbuf,outbuf,eclass,err,line);
2123 } unix_smb_errmap[] =
2125 {EPERM,ERRDOS,ERRnoaccess},
2126 {EACCES,ERRDOS,ERRnoaccess},
2127 {ENOENT,ERRDOS,ERRbadfile},
2128 {ENOTDIR,ERRDOS,ERRbadpath},
2129 {EIO,ERRHRD,ERRgeneral},
2130 {EBADF,ERRSRV,ERRsrverror},
2131 {EINVAL,ERRSRV,ERRsrverror},
2132 {EEXIST,ERRDOS,ERRfilexists},
2133 {ENFILE,ERRDOS,ERRnofids},
2134 {EMFILE,ERRDOS,ERRnofids},
2135 {ENOSPC,ERRHRD,ERRdiskfull},
2137 {EDQUOT,ERRHRD,ERRdiskfull},
2140 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2143 {EXDEV,ERRDOS,ERRdiffdevice},
2145 {EROFS,ERRHRD,ERRnowrite},
2149 /****************************************************************************
2150 create an error packet from errno
2151 ****************************************************************************/
2152 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2154 int eclass=def_class;
2158 if (unix_ERR_class != SUCCESS)
2160 eclass = unix_ERR_class;
2161 ecode = unix_ERR_code;
2162 unix_ERR_class = SUCCESS;
2167 while (unix_smb_errmap[i].smbclass != 0)
2169 if (unix_smb_errmap[i].unixerror == errno)
2171 eclass = unix_smb_errmap[i].smbclass;
2172 ecode = unix_smb_errmap[i].smbcode;
2179 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2183 /****************************************************************************
2184 create an error packet. Normally called using the ERROR() macro
2185 ****************************************************************************/
2186 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2188 int outsize = set_message(outbuf,0,0,True);
2190 cmd = CVAL(inbuf,smb_com);
2192 CVAL(outbuf,smb_rcls) = error_class;
2193 SSVAL(outbuf,smb_err,error_code);
2195 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2198 (int)CVAL(inbuf,smb_com),
2199 smb_fn_name(CVAL(inbuf,smb_com)),
2204 DEBUG(3,("error string = %s\n",strerror(errno)));
2210 #ifndef SIGCLD_IGNORE
2211 /****************************************************************************
2212 this prevents zombie child processes
2213 ****************************************************************************/
2214 static int sig_cld()
2216 static int depth = 0;
2219 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2225 BlockSignals(True,SIGCLD);
2226 DEBUG(5,("got SIGCLD\n"));
2229 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2233 /* Stevens, Adv. Unix Prog. says that on system V you must call
2234 wait before reinstalling the signal handler, because the kernel
2235 calls the handler from within the signal-call when there is a
2236 child that has exited. This would lead to an infinite recursion
2237 if done vice versa. */
2239 #ifndef DONT_REINSTALL_SIG
2240 #ifdef SIGCLD_IGNORE
2241 signal(SIGCLD, SIG_IGN);
2243 signal(SIGCLD, SIGNAL_CAST sig_cld);
2248 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2251 BlockSignals(False,SIGCLD);
2256 /****************************************************************************
2257 this is called when the client exits abruptly
2258 **************************************************************************/
2259 static int sig_pipe()
2261 extern int password_client;
2262 BlockSignals(True,SIGPIPE);
2264 if (password_client != -1) {
2265 DEBUG(3,("lost connection to password server\n"));
2266 close(password_client);
2267 password_client = -1;
2268 #ifndef DONT_REINSTALL_SIG
2269 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2271 BlockSignals(False,SIGPIPE);
2275 exit_server("Got sigpipe\n");
2279 /****************************************************************************
2280 open the socket communication
2281 ****************************************************************************/
2282 static BOOL open_sockets(BOOL is_daemon,int port)
2289 struct sockaddr addr;
2290 int in_addrlen = sizeof(addr);
2293 #ifdef SIGCLD_IGNORE
2294 signal(SIGCLD, SIG_IGN);
2296 signal(SIGCLD, SIGNAL_CAST sig_cld);
2299 /* open an incoming socket */
2300 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2304 /* ready to listen */
2305 if (listen(s, 5) == -1)
2307 DEBUG(0,("listen: %s\n",strerror(errno)));
2315 /* now accept incoming connections - forking a new process
2316 for each incoming connection */
2317 DEBUG(2,("waiting for a connection\n"));
2320 Client = accept(s,&addr,&in_addrlen);
2322 if (Client == -1 && errno == EINTR)
2327 DEBUG(0,("accept: %s\n",strerror(errno)));
2331 #ifdef NO_FORK_DEBUG
2332 #ifndef NO_SIGNAL_TEST
2333 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2334 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2338 if (Client != -1 && fork()==0)
2340 /* Child code ... */
2341 #ifndef NO_SIGNAL_TEST
2342 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2343 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2345 /* close the listening socket */
2348 /* close our standard file descriptors */
2352 set_socket_options(Client,"SO_KEEPALIVE");
2353 set_socket_options(Client,user_socket_options);
2355 /* Reset global variables in util.c so that
2356 client substitutions will be done correctly
2359 reset_globals_after_fork();
2362 close(Client); /* The parent doesn't need this socket */
2368 /* We will abort gracefully when the client or remote system
2370 #ifndef NO_SIGNAL_TEST
2371 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2375 /* close our standard file descriptors */
2378 set_socket_options(Client,"SO_KEEPALIVE");
2379 set_socket_options(Client,user_socket_options);
2385 /****************************************************************************
2386 process an smb from the client - split out from the process() code so
2387 it can be used by the oplock break code.
2388 ****************************************************************************/
2390 static void process_smb(char *inbuf, char *outbuf)
2393 static int trans_num;
2394 int msg_type = CVAL(inbuf,0);
2395 int32 len = smb_len(inbuf);
2396 int nread = len + 4;
2398 if (trans_num == 0) {
2399 /* on the first packet, check the global hosts allow/ hosts
2400 deny parameters before doing any parsing of the packet
2401 passed to us by the client. This prevents attacks on our
2402 parsing code from hosts not in the hosts allow list */
2403 if (!check_access(-1)) {
2404 /* send a negative session response "not listining on calling
2406 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2407 DEBUG(1,("%s Connection denied from %s\n",
2408 timestring(),client_addr()));
2409 send_smb(Client,(char *)buf);
2410 exit_server("connection denied");
2414 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2415 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2418 if(trans_num == 1 && VT_Check(inbuf))
2428 nread = construct_reply(inbuf,outbuf,nread,max_send);
2432 if (CVAL(outbuf,0) == 0)
2435 if (nread != smb_len(outbuf) + 4)
2437 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2438 nread, smb_len(outbuf)));
2441 send_smb(Client,outbuf);
2446 /****************************************************************************
2447 open the oplock IPC socket communication
2448 ****************************************************************************/
2449 static BOOL open_oplock_ipc()
2451 struct sockaddr_in sock_name;
2452 int len = sizeof(sock_name);
2454 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2456 /* Open a lookback UDP socket on a random port. */
2457 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2458 if (oplock_sock == -1)
2460 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2461 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2466 /* Find out the transient UDP port we have been allocated. */
2467 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2469 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2476 oplock_port = ntohs(sock_name.sin_port);
2478 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2479 getpid(), oplock_port));
2484 /****************************************************************************
2485 process an oplock break message.
2486 ****************************************************************************/
2487 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2493 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2494 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2496 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2498 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2499 msg_len, from_port));
2501 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2502 only valid request. */
2504 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2506 case OPLOCK_BREAK_CMD:
2507 /* Ensure that the msg length is correct. */
2508 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2510 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2511 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2515 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2516 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2517 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2518 struct timeval tval;
2519 struct sockaddr_in toaddr;
2521 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2522 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2524 DEBUG(5,("process_local_message: oplock break request from \
2525 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2528 * If we have no record of any currently open oplocks,
2529 * it's not an error, as a close command may have
2530 * just been issued on the file that was oplocked.
2531 * Just return success in this case.
2534 if(global_oplocks_open != 0)
2536 if(oplock_break(dev, inode, &tval) == False)
2538 DEBUG(0,("process_local_message: oplock break failed - \
2539 not returning udp message.\n"));
2545 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2546 oplocks. Returning success.\n"));
2549 /* Send the message back after OR'ing in the 'REPLY' bit. */
2550 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2552 bzero((char *)&toaddr,sizeof(toaddr));
2553 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2554 toaddr.sin_port = htons(from_port);
2555 toaddr.sin_family = AF_INET;
2557 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2558 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2560 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2561 remotepid, strerror(errno)));
2565 DEBUG(5,("process_local_message: oplock break reply sent to \
2566 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2567 from_port, dev, inode));
2572 * Keep this as a debug case - eventually we can remove it.
2575 DEBUG(0,("process_local_message: Received unsolicited break \
2576 reply - dumping info.\n"));
2578 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2580 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2581 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2586 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2587 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2588 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2590 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2591 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2597 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2598 (unsigned int)SVAL(msg_start,0)));
2604 /****************************************************************************
2605 Process an oplock break directly.
2606 ****************************************************************************/
2607 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2610 static char *inbuf = NULL;
2611 static char *outbuf = NULL;
2612 files_struct *fsp = NULL;
2615 BOOL shutdown_server = False;
2617 DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \
2618 global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
2622 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2624 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2627 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2628 if(outbuf == NULL) {
2629 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2636 /* We need to search the file open table for the
2637 entry containing this dev and inode, and ensure
2638 we have an oplock on it. */
2639 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2644 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2645 (fsp->open_time.tv_sec == tval->tv_sec) &&
2646 (fsp->open_time.tv_usec == tval->tv_usec))
2653 /* The file could have been closed in the meantime - return success. */
2654 DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2655 allowing break to succeed.\n", dev, inode, fnum));
2659 /* Ensure we have an oplock on the file */
2661 /* There is a potential race condition in that an oplock could
2662 have been broken due to another udp request, and yet there are
2663 still oplock break messages being sent in the udp message
2664 queue for this file. So return true if we don't have an oplock,
2665 as we may have just freed it.
2668 if(!fsp->granted_oplock)
2670 DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2671 Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode));
2675 /* Now comes the horrid part. We must send an oplock break to the client,
2676 and then process incoming messages until we get a close or oplock release.
2679 /* Prepare the SMBlockingX message. */
2680 bzero(outbuf,smb_size);
2681 set_message(outbuf,8,0,True);
2683 SCVAL(outbuf,smb_com,SMBlockingX);
2684 SSVAL(outbuf,smb_tid,fsp->cnum);
2685 SSVAL(outbuf,smb_pid,0xFFFF);
2686 SSVAL(outbuf,smb_uid,0);
2687 SSVAL(outbuf,smb_mid,0xFFFF);
2688 SCVAL(outbuf,smb_vwv0,0xFF);
2689 SSVAL(outbuf,smb_vwv2,fnum);
2690 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2691 /* Change this when we have level II oplocks. */
2692 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2694 send_smb(Client, outbuf);
2696 global_oplock_break = True;
2698 /* Process incoming messages. */
2700 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2701 seconds we should just die.... */
2703 start_time = time(NULL);
2705 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2707 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2710 * Die if we got an error.
2713 if (smb_read_error == READ_EOF)
2714 DEBUG(0,("oplock_break: end of file from client\n"));
2716 if (smb_read_error == READ_ERROR)
2717 DEBUG(0,("oplock_break: receive_smb error (%s)\n",
2720 if (smb_read_error == READ_TIMEOUT)
2721 DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n",
2722 OPLOCK_BREAK_TIMEOUT));
2724 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2725 inode = %x).\n", fsp->name, fnum, dev, inode));
2726 shutdown_server = True;
2729 process_smb(inbuf, outbuf);
2731 /* We only need this in case a readraw crossed on the wire. */
2732 if(global_oplock_break)
2733 global_oplock_break = False;
2736 * Die if we go over the time limit.
2739 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2741 DEBUG(0,("oplock_break: no break received from client within \
2742 %d seconds.\n", OPLOCK_BREAK_TIMEOUT));
2743 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2744 inode = %x).\n", fsp->name, fnum, dev, inode));
2745 shutdown_server = True;
2751 * If the client did not respond we must die.
2756 DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n"));
2759 exit_server("oplock break failure");
2764 /* The lockingX reply will have removed the oplock flag
2765 from the sharemode. */
2767 fsp->granted_oplock = False;
2770 global_oplocks_open--;
2772 /* Santity check - remove this later. JRA */
2773 if(global_oplocks_open < 0)
2775 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2776 global_oplocks_open));
2777 exit_server("oplock_break: global_oplocks_open < 0");
2780 DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2781 global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open));
2786 /****************************************************************************
2787 Send an oplock break message to another smbd process. If the oplock is held
2788 by the local smbd then call the oplock break function directly.
2789 ****************************************************************************/
2791 BOOL request_oplock_break(min_share_mode_entry *share_entry,
2792 uint32 dev, uint32 inode)
2794 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2795 struct sockaddr_in addr_out;
2798 if(pid == share_entry->pid)
2800 /* We are breaking our own oplock, make sure it's us. */
2801 if(share_entry->op_port != oplock_port)
2803 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2804 should be %d\n", pid, share_entry->op_port, oplock_port));
2808 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2810 /* Call oplock break direct. */
2811 return oplock_break(dev, inode, &share_entry->time);
2814 /* We need to send a OPLOCK_BREAK_CMD message to the
2815 port in the share mode entry. */
2817 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2818 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2819 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2820 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2821 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2822 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2824 /* set the address and port */
2825 bzero((char *)&addr_out,sizeof(addr_out));
2826 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2827 addr_out.sin_port = htons( share_entry->op_port );
2828 addr_out.sin_family = AF_INET;
2830 DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \
2831 for dev = %x, inode = %x\n", share_entry->pid, share_entry->op_port, dev, inode));
2833 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2834 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2836 DEBUG(0,("request_oplock_break: failed when sending a oplock break message \
2837 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2838 share_entry->pid, share_entry->op_port, dev, inode,
2844 * Now we must await the oplock broken message coming back
2845 * from the target smbd process. Timeout if it fails to
2846 * return in OPLOCK_BREAK_TIMEOUT seconds.
2847 * While we get messages that aren't ours, loop.
2852 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
2853 int32 reply_msg_len;
2854 int16 reply_from_port;
2855 char *reply_msg_start;
2857 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
2858 OPLOCK_BREAK_TIMEOUT * 1000) == False)
2860 if(smb_read_error == READ_TIMEOUT)
2861 DEBUG(0,("request_oplock_break: no response received to oplock break request to \
2862 pid %d on port %d for dev = %x, inode = %x\n", share_entry->pid,
2863 share_entry->op_port, dev, inode));
2865 DEBUG(0,("request_oplock_break: error in response received to oplock break request to \
2866 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry->pid,
2867 share_entry->op_port, dev, inode, strerror(errno)));
2872 * If the response we got was not an answer to our message, but
2873 * was a completely different request, push it onto the pending
2874 * udp message stack so that we can deal with it in the main loop.
2875 * It may be another oplock break request to us.
2879 * Local note from JRA. There exists the possibility of a denial
2880 * of service attack here by allowing non-root processes running
2881 * on a local machine sending many of these pending messages to
2882 * a smbd port. Currently I'm not sure how to restrict the messages
2883 * I will queue (although I could add a limit to the queue) to
2884 * those received by root processes only. There should be a
2885 * way to make this bulletproof....
2888 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
2889 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
2891 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
2893 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
2896 DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n"));
2900 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
2901 (reply_from_port != share_entry->op_port) ||
2902 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
2903 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
2904 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
2906 DEBUG(3,("request_oplock_break: received other message whilst awaiting \
2907 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
2908 share_entry->pid, share_entry->op_port, dev, inode));
2909 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
2917 DEBUG(3,("request_oplock_break: broke oplock.\n"));
2922 /****************************************************************************
2923 check if a snum is in use
2924 ****************************************************************************/
2925 BOOL snum_used(int snum)
2928 for (i=0;i<MAX_CONNECTIONS;i++)
2929 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2934 /****************************************************************************
2935 reload the services file
2936 **************************************************************************/
2937 BOOL reload_services(BOOL test)
2944 pstrcpy(fname,lp_configfile());
2945 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2947 pstrcpy(servicesf,fname);
2954 if (test && !lp_file_list_changed())
2957 lp_killunused(snum_used);
2959 ret = lp_load(servicesf,False);
2961 /* perhaps the config filename is now set */
2963 reload_services(True);
2972 set_socket_options(Client,"SO_KEEPALIVE");
2973 set_socket_options(Client,user_socket_options);
2977 create_mangled_stack(lp_mangledstack());
2979 /* this forces service parameters to be flushed */
2980 become_service(-1,True);
2987 /****************************************************************************
2988 this prevents zombie child processes
2989 ****************************************************************************/
2990 static int sig_hup()
2992 BlockSignals(True,SIGHUP);
2993 DEBUG(0,("Got SIGHUP\n"));
2994 reload_services(False);
2995 #ifndef DONT_REINSTALL_SIG
2996 signal(SIGHUP,SIGNAL_CAST sig_hup);
2998 BlockSignals(False,SIGHUP);
3002 /****************************************************************************
3003 Setup the groups a user belongs to.
3004 ****************************************************************************/
3005 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3006 int **p_igroups, gid_t **p_groups)
3008 if (-1 == initgroups(user,gid))
3012 DEBUG(0,("Unable to initgroups!\n"));
3013 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3014 DEBUG(0,("This is probably a problem with the account %s\n",user));
3022 ngroups = getgroups(0,&grp);
3025 igroups = (int *)malloc(sizeof(int)*ngroups);
3026 for (i=0;i<ngroups;i++)
3027 igroups[i] = 0x42424242;
3028 ngroups = getgroups(ngroups,(gid_t *)igroups);
3030 if (igroups[0] == 0x42424242)
3033 *p_ngroups = ngroups;
3035 /* The following bit of code is very strange. It is due to the
3036 fact that some OSes use int* and some use gid_t* for
3037 getgroups, and some (like SunOS) use both, one in prototypes,
3038 and one in man pages and the actual code. Thus we detect it
3039 dynamically using some very ugly code */
3042 /* does getgroups return ints or gid_t ?? */
3043 static BOOL groups_use_ints = True;
3045 if (groups_use_ints &&
3047 SVAL(igroups,2) == 0x4242)
3048 groups_use_ints = False;
3050 for (i=0;groups_use_ints && i<ngroups;i++)
3051 if (igroups[i] == 0x42424242)
3052 groups_use_ints = False;
3054 if (groups_use_ints)
3056 *p_igroups = igroups;
3057 *p_groups = (gid_t *)igroups;
3061 gid_t *groups = (gid_t *)igroups;
3062 igroups = (int *)malloc(sizeof(int)*ngroups);
3063 for (i=0;i<ngroups;i++)
3064 igroups[i] = groups[i];
3065 *p_igroups = igroups;
3066 *p_groups = (gid_t *)groups;
3069 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3070 for (i=0;i<ngroups;i++)
3071 DEBUG(3,("%d ",igroups[i]));
3077 /****************************************************************************
3078 make a connection to a service
3079 ****************************************************************************/
3080 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3084 struct passwd *pass = NULL;
3085 connection_struct *pcon;
3088 static BOOL first_connection = True;
3092 snum = find_service(service);
3095 if (strequal(service,"IPC$"))
3097 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3101 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3105 if (strequal(service,HOMES_NAME))
3107 if (*user && Get_Pwnam(user,True))
3108 return(make_connection(user,user,password,pwlen,dev,vuid));
3110 if (validated_username(vuid))
3112 strcpy(user,validated_username(vuid));
3113 return(make_connection(user,user,password,pwlen,dev,vuid));
3117 if (!lp_snum_ok(snum) || !check_access(snum)) {
3121 /* you can only connect to the IPC$ service as an ipc device */
3122 if (strequal(service,"IPC$"))
3125 if (*dev == '?' || !*dev)
3127 if (lp_print_ok(snum))
3128 strcpy(dev,"LPT1:");
3133 /* if the request is as a printer and you can't print then refuse */
3135 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3136 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3140 /* lowercase the user name */
3143 /* add it as a possible user name */
3144 add_session_user(service);
3146 /* shall we let them in? */
3147 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3149 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3153 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3156 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3160 pcon = &Connections[cnum];
3161 bzero((char *)pcon,sizeof(*pcon));
3163 /* find out some info about the user */
3164 pass = Get_Pwnam(user,True);
3168 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3172 pcon->read_only = lp_readonly(snum);
3176 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3177 string_sub(list,"%S",service);
3179 if (user_in_list(user,list))
3180 pcon->read_only = True;
3182 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3183 string_sub(list,"%S",service);
3185 if (user_in_list(user,list))
3186 pcon->read_only = False;
3189 /* admin user check */
3191 /* JRA - original code denied admin user if the share was
3192 marked read_only. Changed as I don't think this is needed,
3193 but old code left in case there is a problem here.
3195 if (user_in_list(user,lp_admin_users(snum))
3197 && !pcon->read_only)
3202 pcon->admin_user = True;
3203 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3206 pcon->admin_user = False;
3208 pcon->force_user = force;
3210 pcon->uid = pass->pw_uid;
3211 pcon->gid = pass->pw_gid;
3212 pcon->num_files_open = 0;
3213 pcon->lastused = time(NULL);
3214 pcon->service = snum;
3216 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3217 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3218 pcon->dirptr = NULL;
3219 pcon->veto_list = NULL;
3220 pcon->hide_list = NULL;
3221 string_set(&pcon->dirpath,"");
3222 string_set(&pcon->user,user);
3225 if (*lp_force_group(snum))
3230 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3231 /* default service may be a group name */
3232 string_sub(gname,"%S",service);
3233 gptr = (struct group *)getgrnam(gname);
3237 pcon->gid = gptr->gr_gid;
3238 DEBUG(3,("Forced group %s\n",gname));
3241 DEBUG(1,("Couldn't find group %s\n",gname));
3245 if (*lp_force_user(snum))
3247 struct passwd *pass2;
3249 fstrcpy(fuser,lp_force_user(snum));
3250 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3253 pcon->uid = pass2->pw_uid;
3254 string_set(&pcon->user,fuser);
3255 fstrcpy(user,fuser);
3256 pcon->force_user = True;
3257 DEBUG(3,("Forced user %s\n",fuser));
3260 DEBUG(1,("Couldn't find user %s\n",fuser));
3265 pstrcpy(s,lp_pathname(snum));
3266 standard_sub(cnum,s);
3267 string_set(&pcon->connectpath,s);
3268 DEBUG(3,("Connect path is %s\n",s));
3271 /* groups stuff added by ih */
3273 pcon->groups = NULL;
3277 /* Find all the groups this uid is in and store them. Used by become_user() */
3278 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
3280 /* check number of connections */
3281 if (!claim_connection(cnum,
3282 lp_servicename(SNUM(cnum)),
3283 lp_max_connections(SNUM(cnum)),False))
3285 DEBUG(1,("too many connections - rejected\n"));
3289 if (lp_status(SNUM(cnum)))
3290 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3292 first_connection = False;
3297 /* execute any "root preexec = " line */
3298 if (*lp_rootpreexec(SNUM(cnum)))
3301 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3302 standard_sub(cnum,cmd);
3303 DEBUG(5,("cmd=%s\n",cmd));
3304 smbrun(cmd,NULL,False);
3307 if (!become_user(cnum,pcon->vuid))
3309 DEBUG(0,("Can't become connected user!\n"));
3311 if (!IS_IPC(cnum)) {
3312 yield_connection(cnum,
3313 lp_servicename(SNUM(cnum)),
3314 lp_max_connections(SNUM(cnum)));
3315 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3320 if (ChDir(pcon->connectpath) != 0)
3322 DEBUG(0,("Can't change directory to %s (%s)\n",
3323 pcon->connectpath,strerror(errno)));
3326 if (!IS_IPC(cnum)) {
3327 yield_connection(cnum,
3328 lp_servicename(SNUM(cnum)),
3329 lp_max_connections(SNUM(cnum)));
3330 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3335 string_set(&pcon->origpath,pcon->connectpath);
3337 #if SOFTLINK_OPTIMISATION
3338 /* resolve any soft links early */
3341 pstrcpy(s,pcon->connectpath);
3343 string_set(&pcon->connectpath,s);
3344 ChDir(pcon->connectpath);
3348 num_connections_open++;
3349 add_session_user(user);
3351 /* execute any "preexec = " line */
3352 if (*lp_preexec(SNUM(cnum)))
3355 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3356 standard_sub(cnum,cmd);
3357 smbrun(cmd,NULL,False);
3360 /* we've finished with the sensitive stuff */
3363 /* Add veto/hide lists */
3364 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3366 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3367 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3371 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3375 lp_servicename(SNUM(cnum)),user,
3385 /****************************************************************************
3386 find first available file slot
3387 ****************************************************************************/
3388 int find_free_file(void )
3391 /* we start at 1 here for an obscure reason I can't now remember,
3392 but I think is important :-) */
3393 for (i=1;i<MAX_OPEN_FILES;i++)
3396 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3400 /****************************************************************************
3401 find first available connection slot, starting from a random position.
3402 The randomisation stops problems with the server dieing and clients
3403 thinking the server is still available.
3404 ****************************************************************************/
3405 static int find_free_connection(int hash )
3409 hash = (hash % (MAX_CONNECTIONS-2))+1;
3413 for (i=hash+1;i!=hash;)
3415 if (!Connections[i].open && Connections[i].used == used)
3417 DEBUG(3,("found free connection number %d\n",i));
3421 if (i == MAX_CONNECTIONS)
3431 DEBUG(1,("ERROR! Out of connection structures\n"));
3436 /****************************************************************************
3437 reply for the core protocol
3438 ****************************************************************************/
3439 int reply_corep(char *outbuf)
3441 int outsize = set_message(outbuf,1,0,True);
3443 Protocol = PROTOCOL_CORE;
3449 /****************************************************************************
3450 reply for the coreplus protocol
3451 ****************************************************************************/
3452 int reply_coreplus(char *outbuf)
3454 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3455 int outsize = set_message(outbuf,13,0,True);
3456 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3457 readbraw and writebraw (possibly) */
3458 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3459 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3461 Protocol = PROTOCOL_COREPLUS;
3467 /****************************************************************************
3468 reply for the lanman 1.0 protocol
3469 ****************************************************************************/
3470 int reply_lanman1(char *outbuf)
3472 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3474 BOOL doencrypt = SMBENCRYPT();
3475 time_t t = time(NULL);
3476 /* We need to save and restore this as it can be destroyed
3477 if we call another server if security=server
3478 Thanks to Paul Nelson @ Thursby for pointing this out.
3480 uint16 mid = SVAL(outbuf, smb_mid);
3482 if (lp_security()>=SEC_USER) secword |= 1;
3483 if (doencrypt) secword |= 2;
3485 set_message(outbuf,13,doencrypt?8:0,True);
3486 SSVAL(outbuf,smb_vwv1,secword);
3487 /* Create a token value and add it to the outgoing packet. */
3489 generate_next_challenge(smb_buf(outbuf));
3491 Protocol = PROTOCOL_LANMAN1;
3493 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3494 DEBUG(3,("using password server validation\n"));
3495 if (doencrypt) set_challenge(smb_buf(outbuf));
3498 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3499 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3500 SSVAL(outbuf,smb_vwv2,max_recv);
3501 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3502 SSVAL(outbuf,smb_vwv4,1);
3503 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3504 readbraw writebraw (possibly) */
3505 SIVAL(outbuf,smb_vwv6,getpid());
3506 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3508 put_dos_date(outbuf,smb_vwv8,t);
3510 return (smb_len(outbuf)+4);
3514 /****************************************************************************
3515 reply for the lanman 2.0 protocol
3516 ****************************************************************************/
3517 int reply_lanman2(char *outbuf)
3519 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3521 BOOL doencrypt = SMBENCRYPT();
3522 time_t t = time(NULL);
3523 /* We need to save and restore this as it can be destroyed
3524 if we call another server if security=server
3525 Thanks to Paul Nelson @ Thursby for pointing this out.
3527 uint16 mid = SVAL(outbuf, smb_mid);
3529 if (lp_security()>=SEC_USER) secword |= 1;
3530 if (doencrypt) secword |= 2;
3532 set_message(outbuf,13,doencrypt?8:0,True);
3533 SSVAL(outbuf,smb_vwv1,secword);
3534 /* Create a token value and add it to the outgoing packet. */
3536 generate_next_challenge(smb_buf(outbuf));
3538 SIVAL(outbuf,smb_vwv6,getpid());
3540 Protocol = PROTOCOL_LANMAN2;
3542 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3543 DEBUG(3,("using password server validation\n"));
3544 if (doencrypt) set_challenge(smb_buf(outbuf));
3547 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3548 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3549 SSVAL(outbuf,smb_vwv2,max_recv);
3550 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3551 SSVAL(outbuf,smb_vwv4,1);
3552 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3553 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3554 put_dos_date(outbuf,smb_vwv8,t);
3556 return (smb_len(outbuf)+4);
3560 /****************************************************************************
3561 reply for the nt protocol
3562 ****************************************************************************/
3563 int reply_nt1(char *outbuf)
3565 /* dual names + lock_and_read + nt SMBs + remote API calls */
3566 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3568 other valid capabilities which we may support at some time...
3569 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3570 CAP_LARGE_FILES|CAP_LARGE_READX|
3571 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3575 BOOL doencrypt = SMBENCRYPT();
3576 time_t t = time(NULL);
3579 char challenge_len = 8;
3580 /* We need to save and restore this as it can be destroyed
3581 if we call another server if security=server
3582 Thanks to Paul Nelson @ Thursby for pointing this out.
3584 uint16 mid = SVAL(outbuf, smb_mid);
3586 if (lp_readraw() && lp_writeraw())
3588 capabilities |= CAP_RAW_MODE;
3591 if (lp_security()>=SEC_USER) secword |= 1;
3592 if (doencrypt) secword |= 2;
3594 /* decide where (if) to put the encryption challenge, and
3595 follow it with the OEM'd domain name
3597 encrypt_len = doencrypt?challenge_len:0;
3599 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3601 data_len = encrypt_len + strlen(myworkgroup) + 1;
3604 set_message(outbuf,17,data_len,True);
3607 /* put the OEM'd domain name */
3608 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3610 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3613 CVAL(outbuf,smb_vwv1) = secword;
3614 /* Create a token value and add it to the outgoing packet. */
3617 generate_next_challenge(smb_buf(outbuf));
3619 /* Tell the nt machine how long the challenge is. */
3620 SSVALS(outbuf,smb_vwv16+1,challenge_len);
3623 Protocol = PROTOCOL_NT1;
3625 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3626 DEBUG(3,("using password server validation\n"));
3627 if (doencrypt) set_challenge(smb_buf(outbuf));
3630 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3631 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3632 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3633 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3634 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3635 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3636 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3637 put_long_date(outbuf+smb_vwv11+1,t);
3638 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3639 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3641 return (smb_len(outbuf)+4);
3644 /* these are the protocol lists used for auto architecture detection:
3647 protocol [PC NETWORK PROGRAM 1.0]
3648 protocol [XENIX CORE]
3649 protocol [MICROSOFT NETWORKS 1.03]
3650 protocol [LANMAN1.0]
3651 protocol [Windows for Workgroups 3.1a]
3652 protocol [LM1.2X002]
3653 protocol [LANMAN2.1]
3654 protocol [NT LM 0.12]
3657 protocol [PC NETWORK PROGRAM 1.0]
3658 protocol [XENIX CORE]
3659 protocol [MICROSOFT NETWORKS 1.03]
3660 protocol [LANMAN1.0]
3661 protocol [Windows for Workgroups 3.1a]
3662 protocol [LM1.2X002]
3663 protocol [LANMAN2.1]
3664 protocol [NT LM 0.12]
3667 protocol [PC NETWORK PROGRAM 1.0]
3668 protocol [XENIX CORE]
3669 protocol [LANMAN1.0]
3670 protocol [LM1.2X002]
3671 protocol [LANMAN2.1]
3675 * Modified to recognize the architecture of the remote machine better.
3677 * This appears to be the matrix of which protocol is used by which
3679 Protocol WfWg Win95 WinNT OS/2
3680 PC NETWORK PROGRAM 1.0 1 1 1 1
3682 MICROSOFT NETWORKS 3.0 2 2
3684 MICROSOFT NETWORKS 1.03 3
3687 Windows for Workgroups 3.1a 5 5 5
3692 * tim@fsg.com 09/29/95
3695 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3696 #define ARCH_WIN95 0x2
3697 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3698 #define ARCH_WINNT 0x8
3699 #define ARCH_SAMBA 0x10
3701 #define ARCH_ALL 0x1F
3703 /* List of supported protocols, most desired first */
3707 int (*proto_reply_fn)(char *);
3709 } supported_protocols[] = {
3710 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3711 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3712 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3713 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3714 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3715 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3716 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3717 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3718 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3723 /****************************************************************************
3725 ****************************************************************************/
3726 static int reply_negprot(char *inbuf,char *outbuf)
3728 int outsize = set_message(outbuf,1,0,True);
3733 int bcc = SVAL(smb_buf(inbuf),-2);
3734 int arch = ARCH_ALL;
3736 p = smb_buf(inbuf)+1;
3737 while (p < (smb_buf(inbuf) + bcc))
3740 DEBUG(3,("Requested protocol [%s]\n",p));
3741 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3742 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3743 else if (strcsequal(p,"DOS LM1.2X002"))
3744 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3745 else if (strcsequal(p,"DOS LANMAN2.1"))
3746 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3747 else if (strcsequal(p,"NT LM 0.12"))
3748 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3749 else if (strcsequal(p,"LANMAN2.1"))
3750 arch &= ( ARCH_WINNT | ARCH_OS2 );
3751 else if (strcsequal(p,"LM1.2X002"))
3752 arch &= ( ARCH_WINNT | ARCH_OS2 );
3753 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3755 else if (strcsequal(p,"XENIX CORE"))
3756 arch &= ( ARCH_WINNT | ARCH_OS2 );
3757 else if (strcsequal(p,"Samba")) {
3767 set_remote_arch(RA_SAMBA);
3770 set_remote_arch(RA_WFWG);
3773 set_remote_arch(RA_WIN95);
3776 set_remote_arch(RA_WINNT);
3779 set_remote_arch(RA_OS2);
3782 set_remote_arch(RA_UNKNOWN);
3786 /* possibly reload - change of architecture */
3787 reload_services(True);
3789 /* a special case to stop password server loops */
3790 if (Index == 1 && strequal(remote_machine,myhostname) &&
3791 lp_security()==SEC_SERVER)
3792 exit_server("Password server loop!");
3794 /* Check for protocols, most desirable first */
3795 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3797 p = smb_buf(inbuf)+1;
3799 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3800 while (p < (smb_buf(inbuf) + bcc))
3802 if (strequal(p,supported_protocols[protocol].proto_name))
3811 SSVAL(outbuf,smb_vwv0,choice);
3813 extern fstring remote_proto;
3814 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3815 reload_services(True);
3816 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3817 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3820 DEBUG(0,("No protocol supported !\n"));
3822 SSVAL(outbuf,smb_vwv0,choice);
3824 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3830 /****************************************************************************
3831 close all open files for a connection
3832 ****************************************************************************/
3833 static void close_open_files(int cnum)
3836 for (i=0;i<MAX_OPEN_FILES;i++)
3837 if( Files[i].cnum == cnum && Files[i].open) {
3844 /****************************************************************************
3846 ****************************************************************************/
3847 void close_cnum(int cnum, uint16 vuid)
3849 DirCacheFlush(SNUM(cnum));
3853 if (!OPEN_CNUM(cnum))
3855 DEBUG(0,("Can't close cnum %d\n",cnum));
3859 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3861 remote_machine,client_addr(),
3862 lp_servicename(SNUM(cnum))));
3864 yield_connection(cnum,
3865 lp_servicename(SNUM(cnum)),
3866 lp_max_connections(SNUM(cnum)));
3868 if (lp_status(SNUM(cnum)))
3869 yield_connection(cnum,"STATUS.",MAXSTATUS);
3871 close_open_files(cnum);
3872 dptr_closecnum(cnum);
3874 /* execute any "postexec = " line */
3875 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3878 strcpy(cmd,lp_postexec(SNUM(cnum)));
3879 standard_sub(cnum,cmd);
3880 smbrun(cmd,NULL,False);
3885 /* execute any "root postexec = " line */
3886 if (*lp_rootpostexec(SNUM(cnum)))
3889 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3890 standard_sub(cnum,cmd);
3891 smbrun(cmd,NULL,False);
3894 Connections[cnum].open = False;
3895 num_connections_open--;
3896 if (Connections[cnum].ngroups && Connections[cnum].groups)
3898 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3899 free(Connections[cnum].groups);
3900 free(Connections[cnum].igroups);
3901 Connections[cnum].groups = NULL;
3902 Connections[cnum].igroups = NULL;
3903 Connections[cnum].ngroups = 0;
3906 free_namearray(Connections[cnum].veto_list);
3907 free_namearray(Connections[cnum].hide_list);
3909 string_set(&Connections[cnum].user,"");
3910 string_set(&Connections[cnum].dirpath,"");
3911 string_set(&Connections[cnum].connectpath,"");
3915 /****************************************************************************
3916 simple routines to do connection counting
3917 ****************************************************************************/
3918 BOOL yield_connection(int cnum,char *name,int max_connections)
3920 struct connect_record crec;
3923 int mypid = getpid();
3926 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3928 if (max_connections <= 0)
3931 bzero(&crec,sizeof(crec));
3933 pstrcpy(fname,lp_lockdir());
3934 standard_sub(cnum,fname);
3935 trim_string(fname,"","/");
3939 strcat(fname,".LCK");
3941 f = fopen(fname,"r+");
3944 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3948 fseek(f,0,SEEK_SET);
3950 /* find a free spot */
3951 for (i=0;i<max_connections;i++)
3953 if (fread(&crec,sizeof(crec),1,f) != 1)
3955 DEBUG(2,("Entry not found in lock file %s\n",fname));
3959 if (crec.pid == mypid && crec.cnum == cnum)
3963 if (crec.pid != mypid || crec.cnum != cnum)
3966 DEBUG(2,("Entry not found in lock file %s\n",fname));
3970 bzero((void *)&crec,sizeof(crec));
3972 /* remove our mark */
3973 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3974 fwrite(&crec,sizeof(crec),1,f) != 1)
3976 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3981 DEBUG(3,("Yield successful\n"));
3988 /****************************************************************************
3989 simple routines to do connection counting
3990 ****************************************************************************/
3991 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3993 struct connect_record crec;
3996 int snum = SNUM(cnum);
4000 if (max_connections <= 0)
4003 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4005 pstrcpy(fname,lp_lockdir());
4006 standard_sub(cnum,fname);
4007 trim_string(fname,"","/");
4009 if (!directory_exist(fname,NULL))
4014 strcat(fname,".LCK");
4016 if (!file_exist(fname,NULL))
4018 int oldmask = umask(022);
4019 f = fopen(fname,"w");
4024 total_recs = file_size(fname) / sizeof(crec);
4026 f = fopen(fname,"r+");
4030 DEBUG(1,("couldn't open lock file %s\n",fname));
4034 /* find a free spot */
4035 for (i=0;i<max_connections;i++)
4038 if (i>=total_recs ||
4039 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4040 fread(&crec,sizeof(crec),1,f) != 1)
4042 if (foundi < 0) foundi = i;
4046 if (Clear && crec.pid && !process_exists(crec.pid))
4048 fseek(f,i*sizeof(crec),SEEK_SET);
4049 bzero((void *)&crec,sizeof(crec));
4050 fwrite(&crec,sizeof(crec),1,f);
4051 if (foundi < 0) foundi = i;
4054 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4063 DEBUG(3,("no free locks in %s\n",fname));
4068 /* fill in the crec */
4069 bzero((void *)&crec,sizeof(crec));
4070 crec.magic = 0x280267;
4071 crec.pid = getpid();
4073 crec.uid = Connections[cnum].uid;
4074 crec.gid = Connections[cnum].gid;
4075 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4076 crec.start = time(NULL);
4078 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4079 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4082 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4083 fwrite(&crec,sizeof(crec),1,f) != 1)
4094 /*******************************************************************
4095 prepare to dump a core file - carefully!
4096 ********************************************************************/
4097 static BOOL dump_core(void)
4101 pstrcpy(dname,debugf);
4102 if ((p=strrchr(dname,'/'))) *p=0;
4103 strcat(dname,"/corefiles");
4105 sys_chown(dname,getuid(),getgid());
4107 if (chdir(dname)) return(False);
4110 #ifndef NO_GETRLIMIT
4114 getrlimit(RLIMIT_CORE, &rlp);
4115 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4116 setrlimit(RLIMIT_CORE, &rlp);
4117 getrlimit(RLIMIT_CORE, &rlp);
4118 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4124 DEBUG(0,("Dumping core in %s\n",dname));
4129 /****************************************************************************
4131 ****************************************************************************/
4132 void exit_server(char *reason)
4134 static int firsttime=1;
4137 if (!firsttime) exit(0);
4141 DEBUG(2,("Closing connections\n"));
4142 for (i=0;i<MAX_CONNECTIONS;i++)
4143 if (Connections[i].open)
4144 close_cnum(i,(uint16)-1);
4146 if (dcelogin_atmost_once)
4150 int oldlevel = DEBUGLEVEL;
4152 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4154 show_msg(last_inbuf);
4155 DEBUGLEVEL = oldlevel;
4156 DEBUG(0,("===============================================================\n"));
4158 if (dump_core()) return;
4162 #ifdef FAST_SHARE_MODES
4163 stop_share_mode_mgmt();
4164 #endif /* FAST_SHARE_MODES */
4166 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4170 /****************************************************************************
4171 do some standard substitutions in a string
4172 ****************************************************************************/
4173 void standard_sub(int cnum,char *str)
4175 if (VALID_CNUM(cnum)) {
4178 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4180 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4181 string_sub(p,"%H",home);
4185 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4186 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4187 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4188 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4189 case '\0' : p++; break; /* don't run off the end of the string */
4190 default : p+=2; break;
4194 standard_sub_basic(str);
4198 These flags determine some of the permissions required to do an operation
4200 Note that I don't set NEED_WRITE on some write operations because they
4201 are used by some brain-dead clients when printing, and I don't want to
4202 force write permissions on print services.
4204 #define AS_USER (1<<0)
4205 #define NEED_WRITE (1<<1)
4206 #define TIME_INIT (1<<2)
4207 #define CAN_IPC (1<<3)
4208 #define AS_GUEST (1<<5)
4212 define a list of possible SMB messages and their corresponding
4213 functions. Any message that has a NULL function is unimplemented -
4214 please feel free to contribute implementations!
4216 struct smb_message_struct
4230 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4231 {SMBtcon,"SMBtcon",reply_tcon,0},
4232 {SMBtdis,"SMBtdis",reply_tdis,0},
4233 {SMBexit,"SMBexit",reply_exit,0},
4234 {SMBioctl,"SMBioctl",reply_ioctl,0},
4235 {SMBecho,"SMBecho",reply_echo,0},
4236 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4237 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4238 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4239 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4240 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4241 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4242 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4243 {SMBopen,"SMBopen",reply_open,AS_USER},
4245 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4246 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4247 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4249 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4250 {SMBread,"SMBread",reply_read,AS_USER},
4251 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4252 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4253 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4254 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4255 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4256 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4258 /* this is a Pathworks specific call, allowing the
4259 changing of the root path */
4260 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4262 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4263 {SMBflush,"SMBflush",reply_flush,AS_USER},
4264 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4265 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4266 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4267 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4268 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4269 {SMBlock,"SMBlock",reply_lock,AS_USER},
4270 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4272 /* CORE+ PROTOCOL FOLLOWS */
4274 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4275 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4276 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4277 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4278 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4280 /* LANMAN1.0 PROTOCOL FOLLOWS */
4282 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4283 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4284 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4285 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4286 {SMBwritec,"SMBwritec",NULL,AS_USER},
4287 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4288 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4289 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4290 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4291 {SMBioctls,"SMBioctls",NULL,AS_USER},
4292 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4293 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4295 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4296 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4297 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4298 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4300 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4301 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4302 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4304 /* LANMAN2.0 PROTOCOL FOLLOWS */
4305 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4306 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4307 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4308 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4310 /* messaging routines */
4311 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4312 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4313 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4314 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4316 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4318 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4319 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4320 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4321 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4324 /****************************************************************************
4325 return a string containing the function name of a SMB command
4326 ****************************************************************************/
4327 char *smb_fn_name(int type)
4329 static char *unknown_name = "SMBunknown";
4330 static int num_smb_messages =
4331 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4334 for (match=0;match<num_smb_messages;match++)
4335 if (smb_messages[match].code == type)
4338 if (match == num_smb_messages)
4339 return(unknown_name);
4341 return(smb_messages[match].name);
4345 /****************************************************************************
4346 do a switch on the message type, and return the response size
4347 ****************************************************************************/
4348 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4352 static int num_smb_messages =
4353 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4357 struct timeval msg_start_time;
4358 struct timeval msg_end_time;
4359 static unsigned long total_time = 0;
4361 GetTimeOfDay(&msg_start_time);
4368 last_message = type;
4370 /* make sure this is an SMB packet */
4371 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4373 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4377 for (match=0;match<num_smb_messages;match++)
4378 if (smb_messages[match].code == type)
4381 if (match == num_smb_messages)
4383 DEBUG(0,("Unknown message type %d!\n",type));
4384 outsize = reply_unknown(inbuf,outbuf);
4388 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4389 if (smb_messages[match].fn)
4391 int cnum = SVAL(inbuf,smb_tid);
4392 int flags = smb_messages[match].flags;
4393 uint16 session_tag = SVAL(inbuf,smb_uid);
4395 /* does this protocol need to be run as root? */
4396 if (!(flags & AS_USER))
4399 /* does this protocol need to be run as the connected user? */
4400 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
4401 if (flags & AS_GUEST)
4404 return(ERROR(ERRSRV,ERRinvnid));
4406 /* this code is to work around a bug is MS client 3 without
4407 introducing a security hole - it needs to be able to do
4408 print queue checks as guest if it isn't logged in properly */
4409 if (flags & AS_USER)
4412 /* does it need write permission? */
4413 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4414 return(ERROR(ERRSRV,ERRaccess));
4416 /* ipc services are limited */
4417 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4418 return(ERROR(ERRSRV,ERRaccess));
4420 /* load service specific parameters */
4421 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4422 return(ERROR(ERRSRV,ERRaccess));
4424 /* does this protocol need to be run as guest? */
4425 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4426 return(ERROR(ERRSRV,ERRaccess));
4430 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4434 outsize = reply_unknown(inbuf,outbuf);
4439 GetTimeOfDay(&msg_end_time);
4440 if (!(smb_messages[match].flags & TIME_INIT))
4442 smb_messages[match].time = 0;
4443 smb_messages[match].flags |= TIME_INIT;
4446 unsigned long this_time =
4447 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4448 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4449 smb_messages[match].time += this_time;
4450 total_time += this_time;
4452 DEBUG(2,("TIME %s %d usecs %g pct\n",
4453 smb_fn_name(type),smb_messages[match].time,
4454 (100.0*smb_messages[match].time) / total_time));
4461 /****************************************************************************
4462 construct a chained reply and add it to the already made reply
4463 **************************************************************************/
4464 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4466 static char *orig_inbuf;
4467 static char *orig_outbuf;
4468 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4469 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4470 char *inbuf2, *outbuf2;
4472 char inbuf_saved[smb_wct];
4473 char outbuf_saved[smb_wct];
4474 extern int chain_size;
4475 int wct = CVAL(outbuf,smb_wct);
4476 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4478 /* maybe its not chained */
4479 if (smb_com2 == 0xFF) {
4480 CVAL(outbuf,smb_vwv0) = 0xFF;
4484 if (chain_size == 0) {
4485 /* this is the first part of the chain */
4487 orig_outbuf = outbuf;
4490 /* we need to tell the client where the next part of the reply will be */
4491 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4492 CVAL(outbuf,smb_vwv0) = smb_com2;
4494 /* remember how much the caller added to the chain, only counting stuff
4495 after the parameter words */
4496 chain_size += outsize - smb_wct;
4498 /* work out pointers into the original packets. The
4499 headers on these need to be filled in */
4500 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4501 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4503 /* remember the original command type */
4504 smb_com1 = CVAL(orig_inbuf,smb_com);
4506 /* save the data which will be overwritten by the new headers */
4507 memcpy(inbuf_saved,inbuf2,smb_wct);
4508 memcpy(outbuf_saved,outbuf2,smb_wct);
4510 /* give the new packet the same header as the last part of the SMB */
4511 memmove(inbuf2,inbuf,smb_wct);
4513 /* create the in buffer */
4514 CVAL(inbuf2,smb_com) = smb_com2;
4516 /* create the out buffer */
4517 bzero(outbuf2,smb_size);
4518 set_message(outbuf2,0,0,True);
4519 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4521 memcpy(outbuf2+4,inbuf2+4,4);
4522 CVAL(outbuf2,smb_rcls) = SUCCESS;
4523 CVAL(outbuf2,smb_reh) = 0;
4524 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4526 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4527 SSVAL(outbuf2,smb_err,SUCCESS);
4528 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4529 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4530 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4531 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4533 DEBUG(3,("Chained message\n"));
4536 /* process the request */
4537 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4538 bufsize-chain_size);
4540 /* copy the new reply and request headers over the old ones, but
4541 preserve the smb_com field */
4542 memmove(orig_outbuf,outbuf2,smb_wct);
4543 CVAL(orig_outbuf,smb_com) = smb_com1;
4545 /* restore the saved data, being careful not to overwrite any
4546 data from the reply header */
4547 memcpy(inbuf2,inbuf_saved,smb_wct);
4549 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4550 if (ofs < 0) ofs = 0;
4551 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4559 /****************************************************************************
4560 construct a reply to the incoming packet
4561 ****************************************************************************/
4562 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4564 int type = CVAL(inbuf,smb_com);
4566 int msg_type = CVAL(inbuf,0);
4567 extern int chain_size;
4569 smb_last_time = time(NULL);
4574 bzero(outbuf,smb_size);
4577 return(reply_special(inbuf,outbuf));
4579 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4580 set_message(outbuf,0,0,True);
4582 memcpy(outbuf+4,inbuf+4,4);
4583 CVAL(outbuf,smb_rcls) = SUCCESS;
4584 CVAL(outbuf,smb_reh) = 0;
4585 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4587 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4588 SSVAL(outbuf,smb_err,SUCCESS);
4589 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4590 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4591 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4592 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4594 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4596 outsize += chain_size;
4599 smb_setlen(outbuf,outsize - 4);
4603 /****************************************************************************
4604 process commands from the client
4605 ****************************************************************************/
4606 static void process(void)
4610 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4611 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4612 if ((InBuffer == NULL) || (OutBuffer == NULL))
4615 InBuffer += SMB_ALIGNMENT;
4616 OutBuffer += SMB_ALIGNMENT;
4619 DEBUG(3,("priming nmbd\n"));
4622 ip = *interpret_addr2("localhost");
4623 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4625 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4631 int deadtime = lp_deadtime()*60;
4633 int last_keepalive=0;
4634 int service_load_counter = 0;
4635 BOOL got_smb = False;
4638 deadtime = DEFAULT_SMBD_TIMEOUT;
4640 if (lp_readprediction())
4641 do_read_prediction();
4645 for (counter=SMBD_SELECT_LOOP;
4646 !receive_message_or_smb(Client,oplock_sock,
4647 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4648 counter += SMBD_SELECT_LOOP)
4652 BOOL allidle = True;
4653 extern int keepalive;
4655 if (counter > 365 * 3600) /* big number of seconds. */
4658 service_load_counter = 0;
4661 if (smb_read_error == READ_EOF)
4663 DEBUG(3,("end of file from client\n"));
4667 if (smb_read_error == READ_ERROR)
4669 DEBUG(3,("receive_smb error (%s) exiting\n",
4676 /* become root again if waiting */
4679 /* check for smb.conf reload */
4680 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4682 service_load_counter = counter;
4684 /* reload services, if files have changed. */
4685 reload_services(True);
4688 /* automatic timeout if all connections are closed */
4689 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4691 DEBUG(2,("%s Closing idle connection\n",timestring()));
4695 if (keepalive && (counter-last_keepalive)>keepalive)
4697 extern int password_client;
4698 if (!send_keepalive(Client))
4700 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4703 /* also send a keepalive to the password server if its still
4705 if (password_client != -1)
4706 send_keepalive(password_client);
4707 last_keepalive = counter;
4710 /* check for connection timeouts */
4711 for (i=0;i<MAX_CONNECTIONS;i++)
4712 if (Connections[i].open)
4714 /* close dirptrs on connections that are idle */
4715 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4718 if (Connections[i].num_files_open > 0 ||
4719 (t-Connections[i].lastused)<deadtime)
4723 if (allidle && num_connections_open>0)
4725 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4731 process_smb(InBuffer, OutBuffer);
4733 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4738 /****************************************************************************
4739 initialise connect, service and file structs
4740 ****************************************************************************/
4741 static void init_structs(void )
4744 get_myname(myhostname,NULL);
4746 for (i=0;i<MAX_CONNECTIONS;i++)
4748 Connections[i].open = False;
4749 Connections[i].num_files_open=0;
4750 Connections[i].lastused=0;
4751 Connections[i].used=False;
4752 string_init(&Connections[i].user,"");
4753 string_init(&Connections[i].dirpath,"");
4754 string_init(&Connections[i].connectpath,"");
4755 string_init(&Connections[i].origpath,"");
4758 for (i=0;i<MAX_OPEN_FILES;i++)
4760 Files[i].open = False;
4761 string_init(&Files[i].name,"");
4765 for (i=0;i<MAX_OPEN_FILES;i++)
4767 file_fd_struct *fd_ptr = &FileFd[i];
4768 fd_ptr->ref_count = 0;
4769 fd_ptr->dev = (int32)-1;
4770 fd_ptr->inode = (int32)-1;
4772 fd_ptr->fd_readonly = -1;
4773 fd_ptr->fd_writeonly = -1;
4774 fd_ptr->real_open_flags = -1;
4780 /****************************************************************************
4781 usage on the program
4782 ****************************************************************************/
4783 static void usage(char *pname)
4785 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4787 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4788 printf("Version %s\n",VERSION);
4789 printf("\t-D become a daemon\n");
4790 printf("\t-p port listen on the specified port\n");
4791 printf("\t-d debuglevel set the debuglevel\n");
4792 printf("\t-l log basename. Basename for log/debug files\n");
4793 printf("\t-s services file. Filename of services file\n");
4794 printf("\t-P passive only\n");
4795 printf("\t-a overwrite log file, don't append\n");
4800 /****************************************************************************
4802 ****************************************************************************/
4803 int main(int argc,char *argv[])
4805 extern BOOL append_log;
4806 /* shall I run as a daemon */
4807 BOOL is_daemon = False;
4808 int port = SMB_PORT;
4810 extern char *optarg;
4811 char pidFile[100] = { 0 };
4813 #ifdef NEED_AUTH_PARAMETERS
4814 set_auth_parameters(argc,argv);
4825 strcpy(debugf,SMBLOGFILE);
4827 setup_logging(argv[0],False);
4829 charset_initialise();
4831 /* make absolutely sure we run as root - to handle cases whre people
4832 are crazy enough to have it setuid */
4842 fault_setup(exit_server);
4843 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4845 /* we want total control over the permissions on created files,
4846 so set our umask to 0 */
4853 /* this is for people who can't start the program correctly */
4854 while (argc > 1 && (*argv[1] != '-'))
4860 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4864 strncpy(pidFile, optarg, sizeof(pidFile));
4867 strcpy(user_socket_options,optarg);
4870 strcpy(scope,optarg);
4874 extern BOOL passive;
4879 strcpy(servicesf,optarg);
4882 strcpy(debugf,optarg);
4886 extern BOOL append_log;
4887 append_log = !append_log;
4897 DEBUGLEVEL = atoi(optarg);
4900 port = atoi(optarg);
4913 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4914 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4916 #ifndef NO_GETRLIMIT
4917 #ifdef RLIMIT_NOFILE
4920 getrlimit(RLIMIT_NOFILE, &rlp);
4921 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4922 setrlimit(RLIMIT_NOFILE, &rlp);
4923 getrlimit(RLIMIT_NOFILE, &rlp);
4924 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4930 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4931 getuid(),getgid(),geteuid(),getegid()));
4933 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4935 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4941 if (!reload_services(False))
4944 codepage_initialise(lp_client_code_page());
4946 strcpy(myworkgroup, lp_workgroup());
4948 #ifndef NO_SIGNAL_TEST
4949 signal(SIGHUP,SIGNAL_CAST sig_hup);
4952 DEBUG(3,("%s loaded services\n",timestring()));
4954 if (!is_daemon && !is_a_socket(0))
4956 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4962 DEBUG(3,("%s becoming a daemon\n",timestring()));
4971 if ((fd = open(pidFile,
4975 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4977 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4980 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4982 DEBUG(0,("ERROR: smbd is already running\n"));
4985 sprintf(buf, "%u\n", (unsigned int) getpid());
4986 if (write(fd, buf, strlen(buf)) < 0)
4988 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4991 /* Leave pid file open & locked for the duration... */
4994 if (!open_sockets(is_daemon,port))
4997 #ifdef FAST_SHARE_MODES
4998 if (!start_share_mode_mgmt())
5000 #endif /* FAST_SHARE_MODES */
5002 /* possibly reload the services file. */
5003 reload_services(True);
5005 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5009 if (sys_chroot(lp_rootdir()) == 0)
5010 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5013 /* Setup the oplock IPC socket. */
5014 if(!open_oplock_ipc())
5020 exit_server("normal exit");