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 extern fstring remote_machine;
91 /* these can be set by some functions to override the error codes */
92 int unix_ERR_class=SUCCESS;
96 extern int extra_time_offset;
98 extern pstring myhostname;
100 static int find_free_connection(int hash);
102 /* for readability... */
103 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
104 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
105 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
106 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
107 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
109 /****************************************************************************
110 when exiting, take the whole family
111 ****************************************************************************/
114 exit_server("caught signal");
115 return 0; /* Keep -Wall happy :-) */
117 /****************************************************************************
118 Send a SIGTERM to our process group.
119 *****************************************************************************/
122 if(am_parent) kill(0,SIGTERM);
125 /****************************************************************************
126 change a dos mode to a unix mode
127 base permission for files:
128 everybody gets read bit set
129 dos readonly is represented in unix by removing everyone's write bit
130 dos archive is represented in unix by the user's execute bit
131 dos system is represented in unix by the group's execute bit
132 dos hidden is represented in unix by the other's execute bit
133 Then apply create mask,
135 base permission for directories:
136 dos directory is represented in unix by unix's dir bit and the exec bit
137 Then apply create mask,
139 ****************************************************************************/
140 mode_t unix_mode(int cnum,int dosmode)
142 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
144 if ( !IS_DOS_READONLY(dosmode) )
145 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
147 if (IS_DOS_DIR(dosmode)) {
148 /* We never make directories read only for the owner as under DOS a user
149 can always create a file in a read-only directory. */
150 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
151 /* Apply directory mask */
152 result &= lp_dir_mode(SNUM(cnum));
153 /* Add in force bits */
154 result |= lp_force_dir_mode(SNUM(cnum));
156 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
159 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
162 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
165 /* Apply mode mask */
166 result &= lp_create_mode(SNUM(cnum));
167 /* Add in force bits */
168 result |= lp_force_create_mode(SNUM(cnum));
174 /****************************************************************************
175 change a unix mode to a dos mode
176 ****************************************************************************/
177 int dos_mode(int cnum,char *path,struct stat *sbuf)
180 extern struct current_user current_user;
182 DEBUG(5,("dos_mode: %d %s\n", cnum, path));
184 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
185 if (!((sbuf->st_mode & S_IWOTH) ||
186 Connections[cnum].admin_user ||
187 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
188 ((sbuf->st_mode & S_IWGRP) &&
189 in_group(sbuf->st_gid,current_user.gid,
190 current_user.ngroups,current_user.igroups))))
193 if ((sbuf->st_mode & S_IWUSR) == 0)
197 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
200 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
203 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
206 if (S_ISDIR(sbuf->st_mode))
207 result = aDIR | (result & aRONLY);
210 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
214 /* hide files with a name starting with a . */
215 if (lp_hide_dot_files(SNUM(cnum)))
217 char *p = strrchr(path,'/');
223 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
227 /* Optimization : Only call is_hidden_path if it's not already
229 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
234 DEBUG(5,("dos_mode returning "));
236 if (result & aHIDDEN) DEBUG(5, ("h"));
237 if (result & aRONLY ) DEBUG(5, ("r"));
238 if (result & aSYSTEM) DEBUG(5, ("s"));
239 if (result & aDIR ) DEBUG(5, ("d"));
240 if (result & aARCH ) DEBUG(5, ("a"));
248 /*******************************************************************
249 chmod a file - but preserve some bits
250 ********************************************************************/
251 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
260 if (sys_stat(fname,st)) return(-1);
263 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
265 if (dos_mode(cnum,fname,st) == dosmode) return(0);
267 unixmode = unix_mode(cnum,dosmode);
269 /* preserve the s bits */
270 mask |= (S_ISUID | S_ISGID);
272 /* preserve the t bit */
277 /* possibly preserve the x bits */
278 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
279 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
280 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
282 unixmode |= (st->st_mode & mask);
284 /* if we previously had any r bits set then leave them alone */
285 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
286 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
290 /* if we previously had any w bits set then leave them alone
291 if the new mode is not rdonly */
292 if (!IS_DOS_READONLY(dosmode) &&
293 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
294 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
298 return(sys_chmod(fname,unixmode));
302 /****************************************************************************
303 check if two filenames are equal
305 this needs to be careful about whether we are case sensitive
306 ****************************************************************************/
307 static BOOL fname_equal(char *name1, char *name2)
309 int l1 = strlen(name1);
310 int l2 = strlen(name2);
312 /* handle filenames ending in a single dot */
313 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
317 ret = fname_equal(name1,name2);
322 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
326 ret = fname_equal(name1,name2);
331 /* now normal filename handling */
333 return(strcmp(name1,name2) == 0);
335 return(strequal(name1,name2));
339 /****************************************************************************
340 mangle the 2nd name and check if it is then equal to the first name
341 ****************************************************************************/
342 static BOOL mangled_equal(char *name1, char *name2)
346 if (is_8_3(name2, True))
349 strcpy(tmpname,name2);
350 mangle_name_83(tmpname);
352 return(strequal(name1,tmpname));
356 /****************************************************************************
357 scan a directory to find a filename, matching without case sensitivity
359 If the name looks like a mangled name then try via the mangling functions
360 ****************************************************************************/
361 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
368 mangled = is_mangled(name);
370 /* handle null paths */
374 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
380 check_mangled_stack(name);
382 /* open the directory */
383 if (!(cur_dir = OpenDir(cnum, path, True)))
385 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
389 /* now scan for matching names */
390 while ((dname = ReadDirName(cur_dir)))
393 (strequal(dname,".") || strequal(dname,"..")))
397 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
399 if ((mangled && mangled_equal(name,name2))
400 || fname_equal(name, dname))
402 /* we've found the file, change it's name and return */
403 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
414 /****************************************************************************
415 This routine is called to convert names from the dos namespace to unix
416 namespace. It needs to handle any case conversions, mangling, format
419 We assume that we have already done a chdir() to the right "root" directory
422 The function will return False if some part of the name except for the last
423 part cannot be resolved
425 If the saved_last_component != 0, then the unmodified last component
426 of the pathname is returned there. This is used in an exceptional
427 case in reply_mv (so far). If saved_last_component == 0 then nothing
430 The bad_path arg is set to True if the filename walk failed. This is
431 used to pick the correct error code to return between ENOENT and ENOTDIR
432 as Windows applications depend on ERRbadpath being returned if a component
433 of a pathname does not exist.
434 ****************************************************************************/
435 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
445 if(saved_last_component)
446 *saved_last_component = 0;
448 /* convert to basic unix format - removing \ chars and cleaning it up */
450 unix_clean_name(name);
452 /* names must be relative to the root of the service - trim any leading /.
453 also trim trailing /'s */
454 trim_string(name,"/","/");
457 * Ensure saved_last_component is valid even if file exists.
459 if(saved_last_component) {
460 end = strrchr(name, '/');
462 strcpy(saved_last_component, end + 1);
464 strcpy(saved_last_component, name);
467 if (!case_sensitive &&
468 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
471 /* check if it's a printer file */
472 if (Connections[cnum].printer)
474 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
478 sprintf(name2,"%.6s.XXXXXX",remote_machine);
479 /* sanitise the name */
480 for (s=name2 ; *s ; s++)
481 if (!issafe(*s)) *s = '_';
482 strcpy(name,(char *)mktemp(name2));
487 /* stat the name - if it exists then we are all done! */
488 if (sys_stat(name,&st) == 0)
493 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
495 /* a special case - if we don't have any mangling chars and are case
496 sensitive then searching won't help */
497 if (case_sensitive && !is_mangled(name) &&
498 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
501 /* now we need to recursively match the name against the real
502 directory structure */
505 while (strncmp(start,"./",2) == 0)
508 /* now match each part of the path name separately, trying the names
509 as is first, then trying to scan the directory for matching names */
510 for (;start;start = (end?end+1:(char *)NULL))
512 /* pinpoint the end of this section of the filename */
513 end = strchr(start, '/');
515 /* chop the name at this point */
518 if(saved_last_component != 0)
519 strcpy(saved_last_component, end ? end + 1 : start);
521 /* check if the name exists up to this point */
522 if (sys_stat(name, &st) == 0)
524 /* it exists. it must either be a directory or this must be
525 the last part of the path for it to be OK */
526 if (end && !(st.st_mode & S_IFDIR))
528 /* an intermediate part of the name isn't a directory */
529 DEBUG(5,("Not a dir %s\n",start));
540 /* remember the rest of the pathname so it can be restored
542 if (end) strcpy(rest,end+1);
544 /* try to find this part of the path in the directory */
545 if (strchr(start,'?') || strchr(start,'*') ||
546 !scan_directory(dirpath, start, cnum, end?True:False))
550 /* an intermediate part of the name can't be found */
551 DEBUG(5,("Intermediate not found %s\n",start));
553 /* We need to return the fact that the intermediate
554 name resolution failed. This is used to return an
555 error of ERRbadpath rather than ERRbadfile. Some
556 Windows applications depend on the difference between
563 /* just the last part of the name doesn't exist */
564 /* we may need to strupper() or strlower() it in case
565 this conversion is being used for file creation
567 /* if the filename is of mixed case then don't normalise it */
568 if (!case_preserve &&
569 (!strhasupper(start) || !strhaslower(start)))
572 /* check on the mangled stack to see if we can recover the
573 base of the filename */
574 if (is_mangled(start))
575 check_mangled_stack(start);
577 DEBUG(5,("New file %s\n",start));
581 /* restore the rest of the string */
584 strcpy(start+strlen(start)+1,rest);
585 end = start + strlen(start);
589 /* add to the dirpath that we have resolved so far */
590 if (*dirpath) strcat(dirpath,"/");
591 strcat(dirpath,start);
593 /* restore the / that we wiped out earlier */
597 /* the name has been resolved */
598 DEBUG(5,("conversion finished %s\n",name));
603 /****************************************************************************
604 normalise for DOS usage
605 ****************************************************************************/
606 static void disk_norm(int *bsize,int *dfree,int *dsize)
608 /* check if the disk is beyond the max disk size */
609 int maxdisksize = lp_maxdisksize();
611 /* convert to blocks - and don't overflow */
612 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
613 if (*dsize > maxdisksize) *dsize = maxdisksize;
614 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
619 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
624 if (*bsize > WORDMAX )
627 if (*dsize > WORDMAX)
629 if (*dfree > WORDMAX)
636 /****************************************************************************
637 return number of 1K blocks available on a path and total number
638 ****************************************************************************/
639 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
641 char *df_command = lp_dfree_command();
662 /* possibly use system() to get the result */
663 if (df_command && *df_command)
669 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
670 sprintf(syscmd,"%s %s",df_command,path);
671 standard_sub_basic(syscmd);
673 ret = smbrun(syscmd,outfile,False);
674 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
677 FILE *f = fopen(outfile,"r");
683 fscanf(f,"%d %d %d",dsize,dfree,bsize);
687 DEBUG(0,("Can't open %s\n",outfile));
691 disk_norm(bsize,dfree,dsize);
692 dfree_retval = ((*bsize)/1024)*(*dfree);
694 /* Ensure we return the min value between the users quota and
695 what's free on the disk. Thanks to Albrecht Gebhardt
696 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
698 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
700 disk_norm(&bsizeq, &dfreeq, &dsizeq);
701 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
702 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
703 dfree_retval : dfreeq_retval ;
704 /* maybe dfree and dfreeq are calculated using different bsizes
705 so convert dfree from bsize into bsizeq */
706 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
707 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
712 return(dfree_retval);
716 DEBUG(1,("Warning - no statfs function\n"));
720 if (statfs(path,&fs,sizeof(fs),0) != 0)
723 if (statvfs(path, &fs))
726 if (statfs(path,&fs,sizeof(fs)) == -1)
728 if (statfs(path,&fs) == -1)
730 #endif /* USE_STATVFS */
733 DEBUG(3,("dfree call failed code errno=%d\n",errno));
737 return(((*bsize)/1024)*(*dfree));
742 *dfree = fs.fd_req.bfree;
743 *dsize = fs.fd_req.btot;
746 *bsize = fs.f_frsize;
749 /* eg: osf1 has f_fsize = fundamental filesystem block size,
750 f_bsize = optimal transfer block size (MX: 94-04-19) */
755 #endif /* USE_STATVFS */
760 *dfree = fs.f_bavail;
762 *dsize = fs.f_blocks;
765 #if defined(SCO) || defined(ISC) || defined(MIPS)
769 /* handle rediculous bsize values - some OSes are broken */
770 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
772 disk_norm(bsize,dfree,dsize);
778 DEBUG(0,("dfree seems to be broken on your system\n"));
779 *dsize = 20*1024*1024/(*bsize);
780 *dfree = MAX(1,*dfree);
782 dfree_retval = ((*bsize)/1024)*(*dfree);
784 /* Ensure we return the min value between the users quota and
785 what's free on the disk. Thanks to Albrecht Gebhardt
786 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
788 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
790 disk_norm(&bsizeq, &dfreeq, &dsizeq);
791 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
792 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
793 dfree_retval : dfreeq_retval ;
794 /* maybe dfree and dfreeq are calculated using different bsizes
795 so convert dfree from bsize into bsizeq */
796 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
797 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
802 return(dfree_retval);
807 /****************************************************************************
808 wrap it to get filenames right
809 ****************************************************************************/
810 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
812 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
817 /****************************************************************************
818 check a filename - possibly caling reducename
820 This is called by every routine before it allows an operation on a filename.
821 It does any final confirmation necessary to ensure that the filename is
822 a valid one for the user to access.
823 ****************************************************************************/
824 BOOL check_name(char *name,int cnum)
830 if( IS_VETO_PATH(cnum, name))
832 DEBUG(5,("file path name %s vetoed\n",name));
836 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
838 /* Check if we are allowing users to follow symlinks */
839 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
840 University of Geneva */
842 if (!lp_symlinks(SNUM(cnum)))
845 if ( (sys_lstat(name,&statbuf) != -1) &&
846 (S_ISLNK(statbuf.st_mode)) )
848 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
854 DEBUG(5,("check_name on %s failed\n",name));
859 /****************************************************************************
860 check a filename - possibly caling reducename
861 ****************************************************************************/
862 static void check_for_pipe(char *fname)
864 /* special case of pipe opens */
868 if (strstr(s,"pipe/"))
870 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
871 unix_ERR_class = ERRSRV;
872 unix_ERR_code = ERRaccess;
876 /****************************************************************************
877 fd support routines - attempt to do a sys_open
878 ****************************************************************************/
880 int fd_attempt_open(char *fname, int flags, int mode)
882 int fd = sys_open(fname,flags,mode);
884 /* Fix for files ending in '.' */
885 if((fd == -1) && (errno == ENOENT) &&
886 (strchr(fname,'.')==NULL))
889 fd = sys_open(fname,flags,mode);
892 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
893 if ((fd == -1) && (errno == ENAMETOOLONG))
896 char *p = strrchr(fname, '/');
898 if (p == fname) /* name is "/xxx" */
900 max_len = pathconf("/", _PC_NAME_MAX);
903 else if ((p == NULL) || (p == fname))
906 max_len = pathconf(".", _PC_NAME_MAX);
911 max_len = pathconf(fname, _PC_NAME_MAX);
915 if (strlen(p) > max_len)
917 char tmp = p[max_len];
920 if ((fd = sys_open(fname,flags,mode)) == -1)
928 /****************************************************************************
929 fd support routines - attempt to find an already open file by dev
930 and inode - increments the ref_count of the returned file_fd_struct *.
931 ****************************************************************************/
932 file_fd_struct *fd_get_already_open(struct stat *sbuf)
935 file_fd_struct *fd_ptr;
940 for(i = 0; i <= max_file_fd_used; i++) {
942 if((fd_ptr->ref_count > 0) &&
943 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
944 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
947 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
948 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
955 /****************************************************************************
956 fd support routines - attempt to find a empty slot in the FileFd array.
957 Increments the ref_count of the returned entry.
958 ****************************************************************************/
959 file_fd_struct *fd_get_new()
962 file_fd_struct *fd_ptr;
964 for(i = 0; i < MAX_OPEN_FILES; i++) {
966 if(fd_ptr->ref_count == 0) {
967 fd_ptr->dev = (uint32)-1;
968 fd_ptr->inode = (uint32)-1;
970 fd_ptr->fd_readonly = -1;
971 fd_ptr->fd_writeonly = -1;
972 fd_ptr->real_open_flags = -1;
974 /* Increment max used counter if neccessary, cuts down
975 on search time when re-using */
976 if(i > max_file_fd_used)
977 max_file_fd_used = i;
978 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
979 i, fd_ptr->dev, fd_ptr->inode));
983 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
988 /****************************************************************************
989 fd support routines - attempt to re-open an already open fd as O_RDWR.
990 Save the already open fd (we cannot close due to POSIX file locking braindamage.
991 ****************************************************************************/
993 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
995 int fd = sys_open( fname, O_RDWR, mode);
1000 if(fd_ptr->real_open_flags == O_RDONLY)
1001 fd_ptr->fd_readonly = fd_ptr->fd;
1002 if(fd_ptr->real_open_flags == O_WRONLY)
1003 fd_ptr->fd_writeonly = fd_ptr->fd;
1006 fd_ptr->real_open_flags = O_RDWR;
1009 /****************************************************************************
1010 fd support routines - attempt to close the file referenced by this fd.
1011 Decrements the ref_count and returns it.
1012 ****************************************************************************/
1013 int fd_attempt_close(file_fd_struct *fd_ptr)
1015 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1016 fd_ptr - &FileFd[0],
1017 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1018 fd_ptr->real_open_flags,
1019 fd_ptr->ref_count));
1020 if(fd_ptr->ref_count > 0) {
1021 fd_ptr->ref_count--;
1022 if(fd_ptr->ref_count == 0) {
1023 if(fd_ptr->fd != -1)
1025 if(fd_ptr->fd_readonly != -1)
1026 close(fd_ptr->fd_readonly);
1027 if(fd_ptr->fd_writeonly != -1)
1028 close(fd_ptr->fd_writeonly);
1030 fd_ptr->fd_readonly = -1;
1031 fd_ptr->fd_writeonly = -1;
1032 fd_ptr->real_open_flags = -1;
1033 fd_ptr->dev = (uint32)-1;
1034 fd_ptr->inode = (uint32)-1;
1037 return fd_ptr->ref_count;
1040 /****************************************************************************
1042 ****************************************************************************/
1043 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1045 extern struct current_user current_user;
1047 struct stat statbuf;
1048 file_fd_struct *fd_ptr;
1050 Files[fnum].open = False;
1051 Files[fnum].fd_ptr = 0;
1054 strcpy(fname,fname1);
1056 /* check permissions */
1057 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1059 DEBUG(3,("Permission denied opening %s\n",fname));
1060 check_for_pipe(fname);
1064 /* this handles a bug in Win95 - it doesn't say to create the file when it
1066 if (Connections[cnum].printer)
1070 if (flags == O_WRONLY)
1071 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1074 #if UTIME_WORKAROUND
1075 /* XXXX - is this OK?? */
1076 /* this works around a utime bug but can cause other problems */
1077 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1082 * Ensure we have a valid struct stat so we can search the
1086 if(stat(fname, &statbuf) < 0) {
1087 if(errno != ENOENT) {
1088 DEBUG(3,("Error doing stat on file %s (%s)\n",
1089 fname,strerror(errno)));
1091 check_for_pipe(fname);
1101 * Check to see if we have this file already
1102 * open. If we do, just use the already open fd and increment the
1103 * reference count (fd_get_already_open increments the ref_count).
1105 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1107 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1109 /* File was already open. */
1110 if((flags & O_CREAT) && (flags & O_EXCL)) {
1111 fd_ptr->ref_count--;
1117 * If not opened O_RDWR try
1118 * and do that here - a chmod may have been done
1119 * between the last open and now.
1121 if(fd_ptr->real_open_flags != O_RDWR)
1122 fd_attempt_reopen(fname, mode, fd_ptr);
1125 * Ensure that if we wanted write access
1126 * it has been opened for write, and if we wanted read it
1127 * was open for read.
1129 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1130 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1131 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1132 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1133 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1134 check_for_pipe(fname);
1135 fd_ptr->ref_count--;
1141 /* We need to allocate a new file_fd_struct (this increments the
1143 if((fd_ptr = fd_get_new()) == 0)
1146 * Whatever the requested flags, attempt read/write access,
1147 * as we don't know what flags future file opens may require.
1148 * If this fails, try again with the required flags.
1149 * Even if we open read/write when only read access was
1150 * requested the setting of the can_write flag in
1151 * the file_struct will protect us from errant
1152 * write requests. We never need to worry about O_APPEND
1153 * as this is not set anywhere in Samba.
1155 fd_ptr->real_open_flags = O_RDWR;
1156 /* Set the flags as needed without the read/write modes. */
1157 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1158 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1160 * On some systems opening a file for R/W access on a read only
1161 * filesystems sets errno to EROFS.
1164 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1165 #else /* No EROFS */
1166 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1168 if(flags & O_WRONLY) {
1169 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1170 fd_ptr->real_open_flags = O_WRONLY;
1172 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1173 fd_ptr->real_open_flags = O_RDONLY;
1178 if ((fd_ptr->fd >=0) &&
1179 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1183 strcpy(dname,fname);
1184 p = strrchr(dname,'/');
1186 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1187 lp_minprintspace(SNUM(cnum))) {
1188 fd_attempt_close(fd_ptr);
1189 Files[fnum].fd_ptr = 0;
1190 if(fd_ptr->ref_count == 0)
1199 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1200 fname,strerror(errno),flags));
1201 /* Ensure the ref_count is decremented. */
1202 fd_attempt_close(fd_ptr);
1203 check_for_pipe(fname);
1207 if (fd_ptr->fd >= 0)
1211 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1212 /* Error - backout !! */
1213 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1214 fd_ptr->fd, fname,strerror(errno)));
1215 /* Ensure the ref_count is decremented. */
1216 fd_attempt_close(fd_ptr);
1221 /* Set the correct entries in fd_ptr. */
1222 fd_ptr->dev = (uint32)sbuf->st_dev;
1223 fd_ptr->inode = (uint32)sbuf->st_ino;
1225 Files[fnum].fd_ptr = fd_ptr;
1226 Connections[cnum].num_files_open++;
1227 Files[fnum].mode = sbuf->st_mode;
1228 GetTimeOfDay(&Files[fnum].open_time);
1229 Files[fnum].uid = current_user.id;
1230 Files[fnum].size = 0;
1231 Files[fnum].pos = -1;
1232 Files[fnum].open = True;
1233 Files[fnum].mmap_ptr = NULL;
1234 Files[fnum].mmap_size = 0;
1235 Files[fnum].can_lock = True;
1236 Files[fnum].can_read = ((flags & O_WRONLY)==0);
1237 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1238 Files[fnum].share_mode = 0;
1239 Files[fnum].print_file = Connections[cnum].printer;
1240 Files[fnum].modified = False;
1241 Files[fnum].cnum = cnum;
1242 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1243 Files[fnum].wbmpx_ptr = NULL;
1246 * If the printer is marked as postscript output a leading
1247 * file identifier to ensure the file is treated as a raw
1249 * This has a similar effect as CtrlD=0 in WIN.INI file.
1250 * tim@fsg.com 09/06/94
1252 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1253 Files[fnum].can_write)
1255 DEBUG(3,("Writing postscript line\n"));
1256 write_file(fnum,"%!\n",3);
1259 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1260 timestring(),Connections[cnum].user,fname,
1261 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1262 Connections[cnum].num_files_open,fnum));
1267 /* mmap it if read-only */
1268 if (!Files[fnum].can_write)
1270 Files[fnum].mmap_size = file_size(fname);
1271 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1272 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1274 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1276 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1277 Files[fnum].mmap_ptr = NULL;
1283 /*******************************************************************
1285 ********************************************************************/
1286 void sync_file(int fnum)
1289 fsync(Files[fnum].fd_ptr->fd);
1293 /****************************************************************************
1294 run a file if it is a magic script
1295 ****************************************************************************/
1296 static void check_magic(int fnum,int cnum)
1298 if (!*lp_magicscript(SNUM(cnum)))
1301 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1305 if (!(p = strrchr(Files[fnum].name,'/')))
1306 p = Files[fnum].name;
1310 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1316 pstring magic_output;
1318 strcpy(fname,Files[fnum].name);
1320 if (*lp_magicoutput(SNUM(cnum)))
1321 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1323 sprintf(magic_output,"%s.out",fname);
1326 ret = smbrun(fname,magic_output,False);
1327 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1333 /****************************************************************************
1334 close a file - possibly invalidating the read prediction
1335 ****************************************************************************/
1336 void close_file(int fnum)
1338 files_struct *fs_p = &Files[fnum];
1339 int cnum = fs_p->cnum;
1340 uint32 dev = fs_p->fd_ptr->dev;
1341 uint32 inode = fs_p->fd_ptr->inode;
1342 share_lock_token token;
1344 invalidate_read_prediction(fs_p->fd_ptr->fd);
1346 Connections[cnum].num_files_open--;
1349 free((char *)fs_p->wbmpx_ptr);
1350 fs_p->wbmpx_ptr = NULL;
1356 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1357 fs_p->mmap_ptr = NULL;
1361 if (lp_share_modes(SNUM(cnum)))
1363 lock_share_entry( cnum, dev, inode, &token);
1364 del_share_mode(token, fnum);
1367 fd_attempt_close(fs_p->fd_ptr);
1369 if (lp_share_modes(SNUM(cnum)))
1370 unlock_share_entry( cnum, dev, inode, token);
1372 /* NT uses smbclose to start a print - weird */
1373 if (fs_p->print_file)
1376 /* check for magic scripts */
1377 check_magic(fnum,cnum);
1379 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1380 timestring(),Connections[cnum].user,fs_p->name,
1381 Connections[cnum].num_files_open));
1384 enum {AFAIL,AREAD,AWRITE,AALL};
1386 /*******************************************************************
1387 reproduce the share mode access table
1388 ********************************************************************/
1389 static int access_table(int new_deny,int old_deny,int old_mode,
1390 int share_pid,char *fname)
1392 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1394 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1395 if (old_deny == new_deny && share_pid == getpid())
1398 if (old_mode == 0) return(AREAD);
1400 /* the new smbpub.zip spec says that if the file extension is
1401 .com, .dll, .exe or .sym then allow the open. I will force
1402 it to read-only as this seems sensible although the spec is
1403 a little unclear on this. */
1404 if ((fname = strrchr(fname,'.'))) {
1405 if (strequal(fname,".com") ||
1406 strequal(fname,".dll") ||
1407 strequal(fname,".exe") ||
1408 strequal(fname,".sym"))
1418 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1419 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1420 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1423 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1424 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1425 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1428 if (old_deny==DENY_WRITE) return(AREAD);
1429 if (old_deny==DENY_READ) return(AWRITE);
1430 if (old_deny==DENY_NONE) return(AALL);
1436 /*******************************************************************
1437 check if the share mode on a file allows it to be deleted or unlinked
1438 return True if sharing doesn't prevent the operation
1439 ********************************************************************/
1440 BOOL check_file_sharing(int cnum,char *fname)
1444 min_share_mode_entry *old_shares = 0;
1445 int num_share_modes;
1447 share_lock_token token;
1450 if(!lp_share_modes(SNUM(cnum)))
1453 if (stat(fname,&sbuf) == -1) return(True);
1455 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1456 num_share_modes = get_share_modes(cnum, token,
1457 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1459 for( i = 0; i < num_share_modes; i++)
1461 if (old_shares[i].share_mode != DENY_DOS)
1464 if(old_shares[i].pid != pid)
1468 /* XXXX exactly what share mode combinations should be allowed for
1469 deleting/renaming? */
1470 /* If we got here then either there were no share modes or
1471 all share modes were DENY_DOS and the pid == getpid() */
1476 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1477 if(old_shares != NULL)
1478 free((char *)old_shares);
1482 /****************************************************************************
1484 Helper for open_file_shared.
1485 Truncate a file after checking locking; close file if locked.
1486 **************************************************************************/
1487 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1490 if (Files[fnum].can_write){
1491 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1492 /* If share modes are in force for this connection we
1493 have the share entry locked. Unlock it before closing. */
1494 if (*share_locked && lp_share_modes(SNUM(cnum)))
1495 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1496 Files[fnum].fd_ptr->inode, token);
1498 /* Share mode no longer locked. */
1499 *share_locked = False;
1501 unix_ERR_class = ERRDOS;
1502 unix_ERR_code = ERRlock;
1505 ftruncate(Files[fnum].fd_ptr->fd,0);
1510 /****************************************************************************
1511 open a file with a share mode
1512 ****************************************************************************/
1513 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1514 int mode,int *Access,int *action)
1516 files_struct *fs_p = &Files[fnum];
1519 int deny_mode = (share_mode>>4)&7;
1521 BOOL file_existed = file_exist(fname,&sbuf);
1522 BOOL share_locked = False;
1523 BOOL fcbopen = False;
1524 share_lock_token token;
1531 /* this is for OS/2 EAs - try and say we don't support them */
1532 if (strstr(fname,".+,;=[]."))
1534 unix_ERR_class = ERRDOS;
1535 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1539 if ((ofun & 0x3) == 0 && file_existed)
1547 if ((ofun & 0x3) == 2)
1550 /* note that we ignore the append flag as
1551 append does not mean the same thing under dos and unix */
1553 switch (share_mode&0xF)
1570 if (flags != O_RDONLY && file_existed &&
1571 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1581 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1583 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1588 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1590 if (lp_share_modes(SNUM(cnum)))
1594 min_share_mode_entry *old_shares = 0;
1599 dev = (uint32)sbuf.st_dev;
1600 inode = (uint32)sbuf.st_ino;
1601 lock_share_entry(cnum, dev, inode, &token);
1602 share_locked = True;
1603 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1606 for(i = 0; i < num_shares; i++)
1608 /* someone else has a share lock on it, check to see
1610 int old_open_mode = old_shares[i].share_mode &0xF;
1611 int old_deny_mode = (old_shares[i].share_mode >>4)&7;
1613 if (old_deny_mode > 4 || old_open_mode > 2)
1615 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1616 deny_mode,old_deny_mode,old_open_mode,fname));
1617 free((char *)old_shares);
1619 unlock_share_entry(cnum, dev, inode, token);
1621 unix_ERR_class = ERRDOS;
1622 unix_ERR_code = ERRbadshare;
1627 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1628 old_shares[i].pid,fname);
1630 if ((access_allowed == AFAIL) ||
1631 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1632 (access_allowed == AREAD && flags == O_WRONLY) ||
1633 (access_allowed == AWRITE && flags == O_RDONLY))
1635 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1636 deny_mode,old_deny_mode,old_open_mode,
1637 old_shares[i].pid,fname,
1639 free((char *)old_shares);
1641 unlock_share_entry(cnum, dev, inode, token);
1643 unix_ERR_class = ERRDOS;
1644 unix_ERR_code = ERRbadshare;
1648 if (access_allowed == AREAD)
1651 if (access_allowed == AWRITE)
1656 free((char *)old_shares);
1659 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1660 flags,flags2,mode));
1662 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1663 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1666 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1673 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1675 /* We created the file - thus we must now lock the share entry before creating it. */
1676 dev = fs_p->fd_ptr->dev;
1677 inode = fs_p->fd_ptr->inode;
1678 lock_share_entry(cnum, dev, inode, &token);
1679 share_locked = True;
1695 fs_p->share_mode = (deny_mode<<4) | open_mode;
1698 (*Access) = open_mode;
1702 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1703 if (!file_existed) *action = 2;
1704 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1706 /* We must create the share mode entry before truncate as
1707 truncate can fail due to locking and have to close the
1708 file (which expects the share_mode_entry to be there).
1710 if (lp_share_modes(SNUM(cnum)))
1711 set_share_mode(token, fnum);
1713 if ((flags2&O_TRUNC) && file_existed)
1714 truncate_unless_locked(fnum,cnum,token,&share_locked);
1717 if (share_locked && lp_share_modes(SNUM(cnum)))
1718 unlock_share_entry( cnum, dev, inode, token);
1721 /****************************************************************************
1722 seek a file. Try to avoid the seek if possible
1723 ****************************************************************************/
1724 int seek_file(int fnum,uint32 pos)
1727 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1730 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1732 return(Files[fnum].pos);
1735 /****************************************************************************
1737 ****************************************************************************/
1738 int read_file(int fnum,char *data,uint32 pos,int n)
1742 if (!Files[fnum].can_write)
1744 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1752 if (Files[fnum].mmap_ptr)
1754 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1757 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1769 if (seek_file(fnum,pos) != pos)
1771 DEBUG(3,("Failed to seek to %d\n",pos));
1776 readret = read(Files[fnum].fd_ptr->fd,data,n);
1777 if (readret > 0) ret += readret;
1784 /****************************************************************************
1786 ****************************************************************************/
1787 int write_file(int fnum,char *data,int n)
1789 if (!Files[fnum].can_write) {
1794 if (!Files[fnum].modified) {
1796 Files[fnum].modified = True;
1797 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1798 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1799 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1800 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1805 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1809 /****************************************************************************
1810 load parameters specific to a connection/service
1811 ****************************************************************************/
1812 BOOL become_service(int cnum,BOOL do_chdir)
1814 extern char magic_char;
1815 static int last_cnum = -1;
1818 if (!OPEN_CNUM(cnum))
1824 Connections[cnum].lastused = smb_last_time;
1829 ChDir(Connections[cnum].connectpath) != 0 &&
1830 ChDir(Connections[cnum].origpath) != 0)
1832 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1833 Connections[cnum].connectpath,cnum));
1837 if (cnum == last_cnum)
1842 case_default = lp_defaultcase(snum);
1843 case_preserve = lp_preservecase(snum);
1844 short_case_preserve = lp_shortpreservecase(snum);
1845 case_mangle = lp_casemangle(snum);
1846 case_sensitive = lp_casesensitive(snum);
1847 magic_char = lp_magicchar(snum);
1848 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1853 /****************************************************************************
1854 find a service entry
1855 ****************************************************************************/
1856 int find_service(char *service)
1860 string_sub(service,"\\","/");
1862 iService = lp_servicenumber(service);
1864 /* now handle the special case of a home directory */
1867 char *phome_dir = get_home_dir(service);
1868 DEBUG(3,("checking for home directory %s gave %s\n",service,
1869 phome_dir?phome_dir:"(NULL)"));
1873 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1875 lp_add_home(service,iHomeService,phome_dir);
1876 iService = lp_servicenumber(service);
1881 /* If we still don't have a service, attempt to add it as a printer. */
1884 int iPrinterService;
1886 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1890 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1892 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1894 DEBUG(3,("%s is a valid printer name\n", service));
1895 DEBUG(3,("adding %s as a printer service\n", service));
1896 lp_add_printer(service,iPrinterService);
1897 iService = lp_servicenumber(service);
1899 DEBUG(0,("failed to add %s as a printer service!\n", service));
1902 DEBUG(3,("%s is not a valid printer name\n", service));
1906 /* just possibly it's a default service? */
1909 char *defservice = lp_defaultservice();
1910 if (defservice && *defservice && !strequal(defservice,service)) {
1911 iService = find_service(defservice);
1912 if (iService >= 0) {
1913 string_sub(service,"_","/");
1914 iService = lp_add_service(service,iService);
1920 if (!VALID_SNUM(iService))
1922 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1927 DEBUG(3,("find_service() failed to find service %s\n", service));
1933 /****************************************************************************
1934 create an error packet from a cached error.
1935 ****************************************************************************/
1936 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1938 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1940 int32 eclass = wbmpx->wr_errclass;
1941 int32 err = wbmpx->wr_error;
1943 /* We can now delete the auxiliary struct */
1944 free((char *)wbmpx);
1945 Files[fnum].wbmpx_ptr = NULL;
1946 return error_packet(inbuf,outbuf,eclass,err,line);
1955 } unix_smb_errmap[] =
1957 {EPERM,ERRDOS,ERRnoaccess},
1958 {EACCES,ERRDOS,ERRnoaccess},
1959 {ENOENT,ERRDOS,ERRbadfile},
1960 {ENOTDIR,ERRDOS,ERRbaddirectory},
1961 {EIO,ERRHRD,ERRgeneral},
1962 {EBADF,ERRSRV,ERRsrverror},
1963 {EINVAL,ERRSRV,ERRsrverror},
1964 {EEXIST,ERRDOS,ERRfilexists},
1965 {ENFILE,ERRDOS,ERRnofids},
1966 {EMFILE,ERRDOS,ERRnofids},
1967 {ENOSPC,ERRHRD,ERRdiskfull},
1969 {EDQUOT,ERRHRD,ERRdiskfull},
1972 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1975 {EXDEV,ERRDOS,ERRdiffdevice},
1977 {EROFS,ERRHRD,ERRnowrite},
1982 /****************************************************************************
1983 create an error packet from errno
1984 ****************************************************************************/
1985 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1987 int eclass=def_class;
1991 if (unix_ERR_class != SUCCESS)
1993 eclass = unix_ERR_class;
1994 ecode = unix_ERR_code;
1995 unix_ERR_class = SUCCESS;
2000 while (unix_smb_errmap[i].smbclass != 0)
2002 if (unix_smb_errmap[i].unixerror == errno)
2004 eclass = unix_smb_errmap[i].smbclass;
2005 ecode = unix_smb_errmap[i].smbcode;
2012 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2016 /****************************************************************************
2017 create an error packet. Normally called using the ERROR() macro
2018 ****************************************************************************/
2019 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2021 int outsize = set_message(outbuf,0,0,True);
2023 cmd = CVAL(inbuf,smb_com);
2025 CVAL(outbuf,smb_rcls) = error_class;
2026 SSVAL(outbuf,smb_err,error_code);
2028 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2031 (int)CVAL(inbuf,smb_com),
2032 smb_fn_name(CVAL(inbuf,smb_com)),
2037 DEBUG(3,("error string = %s\n",strerror(errno)));
2043 #ifndef SIGCLD_IGNORE
2044 /****************************************************************************
2045 this prevents zombie child processes
2046 ****************************************************************************/
2047 static int sig_cld()
2049 static int depth = 0;
2052 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2058 BlockSignals(True,SIGCLD);
2059 DEBUG(5,("got SIGCLD\n"));
2062 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2066 /* Stevens, Adv. Unix Prog. says that on system V you must call
2067 wait before reinstalling the signal handler, because the kernel
2068 calls the handler from within the signal-call when there is a
2069 child that has exited. This would lead to an infinite recursion
2070 if done vice versa. */
2072 #ifndef DONT_REINSTALL_SIG
2073 #ifdef SIGCLD_IGNORE
2074 signal(SIGCLD, SIG_IGN);
2076 signal(SIGCLD, SIGNAL_CAST sig_cld);
2081 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2084 BlockSignals(False,SIGCLD);
2089 /****************************************************************************
2090 this is called when the client exits abruptly
2091 **************************************************************************/
2092 static int sig_pipe()
2094 extern int password_client;
2095 BlockSignals(True,SIGPIPE);
2097 if (password_client != -1) {
2098 DEBUG(3,("lost connection to password server\n"));
2099 close(password_client);
2100 password_client = -1;
2101 #ifndef DONT_REINSTALL_SIG
2102 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2104 BlockSignals(False,SIGPIPE);
2108 exit_server("Got sigpipe\n");
2112 /****************************************************************************
2113 open the socket communication
2114 ****************************************************************************/
2115 static BOOL open_sockets(BOOL is_daemon,int port)
2122 struct sockaddr addr;
2123 int in_addrlen = sizeof(addr);
2126 #ifdef SIGCLD_IGNORE
2127 signal(SIGCLD, SIG_IGN);
2129 signal(SIGCLD, SIGNAL_CAST sig_cld);
2132 /* open an incoming socket */
2133 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2137 /* ready to listen */
2138 if (listen(s, 5) == -1)
2140 DEBUG(0,("listen: %s\n",strerror(errno)));
2148 /* now accept incoming connections - forking a new process
2149 for each incoming connection */
2150 DEBUG(2,("waiting for a connection\n"));
2153 Client = accept(s,&addr,&in_addrlen);
2155 if (Client == -1 && errno == EINTR)
2160 DEBUG(0,("accept: %s\n",strerror(errno)));
2164 #ifdef NO_FORK_DEBUG
2165 #ifndef NO_SIGNAL_TEST
2166 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2167 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2171 if (Client != -1 && fork()==0)
2173 /* Child code ... */
2174 #ifndef NO_SIGNAL_TEST
2175 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2176 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2178 /* close the listening socket */
2181 /* close our standard file descriptors */
2185 set_socket_options(Client,"SO_KEEPALIVE");
2186 set_socket_options(Client,user_socket_options);
2188 /* Reset global variables in util.c so that
2189 client substitutions will be done correctly
2192 reset_globals_after_fork();
2195 close(Client); /* The parent doesn't need this socket */
2201 /* We will abort gracefully when the client or remote system
2203 #ifndef NO_SIGNAL_TEST
2204 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2208 /* close our standard file descriptors */
2211 set_socket_options(Client,"SO_KEEPALIVE");
2212 set_socket_options(Client,user_socket_options);
2219 /****************************************************************************
2220 check if a snum is in use
2221 ****************************************************************************/
2222 BOOL snum_used(int snum)
2225 for (i=0;i<MAX_CONNECTIONS;i++)
2226 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2231 /****************************************************************************
2232 reload the services file
2233 **************************************************************************/
2234 BOOL reload_services(BOOL test)
2241 strcpy(fname,lp_configfile());
2242 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2244 strcpy(servicesf,fname);
2251 if (test && !lp_file_list_changed())
2254 lp_killunused(snum_used);
2256 ret = lp_load(servicesf,False);
2258 /* perhaps the config filename is now set */
2260 reload_services(True);
2269 set_socket_options(Client,"SO_KEEPALIVE");
2270 set_socket_options(Client,user_socket_options);
2274 create_mangled_stack(lp_mangledstack());
2276 /* this forces service parameters to be flushed */
2277 become_service(-1,True);
2284 /****************************************************************************
2285 this prevents zombie child processes
2286 ****************************************************************************/
2287 static int sig_hup()
2289 BlockSignals(True,SIGHUP);
2290 DEBUG(0,("Got SIGHUP\n"));
2291 reload_services(False);
2292 #ifndef DONT_REINSTALL_SIG
2293 signal(SIGHUP,SIGNAL_CAST sig_hup);
2295 BlockSignals(False,SIGHUP);
2299 /****************************************************************************
2300 Setup the groups a user belongs to.
2301 ****************************************************************************/
2302 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2303 int **p_igroups, gid_t **p_groups)
2305 if (-1 == initgroups(user,gid))
2309 DEBUG(0,("Unable to initgroups!\n"));
2310 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2311 DEBUG(0,("This is probably a problem with the account %s\n",user));
2319 ngroups = getgroups(0,&grp);
2322 igroups = (int *)malloc(sizeof(int)*ngroups);
2323 for (i=0;i<ngroups;i++)
2324 igroups[i] = 0x42424242;
2325 ngroups = getgroups(ngroups,(gid_t *)igroups);
2327 if (igroups[0] == 0x42424242)
2330 *p_ngroups = ngroups;
2332 /* The following bit of code is very strange. It is due to the
2333 fact that some OSes use int* and some use gid_t* for
2334 getgroups, and some (like SunOS) use both, one in prototypes,
2335 and one in man pages and the actual code. Thus we detect it
2336 dynamically using some very ugly code */
2339 /* does getgroups return ints or gid_t ?? */
2340 static BOOL groups_use_ints = True;
2342 if (groups_use_ints &&
2344 SVAL(igroups,2) == 0x4242)
2345 groups_use_ints = False;
2347 for (i=0;groups_use_ints && i<ngroups;i++)
2348 if (igroups[i] == 0x42424242)
2349 groups_use_ints = False;
2351 if (groups_use_ints)
2353 *p_igroups = igroups;
2354 *p_groups = (gid_t *)igroups;
2358 gid_t *groups = (gid_t *)igroups;
2359 igroups = (int *)malloc(sizeof(int)*ngroups);
2360 for (i=0;i<ngroups;i++)
2361 igroups[i] = groups[i];
2362 *p_igroups = igroups;
2363 *p_groups = (gid_t *)groups;
2366 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2367 for (i=0;i<ngroups;i++)
2368 DEBUG(3,("%d ",igroups[i]));
2374 /****************************************************************************
2375 make a connection to a service
2376 ****************************************************************************/
2377 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2381 struct passwd *pass = NULL;
2382 connection_struct *pcon;
2385 static BOOL first_connection = True;
2389 snum = find_service(service);
2392 if (strequal(service,"IPC$"))
2394 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2398 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2402 if (strequal(service,HOMES_NAME))
2404 if (*user && Get_Pwnam(user,True))
2405 return(make_connection(user,user,password,pwlen,dev,vuid));
2407 if (validated_username(vuid))
2409 strcpy(user,validated_username(vuid));
2410 return(make_connection(user,user,password,pwlen,dev,vuid));
2414 if (!lp_snum_ok(snum) || !check_access(snum)) {
2418 /* you can only connect to the IPC$ service as an ipc device */
2419 if (strequal(service,"IPC$"))
2422 if (*dev == '?' || !*dev)
2424 if (lp_print_ok(snum))
2425 strcpy(dev,"LPT1:");
2430 /* if the request is as a printer and you can't print then refuse */
2432 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2433 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2437 /* lowercase the user name */
2440 /* add it as a possible user name */
2441 add_session_user(service);
2443 /* shall we let them in? */
2444 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2446 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2450 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2453 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2457 pcon = &Connections[cnum];
2458 bzero((char *)pcon,sizeof(*pcon));
2460 /* find out some info about the user */
2461 pass = Get_Pwnam(user,True);
2465 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2469 pcon->read_only = lp_readonly(snum);
2473 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2474 string_sub(list,"%S",service);
2476 if (user_in_list(user,list))
2477 pcon->read_only = True;
2479 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2480 string_sub(list,"%S",service);
2482 if (user_in_list(user,list))
2483 pcon->read_only = False;
2486 /* admin user check */
2487 if (user_in_list(user,lp_admin_users(snum)) &&
2490 pcon->admin_user = True;
2491 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2494 pcon->admin_user = False;
2496 pcon->force_user = force;
2498 pcon->uid = pass->pw_uid;
2499 pcon->gid = pass->pw_gid;
2500 pcon->num_files_open = 0;
2501 pcon->lastused = time(NULL);
2502 pcon->service = snum;
2504 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2505 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2506 pcon->dirptr = NULL;
2507 pcon->veto_list = NULL;
2508 pcon->hide_list = NULL;
2509 string_set(&pcon->dirpath,"");
2510 string_set(&pcon->user,user);
2513 if (*lp_force_group(snum))
2518 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2519 /* default service may be a group name */
2520 string_sub(gname,"%S",service);
2521 gptr = (struct group *)getgrnam(gname);
2525 pcon->gid = gptr->gr_gid;
2526 DEBUG(3,("Forced group %s\n",gname));
2529 DEBUG(1,("Couldn't find group %s\n",gname));
2533 if (*lp_force_user(snum))
2535 struct passwd *pass2;
2537 strcpy(fuser,lp_force_user(snum));
2538 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2541 pcon->uid = pass2->pw_uid;
2542 string_set(&pcon->user,fuser);
2544 pcon->force_user = True;
2545 DEBUG(3,("Forced user %s\n",fuser));
2548 DEBUG(1,("Couldn't find user %s\n",fuser));
2553 strcpy(s,lp_pathname(snum));
2554 standard_sub(cnum,s);
2555 string_set(&pcon->connectpath,s);
2556 DEBUG(3,("Connect path is %s\n",s));
2559 /* groups stuff added by ih */
2561 pcon->groups = NULL;
2565 /* Find all the groups this uid is in and store them. Used by become_user() */
2566 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2568 /* check number of connections */
2569 if (!claim_connection(cnum,
2570 lp_servicename(SNUM(cnum)),
2571 lp_max_connections(SNUM(cnum)),False))
2573 DEBUG(1,("too many connections - rejected\n"));
2577 if (lp_status(SNUM(cnum)))
2578 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2580 first_connection = False;
2585 /* execute any "root preexec = " line */
2586 if (*lp_rootpreexec(SNUM(cnum)))
2589 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2590 standard_sub(cnum,cmd);
2591 DEBUG(5,("cmd=%s\n",cmd));
2592 smbrun(cmd,NULL,False);
2595 if (!become_user(cnum,pcon->vuid))
2597 DEBUG(0,("Can't become connected user!\n"));
2599 if (!IS_IPC(cnum)) {
2600 yield_connection(cnum,
2601 lp_servicename(SNUM(cnum)),
2602 lp_max_connections(SNUM(cnum)));
2603 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2608 if (ChDir(pcon->connectpath) != 0)
2610 DEBUG(0,("Can't change directory to %s (%s)\n",
2611 pcon->connectpath,strerror(errno)));
2614 if (!IS_IPC(cnum)) {
2615 yield_connection(cnum,
2616 lp_servicename(SNUM(cnum)),
2617 lp_max_connections(SNUM(cnum)));
2618 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2623 string_set(&pcon->origpath,pcon->connectpath);
2625 #if SOFTLINK_OPTIMISATION
2626 /* resolve any soft links early */
2629 strcpy(s,pcon->connectpath);
2631 string_set(&pcon->connectpath,s);
2632 ChDir(pcon->connectpath);
2636 num_connections_open++;
2637 add_session_user(user);
2639 /* execute any "preexec = " line */
2640 if (*lp_preexec(SNUM(cnum)))
2643 strcpy(cmd,lp_preexec(SNUM(cnum)));
2644 standard_sub(cnum,cmd);
2645 smbrun(cmd,NULL,False);
2648 /* we've finished with the sensitive stuff */
2651 /* Add veto/hide lists */
2652 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
2654 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
2655 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
2659 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2663 lp_servicename(SNUM(cnum)),user,
2673 /****************************************************************************
2674 find first available file slot
2675 ****************************************************************************/
2676 int find_free_file(void )
2679 /* we start at 1 here for an obscure reason I can't now remember,
2680 but I think is important :-) */
2681 for (i=1;i<MAX_OPEN_FILES;i++)
2684 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2688 /****************************************************************************
2689 find first available connection slot, starting from a random position.
2690 The randomisation stops problems with the server dieing and clients
2691 thinking the server is still available.
2692 ****************************************************************************/
2693 static int find_free_connection(int hash )
2697 hash = (hash % (MAX_CONNECTIONS-2))+1;
2701 for (i=hash+1;i!=hash;)
2703 if (!Connections[i].open && Connections[i].used == used)
2705 DEBUG(3,("found free connection number %d\n",i));
2709 if (i == MAX_CONNECTIONS)
2719 DEBUG(1,("ERROR! Out of connection structures\n"));
2724 /****************************************************************************
2725 reply for the core protocol
2726 ****************************************************************************/
2727 int reply_corep(char *outbuf)
2729 int outsize = set_message(outbuf,1,0,True);
2731 Protocol = PROTOCOL_CORE;
2737 /****************************************************************************
2738 reply for the coreplus protocol
2739 ****************************************************************************/
2740 int reply_coreplus(char *outbuf)
2742 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2743 int outsize = set_message(outbuf,13,0,True);
2744 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2745 readbraw and writebraw (possibly) */
2746 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2747 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2749 Protocol = PROTOCOL_COREPLUS;
2755 /****************************************************************************
2756 reply for the lanman 1.0 protocol
2757 ****************************************************************************/
2758 int reply_lanman1(char *outbuf)
2760 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2762 BOOL doencrypt = SMBENCRYPT();
2763 time_t t = time(NULL);
2764 /* We need to save and restore this as it can be destroyed
2765 if we call another server if security=server
2766 Thanks to Paul Nelson @ Thursby for pointing this out.
2768 uint16 mid = SVAL(outbuf, smb_mid);
2770 if (lp_security()>=SEC_USER) secword |= 1;
2771 if (doencrypt) secword |= 2;
2773 set_message(outbuf,13,doencrypt?8:0,True);
2774 SSVAL(outbuf,smb_vwv1,secword);
2776 /* Create a token value and add it to the outgoing packet. */
2778 generate_next_challenge(smb_buf(outbuf));
2781 Protocol = PROTOCOL_LANMAN1;
2783 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2784 DEBUG(3,("using password server validation\n"));
2786 if (doencrypt) set_challenge(smb_buf(outbuf));
2790 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2791 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2792 SSVAL(outbuf,smb_vwv2,max_recv);
2793 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2794 SSVAL(outbuf,smb_vwv4,1);
2795 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2796 readbraw writebraw (possibly) */
2797 SIVAL(outbuf,smb_vwv6,getpid());
2798 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2800 put_dos_date(outbuf,smb_vwv8,t);
2802 return (smb_len(outbuf)+4);
2806 /****************************************************************************
2807 reply for the lanman 2.0 protocol
2808 ****************************************************************************/
2809 int reply_lanman2(char *outbuf)
2811 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2813 BOOL doencrypt = SMBENCRYPT();
2814 time_t t = time(NULL);
2815 /* We need to save and restore this as it can be destroyed
2816 if we call another server if security=server
2817 Thanks to Paul Nelson @ Thursby for pointing this out.
2819 uint16 mid = SVAL(outbuf, smb_mid);
2821 if (lp_security()>=SEC_USER) secword |= 1;
2822 if (doencrypt) secword |= 2;
2824 set_message(outbuf,13,doencrypt?8:0,True);
2825 SSVAL(outbuf,smb_vwv1,secword);
2827 /* Create a token value and add it to the outgoing packet. */
2829 generate_next_challenge(smb_buf(outbuf));
2832 SIVAL(outbuf,smb_vwv6,getpid());
2834 Protocol = PROTOCOL_LANMAN2;
2836 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2837 DEBUG(3,("using password server validation\n"));
2839 if (doencrypt) set_challenge(smb_buf(outbuf));
2843 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2844 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2845 SSVAL(outbuf,smb_vwv2,max_recv);
2846 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2847 SSVAL(outbuf,smb_vwv4,1);
2848 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2849 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2850 put_dos_date(outbuf,smb_vwv8,t);
2852 return (smb_len(outbuf)+4);
2856 /****************************************************************************
2857 reply for the nt protocol
2858 ****************************************************************************/
2859 int reply_nt1(char *outbuf)
2861 /* dual names + lock_and_read + nt SMBs + remote API calls */
2862 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2864 other valid capabilities which we may support at some time...
2865 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2866 CAP_LARGE_FILES|CAP_LARGE_READX|
2867 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2871 BOOL doencrypt = SMBENCRYPT();
2872 time_t t = time(NULL);
2875 char challenge_len = 8;
2876 /* We need to save and restore this as it can be destroyed
2877 if we call another server if security=server
2878 Thanks to Paul Nelson @ Thursby for pointing this out.
2880 uint16 mid = SVAL(outbuf, smb_mid);
2882 if (lp_readraw() && lp_writeraw())
2884 capabilities |= CAP_RAW_MODE;
2887 if (lp_security()>=SEC_USER) secword |= 1;
2888 if (doencrypt) secword |= 2;
2890 /* decide where (if) to put the encryption challenge, and
2891 follow it with the OEM'd domain name
2893 encrypt_len = doencrypt?challenge_len:0;
2895 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
2897 data_len = encrypt_len + strlen(myworkgroup) + 1;
2900 set_message(outbuf,17,data_len,True);
2903 /* put the OEM'd domain name */
2904 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
2906 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
2909 CVAL(outbuf,smb_vwv1) = secword;
2911 /* Create a token value and add it to the outgoing packet. */
2914 generate_next_challenge(smb_buf(outbuf));
2916 /* Tell the nt machine how long the challenge is. */
2917 SSVALS(outbuf,smb_vwv16+1,challenge_len);
2921 Protocol = PROTOCOL_NT1;
2923 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2924 DEBUG(3,("using password server validation\n"));
2926 if (doencrypt) set_challenge(smb_buf(outbuf));
2930 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2931 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2932 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2933 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
2934 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
2935 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2936 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2937 put_long_date(outbuf+smb_vwv11+1,t);
2938 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2939 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
2941 return (smb_len(outbuf)+4);
2944 /* these are the protocol lists used for auto architecture detection:
2947 protocol [PC NETWORK PROGRAM 1.0]
2948 protocol [XENIX CORE]
2949 protocol [MICROSOFT NETWORKS 1.03]
2950 protocol [LANMAN1.0]
2951 protocol [Windows for Workgroups 3.1a]
2952 protocol [LM1.2X002]
2953 protocol [LANMAN2.1]
2954 protocol [NT LM 0.12]
2957 protocol [PC NETWORK PROGRAM 1.0]
2958 protocol [XENIX CORE]
2959 protocol [MICROSOFT NETWORKS 1.03]
2960 protocol [LANMAN1.0]
2961 protocol [Windows for Workgroups 3.1a]
2962 protocol [LM1.2X002]
2963 protocol [LANMAN2.1]
2964 protocol [NT LM 0.12]
2967 protocol [PC NETWORK PROGRAM 1.0]
2968 protocol [XENIX CORE]
2969 protocol [LANMAN1.0]
2970 protocol [LM1.2X002]
2971 protocol [LANMAN2.1]
2975 * Modified to recognize the architecture of the remote machine better.
2977 * This appears to be the matrix of which protocol is used by which
2979 Protocol WfWg Win95 WinNT OS/2
2980 PC NETWORK PROGRAM 1.0 1 1 1 1
2982 MICROSOFT NETWORKS 3.0 2 2
2984 MICROSOFT NETWORKS 1.03 3
2987 Windows for Workgroups 3.1a 5 5 5
2992 * tim@fsg.com 09/29/95
2995 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2996 #define ARCH_WIN95 0x2
2997 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2998 #define ARCH_WINNT 0x8
2999 #define ARCH_SAMBA 0x10
3001 #define ARCH_ALL 0x1F
3003 /* List of supported protocols, most desired first */
3007 int (*proto_reply_fn)(char *);
3009 } supported_protocols[] = {
3010 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3011 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3012 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3013 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3014 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3015 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3016 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3017 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3018 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3023 /****************************************************************************
3025 ****************************************************************************/
3026 static int reply_negprot(char *inbuf,char *outbuf)
3028 extern fstring remote_arch;
3029 int outsize = set_message(outbuf,1,0,True);
3034 int bcc = SVAL(smb_buf(inbuf),-2);
3035 int arch = ARCH_ALL;
3037 p = smb_buf(inbuf)+1;
3038 while (p < (smb_buf(inbuf) + bcc))
3041 DEBUG(3,("Requested protocol [%s]\n",p));
3042 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3043 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3044 else if (strcsequal(p,"DOS LM1.2X002"))
3045 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3046 else if (strcsequal(p,"DOS LANMAN2.1"))
3047 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3048 else if (strcsequal(p,"NT LM 0.12"))
3049 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3050 else if (strcsequal(p,"LANMAN2.1"))
3051 arch &= ( ARCH_WINNT | ARCH_OS2 );
3052 else if (strcsequal(p,"LM1.2X002"))
3053 arch &= ( ARCH_WINNT | ARCH_OS2 );
3054 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3056 else if (strcsequal(p,"XENIX CORE"))
3057 arch &= ( ARCH_WINNT | ARCH_OS2 );
3058 else if (strcsequal(p,"Samba")) {
3068 strcpy(remote_arch,"Samba");
3071 strcpy(remote_arch,"WfWg");
3074 strcpy(remote_arch,"Win95");
3077 strcpy(remote_arch,"WinNT");
3080 strcpy(remote_arch,"OS2");
3083 strcpy(remote_arch,"UNKNOWN");
3087 /* possibly reload - change of architecture */
3088 reload_services(True);
3090 /* a special case to stop password server loops */
3091 if (Index == 1 && strequal(remote_machine,myhostname) &&
3092 lp_security()==SEC_SERVER)
3093 exit_server("Password server loop!");
3095 /* Check for protocols, most desirable first */
3096 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3098 p = smb_buf(inbuf)+1;
3100 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3101 while (p < (smb_buf(inbuf) + bcc))
3103 if (strequal(p,supported_protocols[protocol].proto_name))
3112 SSVAL(outbuf,smb_vwv0,choice);
3114 extern fstring remote_proto;
3115 strcpy(remote_proto,supported_protocols[protocol].short_name);
3116 reload_services(True);
3117 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3118 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3121 DEBUG(0,("No protocol supported !\n"));
3123 SSVAL(outbuf,smb_vwv0,choice);
3125 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3131 /****************************************************************************
3132 close all open files for a connection
3133 ****************************************************************************/
3134 static void close_open_files(int cnum)
3137 for (i=0;i<MAX_OPEN_FILES;i++)
3138 if( Files[i].cnum == cnum && Files[i].open) {
3145 /****************************************************************************
3147 ****************************************************************************/
3148 void close_cnum(int cnum, uint16 vuid)
3150 DirCacheFlush(SNUM(cnum));
3154 if (!OPEN_CNUM(cnum))
3156 DEBUG(0,("Can't close cnum %d\n",cnum));
3160 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3162 remote_machine,client_addr(),
3163 lp_servicename(SNUM(cnum))));
3165 yield_connection(cnum,
3166 lp_servicename(SNUM(cnum)),
3167 lp_max_connections(SNUM(cnum)));
3169 if (lp_status(SNUM(cnum)))
3170 yield_connection(cnum,"STATUS.",MAXSTATUS);
3172 close_open_files(cnum);
3173 dptr_closecnum(cnum);
3175 /* execute any "postexec = " line */
3176 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3179 strcpy(cmd,lp_postexec(SNUM(cnum)));
3180 standard_sub(cnum,cmd);
3181 smbrun(cmd,NULL,False);
3186 /* execute any "root postexec = " line */
3187 if (*lp_rootpostexec(SNUM(cnum)))
3190 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3191 standard_sub(cnum,cmd);
3192 smbrun(cmd,NULL,False);
3195 Connections[cnum].open = False;
3196 num_connections_open--;
3197 if (Connections[cnum].ngroups && Connections[cnum].groups)
3199 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3200 free(Connections[cnum].groups);
3201 free(Connections[cnum].igroups);
3202 Connections[cnum].groups = NULL;
3203 Connections[cnum].igroups = NULL;
3204 Connections[cnum].ngroups = 0;
3207 free_namearray(Connections[cnum].veto_list);
3208 free_namearray(Connections[cnum].hide_list);
3210 string_set(&Connections[cnum].user,"");
3211 string_set(&Connections[cnum].dirpath,"");
3212 string_set(&Connections[cnum].connectpath,"");
3216 /****************************************************************************
3217 simple routines to do connection counting
3218 ****************************************************************************/
3219 BOOL yield_connection(int cnum,char *name,int max_connections)
3221 struct connect_record crec;
3224 int mypid = getpid();
3227 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3229 if (max_connections <= 0)
3232 bzero(&crec,sizeof(crec));
3234 strcpy(fname,lp_lockdir());
3235 standard_sub(cnum,fname);
3236 trim_string(fname,"","/");
3240 strcat(fname,".LCK");
3242 f = fopen(fname,"r+");
3245 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3249 fseek(f,0,SEEK_SET);
3251 /* find a free spot */
3252 for (i=0;i<max_connections;i++)
3254 if (fread(&crec,sizeof(crec),1,f) != 1)
3256 DEBUG(2,("Entry not found in lock file %s\n",fname));
3260 if (crec.pid == mypid && crec.cnum == cnum)
3264 if (crec.pid != mypid || crec.cnum != cnum)
3267 DEBUG(2,("Entry not found in lock file %s\n",fname));
3271 bzero((void *)&crec,sizeof(crec));
3273 /* remove our mark */
3274 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3275 fwrite(&crec,sizeof(crec),1,f) != 1)
3277 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3282 DEBUG(3,("Yield successful\n"));
3289 /****************************************************************************
3290 simple routines to do connection counting
3291 ****************************************************************************/
3292 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3294 struct connect_record crec;
3297 int snum = SNUM(cnum);
3301 if (max_connections <= 0)
3304 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3306 strcpy(fname,lp_lockdir());
3307 standard_sub(cnum,fname);
3308 trim_string(fname,"","/");
3310 if (!directory_exist(fname,NULL))
3315 strcat(fname,".LCK");
3317 if (!file_exist(fname,NULL))
3319 int oldmask = umask(022);
3320 f = fopen(fname,"w");
3325 total_recs = file_size(fname) / sizeof(crec);
3327 f = fopen(fname,"r+");
3331 DEBUG(1,("couldn't open lock file %s\n",fname));
3335 /* find a free spot */
3336 for (i=0;i<max_connections;i++)
3339 if (i>=total_recs ||
3340 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3341 fread(&crec,sizeof(crec),1,f) != 1)
3343 if (foundi < 0) foundi = i;
3347 if (Clear && crec.pid && !process_exists(crec.pid))
3349 fseek(f,i*sizeof(crec),SEEK_SET);
3350 bzero((void *)&crec,sizeof(crec));
3351 fwrite(&crec,sizeof(crec),1,f);
3352 if (foundi < 0) foundi = i;
3355 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3364 DEBUG(3,("no free locks in %s\n",fname));
3369 /* fill in the crec */
3370 bzero((void *)&crec,sizeof(crec));
3371 crec.magic = 0x280267;
3372 crec.pid = getpid();
3374 crec.uid = Connections[cnum].uid;
3375 crec.gid = Connections[cnum].gid;
3376 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3377 crec.start = time(NULL);
3379 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3380 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3383 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3384 fwrite(&crec,sizeof(crec),1,f) != 1)
3395 /*******************************************************************
3396 prepare to dump a core file - carefully!
3397 ********************************************************************/
3398 static BOOL dump_core(void)
3402 strcpy(dname,debugf);
3403 if ((p=strrchr(dname,'/'))) *p=0;
3404 strcat(dname,"/corefiles");
3406 sys_chown(dname,getuid(),getgid());
3408 if (chdir(dname)) return(False);
3411 #ifndef NO_GETRLIMIT
3415 getrlimit(RLIMIT_CORE, &rlp);
3416 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3417 setrlimit(RLIMIT_CORE, &rlp);
3418 getrlimit(RLIMIT_CORE, &rlp);
3419 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3425 DEBUG(0,("Dumping core in %s\n",dname));
3430 /****************************************************************************
3432 ****************************************************************************/
3433 void exit_server(char *reason)
3435 static int firsttime=1;
3438 if (!firsttime) exit(0);
3442 DEBUG(2,("Closing connections\n"));
3443 for (i=0;i<MAX_CONNECTIONS;i++)
3444 if (Connections[i].open)
3445 close_cnum(i,(uint16)-1);
3447 if (dcelogin_atmost_once)
3451 int oldlevel = DEBUGLEVEL;
3453 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3455 show_msg(last_inbuf);
3456 DEBUGLEVEL = oldlevel;
3457 DEBUG(0,("===============================================================\n"));
3459 if (dump_core()) return;
3463 #ifdef FAST_SHARE_MODES
3464 stop_share_mode_mgmt();
3465 #endif /* FAST_SHARE_MODES */
3467 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3471 /****************************************************************************
3472 do some standard substitutions in a string
3473 ****************************************************************************/
3474 void standard_sub(int cnum,char *string)
3476 if (VALID_CNUM(cnum)) {
3479 for ( s=string ; (p=strchr(s, '%')) != NULL ; s=p ) {
3481 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
3482 string_sub(p,"%H",home);
3486 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
3487 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
3488 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
3489 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
3490 case '\0' : p++; break; /* don't run off the end of the string */
3491 default : p+=2; break;
3495 standard_sub_basic(string);
3499 These flags determine some of the permissions required to do an operation
3501 Note that I don't set NEED_WRITE on some write operations because they
3502 are used by some brain-dead clients when printing, and I don't want to
3503 force write permissions on print services.
3505 #define AS_USER (1<<0)
3506 #define NEED_WRITE (1<<1)
3507 #define TIME_INIT (1<<2)
3508 #define CAN_IPC (1<<3)
3509 #define AS_GUEST (1<<5)
3513 define a list of possible SMB messages and their corresponding
3514 functions. Any message that has a NULL function is unimplemented -
3515 please feel free to contribute implementations!
3517 struct smb_message_struct
3531 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3532 {SMBtcon,"SMBtcon",reply_tcon,0},
3533 {SMBtdis,"SMBtdis",reply_tdis,0},
3534 {SMBexit,"SMBexit",reply_exit,0},
3535 {SMBioctl,"SMBioctl",reply_ioctl,0},
3536 {SMBecho,"SMBecho",reply_echo,0},
3537 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3538 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3539 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3540 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3541 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3542 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3543 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3544 {SMBopen,"SMBopen",reply_open,AS_USER},
3546 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3547 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3548 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3550 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3551 {SMBread,"SMBread",reply_read,AS_USER},
3552 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3553 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3554 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3555 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3556 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3557 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3559 /* this is a Pathworks specific call, allowing the
3560 changing of the root path */
3561 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3563 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3564 {SMBflush,"SMBflush",reply_flush,AS_USER},
3565 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3566 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3567 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3568 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3569 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3570 {SMBlock,"SMBlock",reply_lock,AS_USER},
3571 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3573 /* CORE+ PROTOCOL FOLLOWS */
3575 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3576 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3577 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3578 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3579 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3581 /* LANMAN1.0 PROTOCOL FOLLOWS */
3583 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3584 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3585 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3586 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3587 {SMBwritec,"SMBwritec",NULL,AS_USER},
3588 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3589 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3590 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3591 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3592 {SMBioctls,"SMBioctls",NULL,AS_USER},
3593 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3594 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3596 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3597 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3598 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3599 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3601 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3602 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3603 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3605 /* LANMAN2.0 PROTOCOL FOLLOWS */
3606 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3607 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3608 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3609 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3611 /* messaging routines */
3612 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3613 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3614 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3615 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3617 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3619 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3620 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3621 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3622 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3625 /****************************************************************************
3626 return a string containing the function name of a SMB command
3627 ****************************************************************************/
3628 char *smb_fn_name(int type)
3630 static char *unknown_name = "SMBunknown";
3631 static int num_smb_messages =
3632 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3635 for (match=0;match<num_smb_messages;match++)
3636 if (smb_messages[match].code == type)
3639 if (match == num_smb_messages)
3640 return(unknown_name);
3642 return(smb_messages[match].name);
3646 /****************************************************************************
3647 do a switch on the message type, and return the response size
3648 ****************************************************************************/
3649 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3653 static int num_smb_messages =
3654 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3658 struct timeval msg_start_time;
3659 struct timeval msg_end_time;
3660 static unsigned long total_time = 0;
3662 GetTimeOfDay(&msg_start_time);
3669 last_message = type;
3671 /* make sure this is an SMB packet */
3672 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3674 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3678 for (match=0;match<num_smb_messages;match++)
3679 if (smb_messages[match].code == type)
3682 if (match == num_smb_messages)
3684 DEBUG(0,("Unknown message type %d!\n",type));
3685 outsize = reply_unknown(inbuf,outbuf);
3689 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3690 if (smb_messages[match].fn)
3692 int cnum = SVAL(inbuf,smb_tid);
3693 int flags = smb_messages[match].flags;
3694 uint16 session_tag = SVAL(inbuf,smb_uid);
3696 /* does this protocol need to be run as root? */
3697 if (!(flags & AS_USER))
3700 /* does this protocol need to be run as the connected user? */
3701 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3702 if (flags & AS_GUEST)
3705 return(ERROR(ERRSRV,ERRinvnid));
3707 /* this code is to work around a bug is MS client 3 without
3708 introducing a security hole - it needs to be able to do
3709 print queue checks as guest if it isn't logged in properly */
3710 if (flags & AS_USER)
3713 /* does it need write permission? */
3714 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3715 return(ERROR(ERRSRV,ERRaccess));
3717 /* ipc services are limited */
3718 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3719 return(ERROR(ERRSRV,ERRaccess));
3721 /* load service specific parameters */
3722 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3723 return(ERROR(ERRSRV,ERRaccess));
3725 /* does this protocol need to be run as guest? */
3726 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3727 return(ERROR(ERRSRV,ERRaccess));
3731 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3735 outsize = reply_unknown(inbuf,outbuf);
3740 GetTimeOfDay(&msg_end_time);
3741 if (!(smb_messages[match].flags & TIME_INIT))
3743 smb_messages[match].time = 0;
3744 smb_messages[match].flags |= TIME_INIT;
3747 unsigned long this_time =
3748 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3749 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3750 smb_messages[match].time += this_time;
3751 total_time += this_time;
3753 DEBUG(2,("TIME %s %d usecs %g pct\n",
3754 smb_fn_name(type),smb_messages[match].time,
3755 (100.0*smb_messages[match].time) / total_time));
3762 /****************************************************************************
3763 construct a chained reply and add it to the already made reply
3764 **************************************************************************/
3765 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3767 static char *orig_inbuf;
3768 static char *orig_outbuf;
3769 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3770 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3771 char *inbuf2, *outbuf2;
3773 char inbuf_saved[smb_wct];
3774 char outbuf_saved[smb_wct];
3775 extern int chain_size;
3776 int wct = CVAL(outbuf,smb_wct);
3777 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3779 /* maybe its not chained */
3780 if (smb_com2 == 0xFF) {
3781 CVAL(outbuf,smb_vwv0) = 0xFF;
3785 if (chain_size == 0) {
3786 /* this is the first part of the chain */
3788 orig_outbuf = outbuf;
3791 /* we need to tell the client where the next part of the reply will be */
3792 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3793 CVAL(outbuf,smb_vwv0) = smb_com2;
3795 /* remember how much the caller added to the chain, only counting stuff
3796 after the parameter words */
3797 chain_size += outsize - smb_wct;
3799 /* work out pointers into the original packets. The
3800 headers on these need to be filled in */
3801 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3802 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3804 /* remember the original command type */
3805 smb_com1 = CVAL(orig_inbuf,smb_com);
3807 /* save the data which will be overwritten by the new headers */
3808 memcpy(inbuf_saved,inbuf2,smb_wct);
3809 memcpy(outbuf_saved,outbuf2,smb_wct);
3811 /* give the new packet the same header as the last part of the SMB */
3812 memmove(inbuf2,inbuf,smb_wct);
3814 /* create the in buffer */
3815 CVAL(inbuf2,smb_com) = smb_com2;
3817 /* create the out buffer */
3818 bzero(outbuf2,smb_size);
3819 set_message(outbuf2,0,0,True);
3820 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3822 memcpy(outbuf2+4,inbuf2+4,4);
3823 CVAL(outbuf2,smb_rcls) = SUCCESS;
3824 CVAL(outbuf2,smb_reh) = 0;
3825 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3827 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3828 SSVAL(outbuf2,smb_err,SUCCESS);
3829 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3830 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3831 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3832 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3834 DEBUG(3,("Chained message\n"));
3837 /* process the request */
3838 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3839 bufsize-chain_size);
3841 /* copy the new reply and request headers over the old ones, but
3842 preserve the smb_com field */
3843 memmove(orig_outbuf,outbuf2,smb_wct);
3844 CVAL(orig_outbuf,smb_com) = smb_com1;
3846 /* restore the saved data, being careful not to overwrite any
3847 data from the reply header */
3848 memcpy(inbuf2,inbuf_saved,smb_wct);
3850 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3851 if (ofs < 0) ofs = 0;
3852 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3860 /****************************************************************************
3861 construct a reply to the incoming packet
3862 ****************************************************************************/
3863 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3865 int type = CVAL(inbuf,smb_com);
3867 int msg_type = CVAL(inbuf,0);
3868 extern int chain_size;
3870 smb_last_time = time(NULL);
3875 bzero(outbuf,smb_size);
3878 return(reply_special(inbuf,outbuf));
3880 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3881 set_message(outbuf,0,0,True);
3883 memcpy(outbuf+4,inbuf+4,4);
3884 CVAL(outbuf,smb_rcls) = SUCCESS;
3885 CVAL(outbuf,smb_reh) = 0;
3886 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3888 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3889 SSVAL(outbuf,smb_err,SUCCESS);
3890 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3891 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3892 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3893 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3895 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3897 outsize += chain_size;
3900 smb_setlen(outbuf,outsize - 4);
3905 /****************************************************************************
3906 process commands from the client
3907 ****************************************************************************/
3908 static void process(void)
3910 static int trans_num = 0;
3914 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3915 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3916 if ((InBuffer == NULL) || (OutBuffer == NULL))
3919 InBuffer += SMB_ALIGNMENT;
3920 OutBuffer += SMB_ALIGNMENT;
3923 DEBUG(3,("priming nmbd\n"));
3926 ip = *interpret_addr2("localhost");
3927 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3929 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3939 int deadtime = lp_deadtime()*60;
3941 int last_keepalive=0;
3942 int service_load_counter = 0;
3945 deadtime = DEFAULT_SMBD_TIMEOUT;
3947 if (lp_readprediction())
3948 do_read_prediction();
3952 for (counter=SMBD_SELECT_LOOP;
3953 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3954 counter += SMBD_SELECT_LOOP)
3958 BOOL allidle = True;
3959 extern int keepalive;
3961 if (counter > 365 * 3600) /* big number of seconds. */
3964 service_load_counter = 0;
3967 if (smb_read_error == READ_EOF) {
3968 DEBUG(3,("end of file from client\n"));
3972 if (smb_read_error == READ_ERROR) {
3973 DEBUG(3,("receive_smb error (%s) exiting\n",
3980 /* become root again if waiting */
3983 /* check for smb.conf reload */
3984 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
3986 service_load_counter = counter;
3988 /* reload services, if files have changed. */
3989 reload_services(True);
3992 /* automatic timeout if all connections are closed */
3993 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3994 DEBUG(2,("%s Closing idle connection\n",timestring()));
3998 if (keepalive && (counter-last_keepalive)>keepalive) {
3999 extern int password_client;
4000 if (!send_keepalive(Client)) {
4001 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4004 /* also send a keepalive to the password server if its still
4006 if (password_client != -1)
4007 send_keepalive(password_client);
4008 last_keepalive = counter;
4011 /* check for connection timeouts */
4012 for (i=0;i<MAX_CONNECTIONS;i++)
4013 if (Connections[i].open)
4015 /* close dirptrs on connections that are idle */
4016 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4019 if (Connections[i].num_files_open > 0 ||
4020 (t-Connections[i].lastused)<deadtime)
4024 if (allidle && num_connections_open>0) {
4025 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4030 msg_type = CVAL(InBuffer,0);
4031 msg_flags = CVAL(InBuffer,1);
4032 type = CVAL(InBuffer,smb_com);
4034 len = smb_len(InBuffer);
4036 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
4040 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
4043 if(trans_num == 1 && VT_Check(InBuffer)) {
4053 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
4056 if (CVAL(OutBuffer,0) == 0)
4057 show_msg(OutBuffer);
4059 if (nread != smb_len(OutBuffer) + 4)
4061 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
4063 smb_len(OutBuffer)));
4066 send_smb(Client,OutBuffer);
4073 /****************************************************************************
4074 initialise connect, service and file structs
4075 ****************************************************************************/
4076 static void init_structs(void )
4079 get_myname(myhostname,NULL);
4081 for (i=0;i<MAX_CONNECTIONS;i++)
4083 Connections[i].open = False;
4084 Connections[i].num_files_open=0;
4085 Connections[i].lastused=0;
4086 Connections[i].used=False;
4087 string_init(&Connections[i].user,"");
4088 string_init(&Connections[i].dirpath,"");
4089 string_init(&Connections[i].connectpath,"");
4090 string_init(&Connections[i].origpath,"");
4093 for (i=0;i<MAX_OPEN_FILES;i++)
4095 Files[i].open = False;
4096 string_init(&Files[i].name,"");
4100 for (i=0;i<MAX_OPEN_FILES;i++)
4102 file_fd_struct *fd_ptr = &FileFd[i];
4103 fd_ptr->ref_count = 0;
4104 fd_ptr->dev = (int32)-1;
4105 fd_ptr->inode = (int32)-1;
4107 fd_ptr->fd_readonly = -1;
4108 fd_ptr->fd_writeonly = -1;
4109 fd_ptr->real_open_flags = -1;
4115 /****************************************************************************
4116 usage on the program
4117 ****************************************************************************/
4118 static void usage(char *pname)
4120 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4122 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4123 printf("Version %s\n",VERSION);
4124 printf("\t-D become a daemon\n");
4125 printf("\t-p port listen on the specified port\n");
4126 printf("\t-d debuglevel set the debuglevel\n");
4127 printf("\t-l log basename. Basename for log/debug files\n");
4128 printf("\t-s services file. Filename of services file\n");
4129 printf("\t-P passive only\n");
4130 printf("\t-a overwrite log file, don't append\n");
4135 /****************************************************************************
4137 ****************************************************************************/
4138 int main(int argc,char *argv[])
4140 extern BOOL append_log;
4141 /* shall I run as a daemon */
4142 BOOL is_daemon = False;
4143 int port = SMB_PORT;
4145 extern char *optarg;
4146 char pidFile[100] = { 0 };
4148 #ifdef NEED_AUTH_PARAMETERS
4149 set_auth_parameters(argc,argv);
4160 strcpy(debugf,SMBLOGFILE);
4162 setup_logging(argv[0],False);
4164 charset_initialise();
4166 /* make absolutely sure we run as root - to handle cases whre people
4167 are crazy enough to have it setuid */
4177 fault_setup(exit_server);
4178 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4180 /* we want total control over the permissions on created files,
4181 so set our umask to 0 */
4188 /* this is for people who can't start the program correctly */
4189 while (argc > 1 && (*argv[1] != '-'))
4195 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4199 strncpy(pidFile, optarg, sizeof(pidFile));
4202 strcpy(user_socket_options,optarg);
4205 strcpy(scope,optarg);
4209 extern BOOL passive;
4214 strcpy(servicesf,optarg);
4217 strcpy(debugf,optarg);
4221 extern BOOL append_log;
4222 append_log = !append_log;
4232 DEBUGLEVEL = atoi(optarg);
4235 port = atoi(optarg);
4248 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4249 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4251 #ifndef NO_GETRLIMIT
4252 #ifdef RLIMIT_NOFILE
4255 getrlimit(RLIMIT_NOFILE, &rlp);
4256 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4257 setrlimit(RLIMIT_NOFILE, &rlp);
4258 getrlimit(RLIMIT_NOFILE, &rlp);
4259 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4265 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4266 getuid(),getgid(),geteuid(),getegid()));
4268 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4270 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4276 if (!reload_services(False))
4279 codepage_initialise(lp_client_code_page());
4281 strcpy(myworkgroup, lp_workgroup());
4283 #ifndef NO_SIGNAL_TEST
4284 signal(SIGHUP,SIGNAL_CAST sig_hup);
4287 DEBUG(3,("%s loaded services\n",timestring()));
4289 if (!is_daemon && !is_a_socket(0))
4291 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4297 DEBUG(3,("%s becoming a daemon\n",timestring()));
4306 if ((fd = open(pidFile,
4310 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4312 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4315 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4317 DEBUG(0,("ERROR: smbd is already running\n"));
4320 sprintf(buf, "%u\n", (unsigned int) getpid());
4321 if (write(fd, buf, strlen(buf)) < 0)
4323 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4326 /* Leave pid file open & locked for the duration... */
4329 if (!open_sockets(is_daemon,port))
4332 #ifdef FAST_SHARE_MODES
4333 if (!start_share_mode_mgmt())
4335 #endif /* FAST_SHARE_MODES */
4337 /* possibly reload the services file. */
4338 reload_services(True);
4340 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4344 if (sys_chroot(lp_rootdir()) == 0)
4345 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4351 exit_server("normal exit");