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,
3009 if (-1 == initgroups(user,gid))
3013 DEBUG(0,("Unable to initgroups!\n"));
3014 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3015 DEBUG(0,("This is probably a problem with the account %s\n",user));
3024 ngroups = getgroups(0,&grp);
3027 igroups = (int *)malloc(sizeof(int)*ngroups);
3028 attrs = (int *)malloc(sizeof(int)*ngroups);
3029 for (i=0;i<ngroups;i++)
3031 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3032 igroups[i] = 0x42424242;
3034 ngroups = getgroups(ngroups,(gid_t *)igroups);
3036 if (igroups[0] == 0x42424242)
3039 *p_ngroups = ngroups;
3042 /* The following bit of code is very strange. It is due to the
3043 fact that some OSes use int* and some use gid_t* for
3044 getgroups, and some (like SunOS) use both, one in prototypes,
3045 and one in man pages and the actual code. Thus we detect it
3046 dynamically using some very ugly code */
3049 /* does getgroups return ints or gid_t ?? */
3050 static BOOL groups_use_ints = True;
3052 if (groups_use_ints &&
3054 SVAL(igroups,2) == 0x4242)
3055 groups_use_ints = False;
3057 for (i=0;groups_use_ints && i<ngroups;i++)
3058 if (igroups[i] == 0x42424242)
3059 groups_use_ints = False;
3061 if (groups_use_ints)
3063 *p_igroups = igroups;
3064 *p_groups = (gid_t *)igroups;
3068 gid_t *groups = (gid_t *)igroups;
3069 igroups = (int *)malloc(sizeof(int)*ngroups);
3070 for (i=0;i<ngroups;i++)
3072 igroups[i] = groups[i];
3074 *p_igroups = igroups;
3075 *p_groups = (gid_t *)groups;
3078 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3079 for (i=0;i<ngroups;i++)
3080 DEBUG(3,("%d ",igroups[i]));
3086 /****************************************************************************
3087 make a connection to a service
3088 ****************************************************************************/
3089 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3093 struct passwd *pass = NULL;
3094 connection_struct *pcon;
3097 static BOOL first_connection = True;
3101 snum = find_service(service);
3104 if (strequal(service,"IPC$"))
3106 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3110 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3114 if (strequal(service,HOMES_NAME))
3116 if (*user && Get_Pwnam(user,True))
3117 return(make_connection(user,user,password,pwlen,dev,vuid));
3119 if (validated_username(vuid))
3121 strcpy(user,validated_username(vuid));
3122 return(make_connection(user,user,password,pwlen,dev,vuid));
3126 if (!lp_snum_ok(snum) || !check_access(snum)) {
3130 /* you can only connect to the IPC$ service as an ipc device */
3131 if (strequal(service,"IPC$"))
3134 if (*dev == '?' || !*dev)
3136 if (lp_print_ok(snum))
3137 strcpy(dev,"LPT1:");
3142 /* if the request is as a printer and you can't print then refuse */
3144 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3145 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3149 /* lowercase the user name */
3152 /* add it as a possible user name */
3153 add_session_user(service);
3155 /* shall we let them in? */
3156 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3158 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3162 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3165 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3169 pcon = &Connections[cnum];
3170 bzero((char *)pcon,sizeof(*pcon));
3172 /* find out some info about the user */
3173 pass = Get_Pwnam(user,True);
3177 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3181 pcon->read_only = lp_readonly(snum);
3185 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3186 string_sub(list,"%S",service);
3188 if (user_in_list(user,list))
3189 pcon->read_only = True;
3191 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3192 string_sub(list,"%S",service);
3194 if (user_in_list(user,list))
3195 pcon->read_only = False;
3198 /* admin user check */
3200 /* JRA - original code denied admin user if the share was
3201 marked read_only. Changed as I don't think this is needed,
3202 but old code left in case there is a problem here.
3204 if (user_in_list(user,lp_admin_users(snum))
3206 && !pcon->read_only)
3211 pcon->admin_user = True;
3212 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3215 pcon->admin_user = False;
3217 pcon->force_user = force;
3219 pcon->uid = pass->pw_uid;
3220 pcon->gid = pass->pw_gid;
3221 pcon->num_files_open = 0;
3222 pcon->lastused = time(NULL);
3223 pcon->service = snum;
3225 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3226 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3227 pcon->dirptr = NULL;
3228 pcon->veto_list = NULL;
3229 pcon->hide_list = NULL;
3230 string_set(&pcon->dirpath,"");
3231 string_set(&pcon->user,user);
3234 if (*lp_force_group(snum))
3239 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3240 /* default service may be a group name */
3241 string_sub(gname,"%S",service);
3242 gptr = (struct group *)getgrnam(gname);
3246 pcon->gid = gptr->gr_gid;
3247 DEBUG(3,("Forced group %s\n",gname));
3250 DEBUG(1,("Couldn't find group %s\n",gname));
3254 if (*lp_force_user(snum))
3256 struct passwd *pass2;
3258 fstrcpy(fuser,lp_force_user(snum));
3259 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3262 pcon->uid = pass2->pw_uid;
3263 string_set(&pcon->user,fuser);
3264 fstrcpy(user,fuser);
3265 pcon->force_user = True;
3266 DEBUG(3,("Forced user %s\n",fuser));
3269 DEBUG(1,("Couldn't find user %s\n",fuser));
3274 pstrcpy(s,lp_pathname(snum));
3275 standard_sub(cnum,s);
3276 string_set(&pcon->connectpath,s);
3277 DEBUG(3,("Connect path is %s\n",s));
3280 /* groups stuff added by ih */
3282 pcon->igroups = NULL;
3283 pcon->groups = NULL;
3288 /* Find all the groups this uid is in and store them. Used by become_user() */
3289 setup_groups(pcon->user,pcon->uid,pcon->gid,
3290 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3292 /* check number of connections */
3293 if (!claim_connection(cnum,
3294 lp_servicename(SNUM(cnum)),
3295 lp_max_connections(SNUM(cnum)),False))
3297 DEBUG(1,("too many connections - rejected\n"));
3301 if (lp_status(SNUM(cnum)))
3302 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3304 first_connection = False;
3309 /* execute any "root preexec = " line */
3310 if (*lp_rootpreexec(SNUM(cnum)))
3313 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3314 standard_sub(cnum,cmd);
3315 DEBUG(5,("cmd=%s\n",cmd));
3316 smbrun(cmd,NULL,False);
3319 if (!become_user(cnum,pcon->vuid))
3321 DEBUG(0,("Can't become connected user!\n"));
3323 if (!IS_IPC(cnum)) {
3324 yield_connection(cnum,
3325 lp_servicename(SNUM(cnum)),
3326 lp_max_connections(SNUM(cnum)));
3327 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3332 if (ChDir(pcon->connectpath) != 0)
3334 DEBUG(0,("Can't change directory to %s (%s)\n",
3335 pcon->connectpath,strerror(errno)));
3338 if (!IS_IPC(cnum)) {
3339 yield_connection(cnum,
3340 lp_servicename(SNUM(cnum)),
3341 lp_max_connections(SNUM(cnum)));
3342 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3347 string_set(&pcon->origpath,pcon->connectpath);
3349 #if SOFTLINK_OPTIMISATION
3350 /* resolve any soft links early */
3353 pstrcpy(s,pcon->connectpath);
3355 string_set(&pcon->connectpath,s);
3356 ChDir(pcon->connectpath);
3360 num_connections_open++;
3361 add_session_user(user);
3363 /* execute any "preexec = " line */
3364 if (*lp_preexec(SNUM(cnum)))
3367 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3368 standard_sub(cnum,cmd);
3369 smbrun(cmd,NULL,False);
3372 /* we've finished with the sensitive stuff */
3375 /* Add veto/hide lists */
3376 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3378 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3379 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3383 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3387 lp_servicename(SNUM(cnum)),user,
3397 /****************************************************************************
3398 find first available file slot
3399 ****************************************************************************/
3400 int find_free_file(void )
3403 /* we start at 1 here for an obscure reason I can't now remember,
3404 but I think is important :-) */
3405 for (i=1;i<MAX_OPEN_FILES;i++)
3408 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3412 /****************************************************************************
3413 find first available connection slot, starting from a random position.
3414 The randomisation stops problems with the server dieing and clients
3415 thinking the server is still available.
3416 ****************************************************************************/
3417 static int find_free_connection(int hash )
3421 hash = (hash % (MAX_CONNECTIONS-2))+1;
3425 for (i=hash+1;i!=hash;)
3427 if (!Connections[i].open && Connections[i].used == used)
3429 DEBUG(3,("found free connection number %d\n",i));
3433 if (i == MAX_CONNECTIONS)
3443 DEBUG(1,("ERROR! Out of connection structures\n"));
3448 /****************************************************************************
3449 reply for the core protocol
3450 ****************************************************************************/
3451 int reply_corep(char *outbuf)
3453 int outsize = set_message(outbuf,1,0,True);
3455 Protocol = PROTOCOL_CORE;
3461 /****************************************************************************
3462 reply for the coreplus protocol
3463 ****************************************************************************/
3464 int reply_coreplus(char *outbuf)
3466 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3467 int outsize = set_message(outbuf,13,0,True);
3468 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3469 readbraw and writebraw (possibly) */
3470 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3471 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3473 Protocol = PROTOCOL_COREPLUS;
3479 /****************************************************************************
3480 reply for the lanman 1.0 protocol
3481 ****************************************************************************/
3482 int reply_lanman1(char *outbuf)
3484 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3486 BOOL doencrypt = SMBENCRYPT();
3487 time_t t = time(NULL);
3488 /* We need to save and restore this as it can be destroyed
3489 if we call another server if security=server
3490 Thanks to Paul Nelson @ Thursby for pointing this out.
3492 uint16 mid = SVAL(outbuf, smb_mid);
3494 if (lp_security()>=SEC_USER) secword |= 1;
3495 if (doencrypt) secword |= 2;
3497 set_message(outbuf,13,doencrypt?8:0,True);
3498 SSVAL(outbuf,smb_vwv1,secword);
3499 /* Create a token value and add it to the outgoing packet. */
3501 generate_next_challenge(smb_buf(outbuf));
3503 Protocol = PROTOCOL_LANMAN1;
3505 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3506 DEBUG(3,("using password server validation\n"));
3507 if (doencrypt) set_challenge(smb_buf(outbuf));
3510 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3511 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3512 SSVAL(outbuf,smb_vwv2,max_recv);
3513 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3514 SSVAL(outbuf,smb_vwv4,1);
3515 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3516 readbraw writebraw (possibly) */
3517 SIVAL(outbuf,smb_vwv6,getpid());
3518 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3520 put_dos_date(outbuf,smb_vwv8,t);
3522 return (smb_len(outbuf)+4);
3526 /****************************************************************************
3527 reply for the lanman 2.0 protocol
3528 ****************************************************************************/
3529 int reply_lanman2(char *outbuf)
3531 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3533 BOOL doencrypt = SMBENCRYPT();
3534 time_t t = time(NULL);
3535 /* We need to save and restore this as it can be destroyed
3536 if we call another server if security=server
3537 Thanks to Paul Nelson @ Thursby for pointing this out.
3539 uint16 mid = SVAL(outbuf, smb_mid);
3541 if (lp_security()>=SEC_USER) secword |= 1;
3542 if (doencrypt) secword |= 2;
3544 set_message(outbuf,13,doencrypt?8:0,True);
3545 SSVAL(outbuf,smb_vwv1,secword);
3546 /* Create a token value and add it to the outgoing packet. */
3548 generate_next_challenge(smb_buf(outbuf));
3550 SIVAL(outbuf,smb_vwv6,getpid());
3552 Protocol = PROTOCOL_LANMAN2;
3554 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3555 DEBUG(3,("using password server validation\n"));
3556 if (doencrypt) set_challenge(smb_buf(outbuf));
3559 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3560 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3561 SSVAL(outbuf,smb_vwv2,max_recv);
3562 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3563 SSVAL(outbuf,smb_vwv4,1);
3564 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3565 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3566 put_dos_date(outbuf,smb_vwv8,t);
3568 return (smb_len(outbuf)+4);
3572 /****************************************************************************
3573 reply for the nt protocol
3574 ****************************************************************************/
3575 int reply_nt1(char *outbuf)
3577 /* dual names + lock_and_read + nt SMBs + remote API calls */
3578 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3580 other valid capabilities which we may support at some time...
3581 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3582 CAP_LARGE_FILES|CAP_LARGE_READX|
3583 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3587 BOOL doencrypt = SMBENCRYPT();
3588 time_t t = time(NULL);
3591 char challenge_len = 8;
3592 /* We need to save and restore this as it can be destroyed
3593 if we call another server if security=server
3594 Thanks to Paul Nelson @ Thursby for pointing this out.
3596 uint16 mid = SVAL(outbuf, smb_mid);
3598 if (lp_readraw() && lp_writeraw())
3600 capabilities |= CAP_RAW_MODE;
3603 if (lp_security()>=SEC_USER) secword |= 1;
3604 if (doencrypt) secword |= 2;
3606 /* decide where (if) to put the encryption challenge, and
3607 follow it with the OEM'd domain name
3609 encrypt_len = doencrypt?challenge_len:0;
3611 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3613 data_len = encrypt_len + strlen(myworkgroup) + 1;
3616 set_message(outbuf,17,data_len,True);
3619 /* put the OEM'd domain name */
3620 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3622 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3625 CVAL(outbuf,smb_vwv1) = secword;
3626 /* Create a token value and add it to the outgoing packet. */
3629 generate_next_challenge(smb_buf(outbuf));
3631 /* Tell the nt machine how long the challenge is. */
3632 SSVALS(outbuf,smb_vwv16+1,challenge_len);
3635 Protocol = PROTOCOL_NT1;
3637 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3638 DEBUG(3,("using password server validation\n"));
3639 if (doencrypt) set_challenge(smb_buf(outbuf));
3642 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3643 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3644 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3645 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3646 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3647 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3648 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3649 put_long_date(outbuf+smb_vwv11+1,t);
3650 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3651 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3653 return (smb_len(outbuf)+4);
3656 /* these are the protocol lists used for auto architecture detection:
3659 protocol [PC NETWORK PROGRAM 1.0]
3660 protocol [XENIX CORE]
3661 protocol [MICROSOFT NETWORKS 1.03]
3662 protocol [LANMAN1.0]
3663 protocol [Windows for Workgroups 3.1a]
3664 protocol [LM1.2X002]
3665 protocol [LANMAN2.1]
3666 protocol [NT LM 0.12]
3669 protocol [PC NETWORK PROGRAM 1.0]
3670 protocol [XENIX CORE]
3671 protocol [MICROSOFT NETWORKS 1.03]
3672 protocol [LANMAN1.0]
3673 protocol [Windows for Workgroups 3.1a]
3674 protocol [LM1.2X002]
3675 protocol [LANMAN2.1]
3676 protocol [NT LM 0.12]
3679 protocol [PC NETWORK PROGRAM 1.0]
3680 protocol [XENIX CORE]
3681 protocol [LANMAN1.0]
3682 protocol [LM1.2X002]
3683 protocol [LANMAN2.1]
3687 * Modified to recognize the architecture of the remote machine better.
3689 * This appears to be the matrix of which protocol is used by which
3691 Protocol WfWg Win95 WinNT OS/2
3692 PC NETWORK PROGRAM 1.0 1 1 1 1
3694 MICROSOFT NETWORKS 3.0 2 2
3696 MICROSOFT NETWORKS 1.03 3
3699 Windows for Workgroups 3.1a 5 5 5
3704 * tim@fsg.com 09/29/95
3707 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3708 #define ARCH_WIN95 0x2
3709 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3710 #define ARCH_WINNT 0x8
3711 #define ARCH_SAMBA 0x10
3713 #define ARCH_ALL 0x1F
3715 /* List of supported protocols, most desired first */
3719 int (*proto_reply_fn)(char *);
3721 } supported_protocols[] = {
3722 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3723 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3724 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3725 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3726 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3727 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3728 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3729 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3730 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3735 /****************************************************************************
3737 ****************************************************************************/
3738 static int reply_negprot(char *inbuf,char *outbuf)
3740 int outsize = set_message(outbuf,1,0,True);
3745 int bcc = SVAL(smb_buf(inbuf),-2);
3746 int arch = ARCH_ALL;
3748 p = smb_buf(inbuf)+1;
3749 while (p < (smb_buf(inbuf) + bcc))
3752 DEBUG(3,("Requested protocol [%s]\n",p));
3753 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3754 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3755 else if (strcsequal(p,"DOS LM1.2X002"))
3756 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3757 else if (strcsequal(p,"DOS LANMAN2.1"))
3758 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3759 else if (strcsequal(p,"NT LM 0.12"))
3760 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3761 else if (strcsequal(p,"LANMAN2.1"))
3762 arch &= ( ARCH_WINNT | ARCH_OS2 );
3763 else if (strcsequal(p,"LM1.2X002"))
3764 arch &= ( ARCH_WINNT | ARCH_OS2 );
3765 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3767 else if (strcsequal(p,"XENIX CORE"))
3768 arch &= ( ARCH_WINNT | ARCH_OS2 );
3769 else if (strcsequal(p,"Samba")) {
3779 set_remote_arch(RA_SAMBA);
3782 set_remote_arch(RA_WFWG);
3785 set_remote_arch(RA_WIN95);
3788 set_remote_arch(RA_WINNT);
3791 set_remote_arch(RA_OS2);
3794 set_remote_arch(RA_UNKNOWN);
3798 /* possibly reload - change of architecture */
3799 reload_services(True);
3801 /* a special case to stop password server loops */
3802 if (Index == 1 && strequal(remote_machine,myhostname) &&
3803 lp_security()==SEC_SERVER)
3804 exit_server("Password server loop!");
3806 /* Check for protocols, most desirable first */
3807 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3809 p = smb_buf(inbuf)+1;
3811 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3812 while (p < (smb_buf(inbuf) + bcc))
3814 if (strequal(p,supported_protocols[protocol].proto_name))
3823 SSVAL(outbuf,smb_vwv0,choice);
3825 extern fstring remote_proto;
3826 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3827 reload_services(True);
3828 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3829 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3832 DEBUG(0,("No protocol supported !\n"));
3834 SSVAL(outbuf,smb_vwv0,choice);
3836 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3842 /****************************************************************************
3843 close all open files for a connection
3844 ****************************************************************************/
3845 static void close_open_files(int cnum)
3848 for (i=0;i<MAX_OPEN_FILES;i++)
3849 if( Files[i].cnum == cnum && Files[i].open) {
3856 /****************************************************************************
3858 ****************************************************************************/
3859 void close_cnum(int cnum, uint16 vuid)
3861 DirCacheFlush(SNUM(cnum));
3865 if (!OPEN_CNUM(cnum))
3867 DEBUG(0,("Can't close cnum %d\n",cnum));
3871 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3873 remote_machine,client_addr(),
3874 lp_servicename(SNUM(cnum))));
3876 yield_connection(cnum,
3877 lp_servicename(SNUM(cnum)),
3878 lp_max_connections(SNUM(cnum)));
3880 if (lp_status(SNUM(cnum)))
3881 yield_connection(cnum,"STATUS.",MAXSTATUS);
3883 close_open_files(cnum);
3884 dptr_closecnum(cnum);
3886 /* execute any "postexec = " line */
3887 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3890 strcpy(cmd,lp_postexec(SNUM(cnum)));
3891 standard_sub(cnum,cmd);
3892 smbrun(cmd,NULL,False);
3897 /* execute any "root postexec = " line */
3898 if (*lp_rootpostexec(SNUM(cnum)))
3901 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3902 standard_sub(cnum,cmd);
3903 smbrun(cmd,NULL,False);
3906 Connections[cnum].open = False;
3907 num_connections_open--;
3908 if (Connections[cnum].ngroups && Connections[cnum].groups)
3910 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3911 free(Connections[cnum].groups);
3912 free(Connections[cnum].igroups);
3913 Connections[cnum].groups = NULL;
3914 Connections[cnum].igroups = NULL;
3915 Connections[cnum].ngroups = 0;
3918 free_namearray(Connections[cnum].veto_list);
3919 free_namearray(Connections[cnum].hide_list);
3921 string_set(&Connections[cnum].user,"");
3922 string_set(&Connections[cnum].dirpath,"");
3923 string_set(&Connections[cnum].connectpath,"");
3927 /****************************************************************************
3928 simple routines to do connection counting
3929 ****************************************************************************/
3930 BOOL yield_connection(int cnum,char *name,int max_connections)
3932 struct connect_record crec;
3935 int mypid = getpid();
3938 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3940 if (max_connections <= 0)
3943 bzero(&crec,sizeof(crec));
3945 pstrcpy(fname,lp_lockdir());
3946 standard_sub(cnum,fname);
3947 trim_string(fname,"","/");
3951 strcat(fname,".LCK");
3953 f = fopen(fname,"r+");
3956 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3960 fseek(f,0,SEEK_SET);
3962 /* find a free spot */
3963 for (i=0;i<max_connections;i++)
3965 if (fread(&crec,sizeof(crec),1,f) != 1)
3967 DEBUG(2,("Entry not found in lock file %s\n",fname));
3971 if (crec.pid == mypid && crec.cnum == cnum)
3975 if (crec.pid != mypid || crec.cnum != cnum)
3978 DEBUG(2,("Entry not found in lock file %s\n",fname));
3982 bzero((void *)&crec,sizeof(crec));
3984 /* remove our mark */
3985 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3986 fwrite(&crec,sizeof(crec),1,f) != 1)
3988 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3993 DEBUG(3,("Yield successful\n"));
4000 /****************************************************************************
4001 simple routines to do connection counting
4002 ****************************************************************************/
4003 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4005 struct connect_record crec;
4008 int snum = SNUM(cnum);
4012 if (max_connections <= 0)
4015 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4017 pstrcpy(fname,lp_lockdir());
4018 standard_sub(cnum,fname);
4019 trim_string(fname,"","/");
4021 if (!directory_exist(fname,NULL))
4026 strcat(fname,".LCK");
4028 if (!file_exist(fname,NULL))
4030 int oldmask = umask(022);
4031 f = fopen(fname,"w");
4036 total_recs = file_size(fname) / sizeof(crec);
4038 f = fopen(fname,"r+");
4042 DEBUG(1,("couldn't open lock file %s\n",fname));
4046 /* find a free spot */
4047 for (i=0;i<max_connections;i++)
4050 if (i>=total_recs ||
4051 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4052 fread(&crec,sizeof(crec),1,f) != 1)
4054 if (foundi < 0) foundi = i;
4058 if (Clear && crec.pid && !process_exists(crec.pid))
4060 fseek(f,i*sizeof(crec),SEEK_SET);
4061 bzero((void *)&crec,sizeof(crec));
4062 fwrite(&crec,sizeof(crec),1,f);
4063 if (foundi < 0) foundi = i;
4066 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4075 DEBUG(3,("no free locks in %s\n",fname));
4080 /* fill in the crec */
4081 bzero((void *)&crec,sizeof(crec));
4082 crec.magic = 0x280267;
4083 crec.pid = getpid();
4085 crec.uid = Connections[cnum].uid;
4086 crec.gid = Connections[cnum].gid;
4087 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4088 crec.start = time(NULL);
4090 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4091 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4094 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4095 fwrite(&crec,sizeof(crec),1,f) != 1)
4106 /*******************************************************************
4107 prepare to dump a core file - carefully!
4108 ********************************************************************/
4109 static BOOL dump_core(void)
4113 pstrcpy(dname,debugf);
4114 if ((p=strrchr(dname,'/'))) *p=0;
4115 strcat(dname,"/corefiles");
4117 sys_chown(dname,getuid(),getgid());
4119 if (chdir(dname)) return(False);
4122 #ifndef NO_GETRLIMIT
4126 getrlimit(RLIMIT_CORE, &rlp);
4127 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4128 setrlimit(RLIMIT_CORE, &rlp);
4129 getrlimit(RLIMIT_CORE, &rlp);
4130 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4136 DEBUG(0,("Dumping core in %s\n",dname));
4141 /****************************************************************************
4143 ****************************************************************************/
4144 void exit_server(char *reason)
4146 static int firsttime=1;
4149 if (!firsttime) exit(0);
4153 DEBUG(2,("Closing connections\n"));
4154 for (i=0;i<MAX_CONNECTIONS;i++)
4155 if (Connections[i].open)
4156 close_cnum(i,(uint16)-1);
4158 if (dcelogin_atmost_once)
4162 int oldlevel = DEBUGLEVEL;
4164 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4166 show_msg(last_inbuf);
4167 DEBUGLEVEL = oldlevel;
4168 DEBUG(0,("===============================================================\n"));
4170 if (dump_core()) return;
4174 #ifdef FAST_SHARE_MODES
4175 stop_share_mode_mgmt();
4176 #endif /* FAST_SHARE_MODES */
4178 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4182 /****************************************************************************
4183 do some standard substitutions in a string
4184 ****************************************************************************/
4185 void standard_sub(int cnum,char *str)
4187 if (VALID_CNUM(cnum)) {
4190 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4192 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4193 string_sub(p,"%H",home);
4197 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4198 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4199 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4200 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4201 case '\0' : p++; break; /* don't run off the end of the string */
4202 default : p+=2; break;
4206 standard_sub_basic(str);
4210 These flags determine some of the permissions required to do an operation
4212 Note that I don't set NEED_WRITE on some write operations because they
4213 are used by some brain-dead clients when printing, and I don't want to
4214 force write permissions on print services.
4216 #define AS_USER (1<<0)
4217 #define NEED_WRITE (1<<1)
4218 #define TIME_INIT (1<<2)
4219 #define CAN_IPC (1<<3)
4220 #define AS_GUEST (1<<5)
4224 define a list of possible SMB messages and their corresponding
4225 functions. Any message that has a NULL function is unimplemented -
4226 please feel free to contribute implementations!
4228 struct smb_message_struct
4242 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4243 {SMBtcon,"SMBtcon",reply_tcon,0},
4244 {SMBtdis,"SMBtdis",reply_tdis,0},
4245 {SMBexit,"SMBexit",reply_exit,0},
4246 {SMBioctl,"SMBioctl",reply_ioctl,0},
4247 {SMBecho,"SMBecho",reply_echo,0},
4248 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4249 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4250 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4251 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4252 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4253 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4254 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4255 {SMBopen,"SMBopen",reply_open,AS_USER},
4257 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4258 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4259 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4261 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4262 {SMBread,"SMBread",reply_read,AS_USER},
4263 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4264 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4265 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4266 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4267 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4268 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4270 /* this is a Pathworks specific call, allowing the
4271 changing of the root path */
4272 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4274 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4275 {SMBflush,"SMBflush",reply_flush,AS_USER},
4276 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4277 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4278 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4279 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4280 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4281 {SMBlock,"SMBlock",reply_lock,AS_USER},
4282 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4284 /* CORE+ PROTOCOL FOLLOWS */
4286 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4287 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4288 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4289 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4290 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4292 /* LANMAN1.0 PROTOCOL FOLLOWS */
4294 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4295 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4296 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4297 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4298 {SMBwritec,"SMBwritec",NULL,AS_USER},
4299 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4300 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4301 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4302 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4303 {SMBioctls,"SMBioctls",NULL,AS_USER},
4304 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4305 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4307 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4308 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4309 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4310 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4312 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4313 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4314 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4316 /* LANMAN2.0 PROTOCOL FOLLOWS */
4317 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4318 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4319 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4320 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4322 /* messaging routines */
4323 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4324 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4325 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4326 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4328 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4330 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4331 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4332 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4333 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4336 /****************************************************************************
4337 return a string containing the function name of a SMB command
4338 ****************************************************************************/
4339 char *smb_fn_name(int type)
4341 static char *unknown_name = "SMBunknown";
4342 static int num_smb_messages =
4343 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4346 for (match=0;match<num_smb_messages;match++)
4347 if (smb_messages[match].code == type)
4350 if (match == num_smb_messages)
4351 return(unknown_name);
4353 return(smb_messages[match].name);
4357 /****************************************************************************
4358 do a switch on the message type, and return the response size
4359 ****************************************************************************/
4360 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4364 static int num_smb_messages =
4365 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4369 struct timeval msg_start_time;
4370 struct timeval msg_end_time;
4371 static unsigned long total_time = 0;
4373 GetTimeOfDay(&msg_start_time);
4380 last_message = type;
4382 /* make sure this is an SMB packet */
4383 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4385 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4389 for (match=0;match<num_smb_messages;match++)
4390 if (smb_messages[match].code == type)
4393 if (match == num_smb_messages)
4395 DEBUG(0,("Unknown message type %d!\n",type));
4396 outsize = reply_unknown(inbuf,outbuf);
4400 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4401 if (smb_messages[match].fn)
4403 int cnum = SVAL(inbuf,smb_tid);
4404 int flags = smb_messages[match].flags;
4405 uint16 session_tag = SVAL(inbuf,smb_uid);
4407 /* does this protocol need to be run as root? */
4408 if (!(flags & AS_USER))
4411 /* does this protocol need to be run as the connected user? */
4412 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
4413 if (flags & AS_GUEST)
4416 return(ERROR(ERRSRV,ERRinvnid));
4418 /* this code is to work around a bug is MS client 3 without
4419 introducing a security hole - it needs to be able to do
4420 print queue checks as guest if it isn't logged in properly */
4421 if (flags & AS_USER)
4424 /* does it need write permission? */
4425 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4426 return(ERROR(ERRSRV,ERRaccess));
4428 /* ipc services are limited */
4429 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4430 return(ERROR(ERRSRV,ERRaccess));
4432 /* load service specific parameters */
4433 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4434 return(ERROR(ERRSRV,ERRaccess));
4436 /* does this protocol need to be run as guest? */
4437 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4438 return(ERROR(ERRSRV,ERRaccess));
4442 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4446 outsize = reply_unknown(inbuf,outbuf);
4451 GetTimeOfDay(&msg_end_time);
4452 if (!(smb_messages[match].flags & TIME_INIT))
4454 smb_messages[match].time = 0;
4455 smb_messages[match].flags |= TIME_INIT;
4458 unsigned long this_time =
4459 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4460 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4461 smb_messages[match].time += this_time;
4462 total_time += this_time;
4464 DEBUG(2,("TIME %s %d usecs %g pct\n",
4465 smb_fn_name(type),smb_messages[match].time,
4466 (100.0*smb_messages[match].time) / total_time));
4473 /****************************************************************************
4474 construct a chained reply and add it to the already made reply
4475 **************************************************************************/
4476 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4478 static char *orig_inbuf;
4479 static char *orig_outbuf;
4480 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4481 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4482 char *inbuf2, *outbuf2;
4484 char inbuf_saved[smb_wct];
4485 char outbuf_saved[smb_wct];
4486 extern int chain_size;
4487 int wct = CVAL(outbuf,smb_wct);
4488 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4490 /* maybe its not chained */
4491 if (smb_com2 == 0xFF) {
4492 CVAL(outbuf,smb_vwv0) = 0xFF;
4496 if (chain_size == 0) {
4497 /* this is the first part of the chain */
4499 orig_outbuf = outbuf;
4502 /* we need to tell the client where the next part of the reply will be */
4503 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4504 CVAL(outbuf,smb_vwv0) = smb_com2;
4506 /* remember how much the caller added to the chain, only counting stuff
4507 after the parameter words */
4508 chain_size += outsize - smb_wct;
4510 /* work out pointers into the original packets. The
4511 headers on these need to be filled in */
4512 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4513 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4515 /* remember the original command type */
4516 smb_com1 = CVAL(orig_inbuf,smb_com);
4518 /* save the data which will be overwritten by the new headers */
4519 memcpy(inbuf_saved,inbuf2,smb_wct);
4520 memcpy(outbuf_saved,outbuf2,smb_wct);
4522 /* give the new packet the same header as the last part of the SMB */
4523 memmove(inbuf2,inbuf,smb_wct);
4525 /* create the in buffer */
4526 CVAL(inbuf2,smb_com) = smb_com2;
4528 /* create the out buffer */
4529 bzero(outbuf2,smb_size);
4530 set_message(outbuf2,0,0,True);
4531 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4533 memcpy(outbuf2+4,inbuf2+4,4);
4534 CVAL(outbuf2,smb_rcls) = SUCCESS;
4535 CVAL(outbuf2,smb_reh) = 0;
4536 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4538 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4539 SSVAL(outbuf2,smb_err,SUCCESS);
4540 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4541 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4542 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4543 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4545 DEBUG(3,("Chained message\n"));
4548 /* process the request */
4549 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4550 bufsize-chain_size);
4552 /* copy the new reply and request headers over the old ones, but
4553 preserve the smb_com field */
4554 memmove(orig_outbuf,outbuf2,smb_wct);
4555 CVAL(orig_outbuf,smb_com) = smb_com1;
4557 /* restore the saved data, being careful not to overwrite any
4558 data from the reply header */
4559 memcpy(inbuf2,inbuf_saved,smb_wct);
4561 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4562 if (ofs < 0) ofs = 0;
4563 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4571 /****************************************************************************
4572 construct a reply to the incoming packet
4573 ****************************************************************************/
4574 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4576 int type = CVAL(inbuf,smb_com);
4578 int msg_type = CVAL(inbuf,0);
4579 extern int chain_size;
4581 smb_last_time = time(NULL);
4586 bzero(outbuf,smb_size);
4589 return(reply_special(inbuf,outbuf));
4591 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4592 set_message(outbuf,0,0,True);
4594 memcpy(outbuf+4,inbuf+4,4);
4595 CVAL(outbuf,smb_rcls) = SUCCESS;
4596 CVAL(outbuf,smb_reh) = 0;
4597 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4599 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4600 SSVAL(outbuf,smb_err,SUCCESS);
4601 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4602 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4603 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4604 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4606 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4608 outsize += chain_size;
4611 smb_setlen(outbuf,outsize - 4);
4615 /****************************************************************************
4616 process commands from the client
4617 ****************************************************************************/
4618 static void process(void)
4622 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4623 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4624 if ((InBuffer == NULL) || (OutBuffer == NULL))
4627 InBuffer += SMB_ALIGNMENT;
4628 OutBuffer += SMB_ALIGNMENT;
4631 DEBUG(3,("priming nmbd\n"));
4634 ip = *interpret_addr2("localhost");
4635 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4637 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4643 int deadtime = lp_deadtime()*60;
4645 int last_keepalive=0;
4646 int service_load_counter = 0;
4647 BOOL got_smb = False;
4650 deadtime = DEFAULT_SMBD_TIMEOUT;
4652 if (lp_readprediction())
4653 do_read_prediction();
4657 for (counter=SMBD_SELECT_LOOP;
4658 !receive_message_or_smb(Client,oplock_sock,
4659 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4660 counter += SMBD_SELECT_LOOP)
4664 BOOL allidle = True;
4665 extern int keepalive;
4667 if (counter > 365 * 3600) /* big number of seconds. */
4670 service_load_counter = 0;
4673 if (smb_read_error == READ_EOF)
4675 DEBUG(3,("end of file from client\n"));
4679 if (smb_read_error == READ_ERROR)
4681 DEBUG(3,("receive_smb error (%s) exiting\n",
4688 /* become root again if waiting */
4691 /* check for smb.conf reload */
4692 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4694 service_load_counter = counter;
4696 /* reload services, if files have changed. */
4697 reload_services(True);
4700 /* automatic timeout if all connections are closed */
4701 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4703 DEBUG(2,("%s Closing idle connection\n",timestring()));
4707 if (keepalive && (counter-last_keepalive)>keepalive)
4709 extern int password_client;
4710 if (!send_keepalive(Client))
4712 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4715 /* also send a keepalive to the password server if its still
4717 if (password_client != -1)
4718 send_keepalive(password_client);
4719 last_keepalive = counter;
4722 /* check for connection timeouts */
4723 for (i=0;i<MAX_CONNECTIONS;i++)
4724 if (Connections[i].open)
4726 /* close dirptrs on connections that are idle */
4727 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4730 if (Connections[i].num_files_open > 0 ||
4731 (t-Connections[i].lastused)<deadtime)
4735 if (allidle && num_connections_open>0)
4737 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4743 process_smb(InBuffer, OutBuffer);
4745 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4750 /****************************************************************************
4751 initialise connect, service and file structs
4752 ****************************************************************************/
4753 static void init_structs(void )
4756 get_myname(myhostname,NULL);
4758 for (i=0;i<MAX_CONNECTIONS;i++)
4760 Connections[i].open = False;
4761 Connections[i].num_files_open=0;
4762 Connections[i].lastused=0;
4763 Connections[i].used=False;
4764 string_init(&Connections[i].user,"");
4765 string_init(&Connections[i].dirpath,"");
4766 string_init(&Connections[i].connectpath,"");
4767 string_init(&Connections[i].origpath,"");
4770 for (i=0;i<MAX_OPEN_FILES;i++)
4772 Files[i].open = False;
4773 string_init(&Files[i].name,"");
4777 for (i=0;i<MAX_OPEN_FILES;i++)
4779 file_fd_struct *fd_ptr = &FileFd[i];
4780 fd_ptr->ref_count = 0;
4781 fd_ptr->dev = (int32)-1;
4782 fd_ptr->inode = (int32)-1;
4784 fd_ptr->fd_readonly = -1;
4785 fd_ptr->fd_writeonly = -1;
4786 fd_ptr->real_open_flags = -1;
4792 /****************************************************************************
4793 usage on the program
4794 ****************************************************************************/
4795 static void usage(char *pname)
4797 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4799 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4800 printf("Version %s\n",VERSION);
4801 printf("\t-D become a daemon\n");
4802 printf("\t-p port listen on the specified port\n");
4803 printf("\t-d debuglevel set the debuglevel\n");
4804 printf("\t-l log basename. Basename for log/debug files\n");
4805 printf("\t-s services file. Filename of services file\n");
4806 printf("\t-P passive only\n");
4807 printf("\t-a overwrite log file, don't append\n");
4812 /****************************************************************************
4814 ****************************************************************************/
4815 int main(int argc,char *argv[])
4817 extern BOOL append_log;
4818 /* shall I run as a daemon */
4819 BOOL is_daemon = False;
4820 int port = SMB_PORT;
4822 extern char *optarg;
4823 char pidFile[100] = { 0 };
4825 #ifdef NEED_AUTH_PARAMETERS
4826 set_auth_parameters(argc,argv);
4837 strcpy(debugf,SMBLOGFILE);
4839 setup_logging(argv[0],False);
4841 charset_initialise();
4843 /* make absolutely sure we run as root - to handle cases whre people
4844 are crazy enough to have it setuid */
4854 fault_setup(exit_server);
4855 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4857 /* we want total control over the permissions on created files,
4858 so set our umask to 0 */
4865 /* this is for people who can't start the program correctly */
4866 while (argc > 1 && (*argv[1] != '-'))
4872 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4876 strncpy(pidFile, optarg, sizeof(pidFile));
4879 strcpy(user_socket_options,optarg);
4882 strcpy(scope,optarg);
4886 extern BOOL passive;
4891 strcpy(servicesf,optarg);
4894 strcpy(debugf,optarg);
4898 extern BOOL append_log;
4899 append_log = !append_log;
4909 DEBUGLEVEL = atoi(optarg);
4912 port = atoi(optarg);
4925 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4926 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4928 #ifndef NO_GETRLIMIT
4929 #ifdef RLIMIT_NOFILE
4932 getrlimit(RLIMIT_NOFILE, &rlp);
4933 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4934 setrlimit(RLIMIT_NOFILE, &rlp);
4935 getrlimit(RLIMIT_NOFILE, &rlp);
4936 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4942 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4943 getuid(),getgid(),geteuid(),getegid()));
4945 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4947 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4953 if (!reload_services(False))
4956 codepage_initialise(lp_client_code_page());
4958 strcpy(myworkgroup, lp_workgroup());
4960 #ifndef NO_SIGNAL_TEST
4961 signal(SIGHUP,SIGNAL_CAST sig_hup);
4964 DEBUG(3,("%s loaded services\n",timestring()));
4966 if (!is_daemon && !is_a_socket(0))
4968 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4974 DEBUG(3,("%s becoming a daemon\n",timestring()));
4983 if ((fd = open(pidFile,
4987 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4989 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4992 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4994 DEBUG(0,("ERROR: smbd is already running\n"));
4997 sprintf(buf, "%u\n", (unsigned int) getpid());
4998 if (write(fd, buf, strlen(buf)) < 0)
5000 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5003 /* Leave pid file open & locked for the duration... */
5006 if (!open_sockets(is_daemon,port))
5009 #ifdef FAST_SHARE_MODES
5010 if (!start_share_mode_mgmt())
5012 #endif /* FAST_SHARE_MODES */
5014 /* possibly reload the services file. */
5015 reload_services(True);
5017 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5021 if (sys_chroot(lp_rootdir()) == 0)
5022 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5025 /* Setup the oplock IPC socket. */
5026 if(!open_oplock_ipc())
5032 exit_server("normal exit");