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
429 ****************************************************************************/
430 BOOL unix_convert(char *name,int cnum,pstring saved_last_component)
437 if(saved_last_component)
438 *saved_last_component = 0;
440 /* convert to basic unix format - removing \ chars and cleaning it up */
442 unix_clean_name(name);
444 /* names must be relative to the root of the service - trim any leading /.
445 also trim trailing /'s */
446 trim_string(name,"/","/");
449 * Ensure saved_last_component is valid even if file exists.
451 if(saved_last_component) {
452 end = strrchr(name, '/');
454 strcpy(saved_last_component, end + 1);
456 strcpy(saved_last_component, name);
459 if (!case_sensitive &&
460 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
463 /* check if it's a printer file */
464 if (Connections[cnum].printer)
466 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
470 sprintf(name2,"%.6s.XXXXXX",remote_machine);
471 /* sanitise the name */
472 for (s=name2 ; *s ; s++)
473 if (!issafe(*s)) *s = '_';
474 strcpy(name,(char *)mktemp(name2));
479 /* stat the name - if it exists then we are all done! */
480 if (sys_stat(name,&st) == 0)
483 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
485 /* a special case - if we don't have any mangling chars and are case
486 sensitive then searching won't help */
487 if (case_sensitive && !is_mangled(name) &&
488 !lp_strip_dot() && !use_mangled_map)
491 /* now we need to recursively match the name against the real
492 directory structure */
495 while (strncmp(start,"./",2) == 0)
498 /* now match each part of the path name separately, trying the names
499 as is first, then trying to scan the directory for matching names */
500 for (;start;start = (end?end+1:(char *)NULL))
502 /* pinpoint the end of this section of the filename */
503 end = strchr(start, '/');
505 /* chop the name at this point */
508 if(saved_last_component != 0)
509 strcpy(saved_last_component, end ? end + 1 : start);
511 /* check if the name exists up to this point */
512 if (sys_stat(name, &st) == 0)
514 /* it exists. it must either be a directory or this must be
515 the last part of the path for it to be OK */
516 if (end && !(st.st_mode & S_IFDIR))
518 /* an intermediate part of the name isn't a directory */
519 DEBUG(5,("Not a dir %s\n",start));
530 /* remember the rest of the pathname so it can be restored
532 if (end) strcpy(rest,end+1);
534 /* try to find this part of the path in the directory */
535 if (strchr(start,'?') || strchr(start,'*') ||
536 !scan_directory(dirpath, start, cnum, end?True:False))
540 /* an intermediate part of the name can't be found */
541 DEBUG(5,("Intermediate not found %s\n",start));
546 /* just the last part of the name doesn't exist */
547 /* we may need to strupper() or strlower() it in case
548 this conversion is being used for file creation
550 /* if the filename is of mixed case then don't normalise it */
551 if (!case_preserve &&
552 (!strhasupper(start) || !strhaslower(start)))
555 /* check on the mangled stack to see if we can recover the
556 base of the filename */
557 if (is_mangled(start))
558 check_mangled_stack(start);
560 DEBUG(5,("New file %s\n",start));
564 /* restore the rest of the string */
567 strcpy(start+strlen(start)+1,rest);
568 end = start + strlen(start);
572 /* add to the dirpath that we have resolved so far */
573 if (*dirpath) strcat(dirpath,"/");
574 strcat(dirpath,start);
576 /* restore the / that we wiped out earlier */
580 /* the name has been resolved */
581 DEBUG(5,("conversion finished %s\n",name));
586 /****************************************************************************
587 normalise for DOS usage
588 ****************************************************************************/
589 static void disk_norm(int *bsize,int *dfree,int *dsize)
591 /* check if the disk is beyond the max disk size */
592 int maxdisksize = lp_maxdisksize();
594 /* convert to blocks - and don't overflow */
595 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
596 if (*dsize > maxdisksize) *dsize = maxdisksize;
597 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
602 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
607 if (*bsize > WORDMAX )
610 if (*dsize > WORDMAX)
612 if (*dfree > WORDMAX)
619 /****************************************************************************
620 return number of 1K blocks available on a path and total number
621 ****************************************************************************/
622 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
624 char *df_command = lp_dfree_command();
645 /* possibly use system() to get the result */
646 if (df_command && *df_command)
652 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
653 sprintf(syscmd,"%s %s",df_command,path);
654 standard_sub_basic(syscmd);
656 ret = smbrun(syscmd,outfile,False);
657 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
660 FILE *f = fopen(outfile,"r");
666 fscanf(f,"%d %d %d",dsize,dfree,bsize);
670 DEBUG(0,("Can't open %s\n",outfile));
674 disk_norm(bsize,dfree,dsize);
675 dfree_retval = ((*bsize)/1024)*(*dfree);
677 /* Ensure we return the min value between the users quota and
678 what's free on the disk. Thanks to Albrecht Gebhardt
679 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
681 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
683 disk_norm(&bsizeq, &dfreeq, &dsizeq);
684 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
685 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
686 dfree_retval : dfreeq_retval ;
687 /* maybe dfree and dfreeq are calculated using different bsizes
688 so convert dfree from bsize into bsizeq */
689 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
690 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
695 return(dfree_retval);
699 DEBUG(1,("Warning - no statfs function\n"));
703 if (statfs(path,&fs,sizeof(fs),0) != 0)
706 if (statvfs(path, &fs))
709 if (statfs(path,&fs,sizeof(fs)) == -1)
711 if (statfs(path,&fs) == -1)
713 #endif /* USE_STATVFS */
716 DEBUG(3,("dfree call failed code errno=%d\n",errno));
720 return(((*bsize)/1024)*(*dfree));
725 *dfree = fs.fd_req.bfree;
726 *dsize = fs.fd_req.btot;
729 *bsize = fs.f_frsize;
732 /* eg: osf1 has f_fsize = fundamental filesystem block size,
733 f_bsize = optimal transfer block size (MX: 94-04-19) */
738 #endif /* USE_STATVFS */
743 *dfree = fs.f_bavail;
745 *dsize = fs.f_blocks;
748 #if defined(SCO) || defined(ISC) || defined(MIPS)
752 /* handle rediculous bsize values - some OSes are broken */
753 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
755 disk_norm(bsize,dfree,dsize);
761 DEBUG(0,("dfree seems to be broken on your system\n"));
762 *dsize = 20*1024*1024/(*bsize);
763 *dfree = MAX(1,*dfree);
765 dfree_retval = ((*bsize)/1024)*(*dfree);
767 /* Ensure we return the min value between the users quota and
768 what's free on the disk. Thanks to Albrecht Gebhardt
769 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
771 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
773 disk_norm(&bsizeq, &dfreeq, &dsizeq);
774 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
775 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
776 dfree_retval : dfreeq_retval ;
777 /* maybe dfree and dfreeq are calculated using different bsizes
778 so convert dfree from bsize into bsizeq */
779 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
780 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
785 return(dfree_retval);
790 /****************************************************************************
791 wrap it to get filenames right
792 ****************************************************************************/
793 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
795 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
800 /****************************************************************************
801 check a filename - possibly caling reducename
803 This is called by every routine before it allows an operation on a filename.
804 It does any final confirmation necessary to ensure that the filename is
805 a valid one for the user to access.
806 ****************************************************************************/
807 BOOL check_name(char *name,int cnum)
813 if( IS_VETO_PATH(cnum, name))
815 DEBUG(5,("file path name %s vetoed\n",name));
819 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
821 /* Check if we are allowing users to follow symlinks */
822 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
823 University of Geneva */
825 if (!lp_symlinks(SNUM(cnum)))
828 if ( (sys_lstat(name,&statbuf) != -1) &&
829 (S_ISLNK(statbuf.st_mode)) )
831 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
837 DEBUG(5,("check_name on %s failed\n",name));
842 /****************************************************************************
843 check a filename - possibly caling reducename
844 ****************************************************************************/
845 static void check_for_pipe(char *fname)
847 /* special case of pipe opens */
851 if (strstr(s,"pipe/"))
853 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
854 unix_ERR_class = ERRSRV;
855 unix_ERR_code = ERRaccess;
859 /****************************************************************************
860 fd support routines - attempt to do a sys_open
861 ****************************************************************************/
863 int fd_attempt_open(char *fname, int flags, int mode)
865 int fd = sys_open(fname,flags,mode);
867 /* Fix for files ending in '.' */
868 if((fd == -1) && (errno == ENOENT) &&
869 (strchr(fname,'.')==NULL))
872 fd = sys_open(fname,flags,mode);
875 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
876 if ((fd == -1) && (errno == ENAMETOOLONG))
879 char *p = strrchr(fname, '/');
881 if (p == fname) /* name is "/xxx" */
883 max_len = pathconf("/", _PC_NAME_MAX);
886 else if ((p == NULL) || (p == fname))
889 max_len = pathconf(".", _PC_NAME_MAX);
894 max_len = pathconf(fname, _PC_NAME_MAX);
898 if (strlen(p) > max_len)
900 char tmp = p[max_len];
903 if ((fd = sys_open(fname,flags,mode)) == -1)
911 /****************************************************************************
912 fd support routines - attempt to find an already open file by dev
913 and inode - increments the ref_count of the returned file_fd_struct *.
914 ****************************************************************************/
915 file_fd_struct *fd_get_already_open(struct stat *sbuf)
918 file_fd_struct *fd_ptr;
923 for(i = 0; i <= max_file_fd_used; i++) {
925 if((fd_ptr->ref_count > 0) &&
926 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
927 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
930 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
931 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
938 /****************************************************************************
939 fd support routines - attempt to find a empty slot in the FileFd array.
940 Increments the ref_count of the returned entry.
941 ****************************************************************************/
942 file_fd_struct *fd_get_new()
945 file_fd_struct *fd_ptr;
947 for(i = 0; i < MAX_OPEN_FILES; i++) {
949 if(fd_ptr->ref_count == 0) {
950 fd_ptr->dev = (uint32)-1;
951 fd_ptr->inode = (uint32)-1;
953 fd_ptr->fd_readonly = -1;
954 fd_ptr->fd_writeonly = -1;
955 fd_ptr->real_open_flags = -1;
957 /* Increment max used counter if neccessary, cuts down
958 on search time when re-using */
959 if(i > max_file_fd_used)
960 max_file_fd_used = i;
961 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
962 i, fd_ptr->dev, fd_ptr->inode));
966 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
971 /****************************************************************************
972 fd support routines - attempt to re-open an already open fd as O_RDWR.
973 Save the already open fd (we cannot close due to POSIX file locking braindamage.
974 ****************************************************************************/
976 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
978 int fd = sys_open( fname, O_RDWR, mode);
983 if(fd_ptr->real_open_flags == O_RDONLY)
984 fd_ptr->fd_readonly = fd_ptr->fd;
985 if(fd_ptr->real_open_flags == O_WRONLY)
986 fd_ptr->fd_writeonly = fd_ptr->fd;
989 fd_ptr->real_open_flags = O_RDWR;
992 /****************************************************************************
993 fd support routines - attempt to close the file referenced by this fd.
994 Decrements the ref_count and returns it.
995 ****************************************************************************/
996 int fd_attempt_close(file_fd_struct *fd_ptr)
998 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1000 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1001 fd_ptr->real_open_flags,
1002 fd_ptr->ref_count));
1003 if(fd_ptr->ref_count > 0) {
1004 fd_ptr->ref_count--;
1005 if(fd_ptr->ref_count == 0) {
1006 if(fd_ptr->fd != -1)
1008 if(fd_ptr->fd_readonly != -1)
1009 close(fd_ptr->fd_readonly);
1010 if(fd_ptr->fd_writeonly != -1)
1011 close(fd_ptr->fd_writeonly);
1013 fd_ptr->fd_readonly = -1;
1014 fd_ptr->fd_writeonly = -1;
1015 fd_ptr->real_open_flags = -1;
1016 fd_ptr->dev = (uint32)-1;
1017 fd_ptr->inode = (uint32)-1;
1020 return fd_ptr->ref_count;
1023 /****************************************************************************
1025 ****************************************************************************/
1026 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1028 extern struct current_user current_user;
1030 struct stat statbuf;
1031 file_fd_struct *fd_ptr;
1033 Files[fnum].open = False;
1034 Files[fnum].fd_ptr = 0;
1037 strcpy(fname,fname1);
1039 /* check permissions */
1040 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1042 DEBUG(3,("Permission denied opening %s\n",fname));
1043 check_for_pipe(fname);
1047 /* this handles a bug in Win95 - it doesn't say to create the file when it
1049 if (Connections[cnum].printer)
1053 if (flags == O_WRONLY)
1054 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1057 #if UTIME_WORKAROUND
1058 /* XXXX - is this OK?? */
1059 /* this works around a utime bug but can cause other problems */
1060 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
1065 * Ensure we have a valid struct stat so we can search the
1069 if(stat(fname, &statbuf) < 0) {
1070 if(errno != ENOENT) {
1071 DEBUG(3,("Error doing stat on file %s (%s)\n",
1072 fname,strerror(errno)));
1074 check_for_pipe(fname);
1084 * Check to see if we have this file already
1085 * open. If we do, just use the already open fd and increment the
1086 * reference count (fd_get_already_open increments the ref_count).
1088 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1090 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1092 /* File was already open. */
1093 if((flags & O_CREAT) && (flags & O_EXCL)) {
1094 fd_ptr->ref_count--;
1100 * If not opened O_RDWR try
1101 * and do that here - a chmod may have been done
1102 * between the last open and now.
1104 if(fd_ptr->real_open_flags != O_RDWR)
1105 fd_attempt_reopen(fname, mode, fd_ptr);
1108 * Ensure that if we wanted write access
1109 * it has been opened for write, and if we wanted read it
1110 * was open for read.
1112 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1113 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1114 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1115 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1116 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1117 check_for_pipe(fname);
1118 fd_ptr->ref_count--;
1124 /* We need to allocate a new file_fd_struct (this increments the
1126 if((fd_ptr = fd_get_new()) == 0)
1129 * Whatever the requested flags, attempt read/write access,
1130 * as we don't know what flags future file opens may require.
1131 * If this fails, try again with the required flags.
1132 * Even if we open read/write when only read access was
1133 * requested the setting of the can_write flag in
1134 * the file_struct will protect us from errant
1135 * write requests. We never need to worry about O_APPEND
1136 * as this is not set anywhere in Samba.
1138 fd_ptr->real_open_flags = O_RDWR;
1139 /* Set the flags as needed without the read/write modes. */
1140 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1141 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1143 * On some systems opening a file for R/W access on a read only
1144 * filesystems sets errno to EROFS.
1147 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1148 #else /* No EROFS */
1149 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1151 if(flags & O_WRONLY) {
1152 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1153 fd_ptr->real_open_flags = O_WRONLY;
1155 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1156 fd_ptr->real_open_flags = O_RDONLY;
1161 if ((fd_ptr->fd >=0) &&
1162 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1166 strcpy(dname,fname);
1167 p = strrchr(dname,'/');
1169 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1170 lp_minprintspace(SNUM(cnum))) {
1171 fd_attempt_close(fd_ptr);
1172 Files[fnum].fd_ptr = 0;
1173 if(fd_ptr->ref_count == 0)
1182 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1183 fname,strerror(errno),flags));
1184 /* Ensure the ref_count is decremented. */
1185 fd_attempt_close(fd_ptr);
1186 check_for_pipe(fname);
1190 if (fd_ptr->fd >= 0)
1194 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1195 /* Error - backout !! */
1196 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1197 fd_ptr->fd, fname,strerror(errno)));
1198 /* Ensure the ref_count is decremented. */
1199 fd_attempt_close(fd_ptr);
1204 /* Set the correct entries in fd_ptr. */
1205 fd_ptr->dev = (uint32)sbuf->st_dev;
1206 fd_ptr->inode = (uint32)sbuf->st_ino;
1208 Files[fnum].fd_ptr = fd_ptr;
1209 Connections[cnum].num_files_open++;
1210 Files[fnum].mode = sbuf->st_mode;
1211 GetTimeOfDay(&Files[fnum].open_time);
1212 Files[fnum].uid = current_user.id;
1213 Files[fnum].size = 0;
1214 Files[fnum].pos = -1;
1215 Files[fnum].open = True;
1216 Files[fnum].mmap_ptr = NULL;
1217 Files[fnum].mmap_size = 0;
1218 Files[fnum].can_lock = True;
1219 Files[fnum].can_read = ((flags & O_WRONLY)==0);
1220 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1221 Files[fnum].share_mode = 0;
1222 Files[fnum].print_file = Connections[cnum].printer;
1223 Files[fnum].modified = False;
1224 Files[fnum].cnum = cnum;
1225 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1226 Files[fnum].wbmpx_ptr = NULL;
1229 * If the printer is marked as postscript output a leading
1230 * file identifier to ensure the file is treated as a raw
1232 * This has a similar effect as CtrlD=0 in WIN.INI file.
1233 * tim@fsg.com 09/06/94
1235 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1236 Files[fnum].can_write)
1238 DEBUG(3,("Writing postscript line\n"));
1239 write_file(fnum,"%!\n",3);
1242 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1243 timestring(),Connections[cnum].user,fname,
1244 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1245 Connections[cnum].num_files_open,fnum));
1250 /* mmap it if read-only */
1251 if (!Files[fnum].can_write)
1253 Files[fnum].mmap_size = file_size(fname);
1254 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1255 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1257 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1259 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1260 Files[fnum].mmap_ptr = NULL;
1266 /*******************************************************************
1268 ********************************************************************/
1269 void sync_file(int fnum)
1272 fsync(Files[fnum].fd_ptr->fd);
1276 /****************************************************************************
1277 run a file if it is a magic script
1278 ****************************************************************************/
1279 static void check_magic(int fnum,int cnum)
1281 if (!*lp_magicscript(SNUM(cnum)))
1284 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1288 if (!(p = strrchr(Files[fnum].name,'/')))
1289 p = Files[fnum].name;
1293 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1299 pstring magic_output;
1301 strcpy(fname,Files[fnum].name);
1303 if (*lp_magicoutput(SNUM(cnum)))
1304 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1306 sprintf(magic_output,"%s.out",fname);
1309 ret = smbrun(fname,magic_output,False);
1310 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1316 /****************************************************************************
1317 close a file - possibly invalidating the read prediction
1318 ****************************************************************************/
1319 void close_file(int fnum)
1321 files_struct *fs_p = &Files[fnum];
1322 int cnum = fs_p->cnum;
1323 uint32 dev = fs_p->fd_ptr->dev;
1324 uint32 inode = fs_p->fd_ptr->inode;
1325 share_lock_token token;
1327 invalidate_read_prediction(fs_p->fd_ptr->fd);
1329 Connections[cnum].num_files_open--;
1332 free((char *)fs_p->wbmpx_ptr);
1333 fs_p->wbmpx_ptr = NULL;
1339 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1340 fs_p->mmap_ptr = NULL;
1344 if (lp_share_modes(SNUM(cnum)))
1346 lock_share_entry( cnum, dev, inode, &token);
1347 del_share_mode(token, fnum);
1350 fd_attempt_close(fs_p->fd_ptr);
1352 if (lp_share_modes(SNUM(cnum)))
1353 unlock_share_entry( cnum, dev, inode, token);
1355 /* NT uses smbclose to start a print - weird */
1356 if (fs_p->print_file)
1359 /* check for magic scripts */
1360 check_magic(fnum,cnum);
1362 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1363 timestring(),Connections[cnum].user,fs_p->name,
1364 Connections[cnum].num_files_open));
1367 enum {AFAIL,AREAD,AWRITE,AALL};
1369 /*******************************************************************
1370 reproduce the share mode access table
1371 ********************************************************************/
1372 static int access_table(int new_deny,int old_deny,int old_mode,
1373 int share_pid,char *fname)
1375 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1377 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1378 if (old_deny == new_deny && share_pid == getpid())
1381 if (old_mode == 0) return(AREAD);
1383 /* the new smbpub.zip spec says that if the file extension is
1384 .com, .dll, .exe or .sym then allow the open. I will force
1385 it to read-only as this seems sensible although the spec is
1386 a little unclear on this. */
1387 if ((fname = strrchr(fname,'.'))) {
1388 if (strequal(fname,".com") ||
1389 strequal(fname,".dll") ||
1390 strequal(fname,".exe") ||
1391 strequal(fname,".sym"))
1401 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1402 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1403 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1406 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1407 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1408 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1411 if (old_deny==DENY_WRITE) return(AREAD);
1412 if (old_deny==DENY_READ) return(AWRITE);
1413 if (old_deny==DENY_NONE) return(AALL);
1419 /*******************************************************************
1420 check if the share mode on a file allows it to be deleted or unlinked
1421 return True if sharing doesn't prevent the operation
1422 ********************************************************************/
1423 BOOL check_file_sharing(int cnum,char *fname)
1427 min_share_mode_entry *old_shares = 0;
1428 int num_share_modes;
1430 share_lock_token token;
1433 if(!lp_share_modes(SNUM(cnum)))
1436 if (stat(fname,&sbuf) == -1) return(True);
1438 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1439 num_share_modes = get_share_modes(cnum, token,
1440 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1442 for( i = 0; i < num_share_modes; i++)
1444 if (old_shares[i].share_mode != DENY_DOS)
1447 if(old_shares[i].pid != pid)
1451 /* XXXX exactly what share mode combinations should be allowed for
1452 deleting/renaming? */
1453 /* If we got here then either there were no share modes or
1454 all share modes were DENY_DOS and the pid == getpid() */
1459 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1460 if(old_shares != NULL)
1461 free((char *)old_shares);
1465 /****************************************************************************
1467 Helper for open_file_shared.
1468 Truncate a file after checking locking; close file if locked.
1469 **************************************************************************/
1470 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1473 if (Files[fnum].can_write){
1474 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1475 /* If share modes are in force for this connection we
1476 have the share entry locked. Unlock it before closing. */
1477 if (*share_locked && lp_share_modes(SNUM(cnum)))
1478 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1479 Files[fnum].fd_ptr->inode, token);
1481 /* Share mode no longer locked. */
1482 *share_locked = False;
1484 unix_ERR_class = ERRDOS;
1485 unix_ERR_code = ERRlock;
1488 ftruncate(Files[fnum].fd_ptr->fd,0);
1493 /****************************************************************************
1494 open a file with a share mode
1495 ****************************************************************************/
1496 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1497 int mode,int *Access,int *action)
1499 files_struct *fs_p = &Files[fnum];
1502 int deny_mode = (share_mode>>4)&7;
1504 BOOL file_existed = file_exist(fname,&sbuf);
1505 BOOL share_locked = False;
1506 BOOL fcbopen = False;
1507 share_lock_token token;
1514 /* this is for OS/2 EAs - try and say we don't support them */
1515 if (strstr(fname,".+,;=[]."))
1517 unix_ERR_class = ERRDOS;
1518 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1522 if ((ofun & 0x3) == 0 && file_existed)
1530 if ((ofun & 0x3) == 2)
1533 /* note that we ignore the append flag as
1534 append does not mean the same thing under dos and unix */
1536 switch (share_mode&0xF)
1553 if (flags != O_RDONLY && file_existed &&
1554 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1564 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1566 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1571 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1573 if (lp_share_modes(SNUM(cnum)))
1577 min_share_mode_entry *old_shares = 0;
1582 dev = (uint32)sbuf.st_dev;
1583 inode = (uint32)sbuf.st_ino;
1584 lock_share_entry(cnum, dev, inode, &token);
1585 share_locked = True;
1586 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1589 for(i = 0; i < num_shares; i++)
1591 /* someone else has a share lock on it, check to see
1593 int old_open_mode = old_shares[i].share_mode &0xF;
1594 int old_deny_mode = (old_shares[i].share_mode >>4)&7;
1596 if (old_deny_mode > 4 || old_open_mode > 2)
1598 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1599 deny_mode,old_deny_mode,old_open_mode,fname));
1600 free((char *)old_shares);
1602 unlock_share_entry(cnum, dev, inode, token);
1604 unix_ERR_class = ERRDOS;
1605 unix_ERR_code = ERRbadshare;
1610 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1611 old_shares[i].pid,fname);
1613 if ((access_allowed == AFAIL) ||
1614 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1615 (access_allowed == AREAD && flags == O_WRONLY) ||
1616 (access_allowed == AWRITE && flags == O_RDONLY))
1618 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1619 deny_mode,old_deny_mode,old_open_mode,
1620 old_shares[i].pid,fname,
1622 free((char *)old_shares);
1624 unlock_share_entry(cnum, dev, inode, token);
1626 unix_ERR_class = ERRDOS;
1627 unix_ERR_code = ERRbadshare;
1631 if (access_allowed == AREAD)
1634 if (access_allowed == AWRITE)
1639 free((char *)old_shares);
1642 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1643 flags,flags2,mode));
1645 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1646 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1649 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1656 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1658 /* We created the file - thus we must now lock the share entry before creating it. */
1659 dev = fs_p->fd_ptr->dev;
1660 inode = fs_p->fd_ptr->inode;
1661 lock_share_entry(cnum, dev, inode, &token);
1662 share_locked = True;
1678 fs_p->share_mode = (deny_mode<<4) | open_mode;
1681 (*Access) = open_mode;
1685 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1686 if (!file_existed) *action = 2;
1687 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1689 /* We must create the share mode entry before truncate as
1690 truncate can fail due to locking and have to close the
1691 file (which expects the share_mode_entry to be there).
1693 if (lp_share_modes(SNUM(cnum)))
1694 set_share_mode(token, fnum);
1696 if ((flags2&O_TRUNC) && file_existed)
1697 truncate_unless_locked(fnum,cnum,token,&share_locked);
1700 if (share_locked && lp_share_modes(SNUM(cnum)))
1701 unlock_share_entry( cnum, dev, inode, token);
1704 /****************************************************************************
1705 seek a file. Try to avoid the seek if possible
1706 ****************************************************************************/
1707 int seek_file(int fnum,uint32 pos)
1710 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1713 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1715 return(Files[fnum].pos);
1718 /****************************************************************************
1720 ****************************************************************************/
1721 int read_file(int fnum,char *data,uint32 pos,int n)
1725 if (!Files[fnum].can_write)
1727 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1735 if (Files[fnum].mmap_ptr)
1737 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1740 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1752 if (seek_file(fnum,pos) != pos)
1754 DEBUG(3,("Failed to seek to %d\n",pos));
1759 readret = read(Files[fnum].fd_ptr->fd,data,n);
1760 if (readret > 0) ret += readret;
1767 /****************************************************************************
1769 ****************************************************************************/
1770 int write_file(int fnum,char *data,int n)
1772 if (!Files[fnum].can_write) {
1777 if (!Files[fnum].modified) {
1779 Files[fnum].modified = True;
1780 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1781 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1782 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1783 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1788 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1792 /****************************************************************************
1793 load parameters specific to a connection/service
1794 ****************************************************************************/
1795 BOOL become_service(int cnum,BOOL do_chdir)
1797 extern char magic_char;
1798 static int last_cnum = -1;
1801 if (!OPEN_CNUM(cnum))
1807 Connections[cnum].lastused = smb_last_time;
1812 ChDir(Connections[cnum].connectpath) != 0 &&
1813 ChDir(Connections[cnum].origpath) != 0)
1815 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1816 Connections[cnum].connectpath,cnum));
1820 if (cnum == last_cnum)
1825 case_default = lp_defaultcase(snum);
1826 case_preserve = lp_preservecase(snum);
1827 short_case_preserve = lp_shortpreservecase(snum);
1828 case_mangle = lp_casemangle(snum);
1829 case_sensitive = lp_casesensitive(snum);
1830 magic_char = lp_magicchar(snum);
1831 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1836 /****************************************************************************
1837 find a service entry
1838 ****************************************************************************/
1839 int find_service(char *service)
1843 string_sub(service,"\\","/");
1845 iService = lp_servicenumber(service);
1847 /* now handle the special case of a home directory */
1850 char *phome_dir = get_home_dir(service);
1851 DEBUG(3,("checking for home directory %s gave %s\n",service,
1852 phome_dir?phome_dir:"(NULL)"));
1856 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1858 lp_add_home(service,iHomeService,phome_dir);
1859 iService = lp_servicenumber(service);
1864 /* If we still don't have a service, attempt to add it as a printer. */
1867 int iPrinterService;
1869 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1873 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1875 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1877 DEBUG(3,("%s is a valid printer name\n", service));
1878 DEBUG(3,("adding %s as a printer service\n", service));
1879 lp_add_printer(service,iPrinterService);
1880 iService = lp_servicenumber(service);
1882 DEBUG(0,("failed to add %s as a printer service!\n", service));
1885 DEBUG(3,("%s is not a valid printer name\n", service));
1889 /* just possibly it's a default service? */
1892 char *defservice = lp_defaultservice();
1893 if (defservice && *defservice && !strequal(defservice,service)) {
1894 iService = find_service(defservice);
1895 if (iService >= 0) {
1896 string_sub(service,"_","/");
1897 iService = lp_add_service(service,iService);
1903 if (!VALID_SNUM(iService))
1905 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1910 DEBUG(3,("find_service() failed to find service %s\n", service));
1916 /****************************************************************************
1917 create an error packet from a cached error.
1918 ****************************************************************************/
1919 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1921 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1923 int32 eclass = wbmpx->wr_errclass;
1924 int32 err = wbmpx->wr_error;
1926 /* We can now delete the auxiliary struct */
1927 free((char *)wbmpx);
1928 Files[fnum].wbmpx_ptr = NULL;
1929 return error_packet(inbuf,outbuf,eclass,err,line);
1938 } unix_smb_errmap[] =
1940 {EPERM,ERRDOS,ERRnoaccess},
1941 {EACCES,ERRDOS,ERRnoaccess},
1942 {ENOENT,ERRDOS,ERRbadfile},
1943 {ENOTDIR,ERRDOS,ERRbadpath},
1944 {EIO,ERRHRD,ERRgeneral},
1945 {EBADF,ERRSRV,ERRsrverror},
1946 {EINVAL,ERRSRV,ERRsrverror},
1947 {EEXIST,ERRDOS,ERRfilexists},
1948 {ENFILE,ERRDOS,ERRnofids},
1949 {EMFILE,ERRDOS,ERRnofids},
1950 {ENOSPC,ERRHRD,ERRdiskfull},
1952 {EDQUOT,ERRHRD,ERRdiskfull},
1955 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1958 {EXDEV,ERRDOS,ERRdiffdevice},
1960 {EROFS,ERRHRD,ERRnowrite},
1965 /****************************************************************************
1966 create an error packet from errno
1967 ****************************************************************************/
1968 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1970 int eclass=def_class;
1974 if (unix_ERR_class != SUCCESS)
1976 eclass = unix_ERR_class;
1977 ecode = unix_ERR_code;
1978 unix_ERR_class = SUCCESS;
1983 while (unix_smb_errmap[i].smbclass != 0)
1985 if (unix_smb_errmap[i].unixerror == errno)
1987 eclass = unix_smb_errmap[i].smbclass;
1988 ecode = unix_smb_errmap[i].smbcode;
1995 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1999 /****************************************************************************
2000 create an error packet. Normally called using the ERROR() macro
2001 ****************************************************************************/
2002 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2004 int outsize = set_message(outbuf,0,0,True);
2006 cmd = CVAL(inbuf,smb_com);
2008 CVAL(outbuf,smb_rcls) = error_class;
2009 SSVAL(outbuf,smb_err,error_code);
2011 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2014 (int)CVAL(inbuf,smb_com),
2015 smb_fn_name(CVAL(inbuf,smb_com)),
2020 DEBUG(3,("error string = %s\n",strerror(errno)));
2026 #ifndef SIGCLD_IGNORE
2027 /****************************************************************************
2028 this prevents zombie child processes
2029 ****************************************************************************/
2030 static int sig_cld()
2032 static int depth = 0;
2035 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2041 BlockSignals(True,SIGCLD);
2042 DEBUG(5,("got SIGCLD\n"));
2045 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2049 /* Stevens, Adv. Unix Prog. says that on system V you must call
2050 wait before reinstalling the signal handler, because the kernel
2051 calls the handler from within the signal-call when there is a
2052 child that has exited. This would lead to an infinite recursion
2053 if done vice versa. */
2055 #ifndef DONT_REINSTALL_SIG
2056 #ifdef SIGCLD_IGNORE
2057 signal(SIGCLD, SIG_IGN);
2059 signal(SIGCLD, SIGNAL_CAST sig_cld);
2064 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2067 BlockSignals(False,SIGCLD);
2072 /****************************************************************************
2073 this is called when the client exits abruptly
2074 **************************************************************************/
2075 static int sig_pipe()
2077 extern int password_client;
2078 BlockSignals(True,SIGPIPE);
2080 if (password_client != -1) {
2081 DEBUG(3,("lost connection to password server\n"));
2082 close(password_client);
2083 password_client = -1;
2084 #ifndef DONT_REINSTALL_SIG
2085 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2087 BlockSignals(False,SIGPIPE);
2091 exit_server("Got sigpipe\n");
2095 /****************************************************************************
2096 open the socket communication
2097 ****************************************************************************/
2098 static BOOL open_sockets(BOOL is_daemon,int port)
2105 struct sockaddr addr;
2106 int in_addrlen = sizeof(addr);
2109 #ifdef SIGCLD_IGNORE
2110 signal(SIGCLD, SIG_IGN);
2112 signal(SIGCLD, SIGNAL_CAST sig_cld);
2115 /* open an incoming socket */
2116 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2120 /* ready to listen */
2121 if (listen(s, 5) == -1)
2123 DEBUG(0,("listen: %s\n",strerror(errno)));
2131 /* now accept incoming connections - forking a new process
2132 for each incoming connection */
2133 DEBUG(2,("waiting for a connection\n"));
2136 Client = accept(s,&addr,&in_addrlen);
2138 if (Client == -1 && errno == EINTR)
2143 DEBUG(0,("accept: %s\n",strerror(errno)));
2147 #ifdef NO_FORK_DEBUG
2148 #ifndef NO_SIGNAL_TEST
2149 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2150 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2154 if (Client != -1 && fork()==0)
2156 /* Child code ... */
2157 #ifndef NO_SIGNAL_TEST
2158 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2159 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2161 /* close the listening socket */
2164 /* close our standard file descriptors */
2168 set_socket_options(Client,"SO_KEEPALIVE");
2169 set_socket_options(Client,user_socket_options);
2171 /* Reset global variables in util.c so that
2172 client substitutions will be done correctly
2175 reset_globals_after_fork();
2178 close(Client); /* The parent doesn't need this socket */
2184 /* We will abort gracefully when the client or remote system
2186 #ifndef NO_SIGNAL_TEST
2187 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2191 /* close our standard file descriptors */
2194 set_socket_options(Client,"SO_KEEPALIVE");
2195 set_socket_options(Client,user_socket_options);
2202 /****************************************************************************
2203 check if a snum is in use
2204 ****************************************************************************/
2205 BOOL snum_used(int snum)
2208 for (i=0;i<MAX_CONNECTIONS;i++)
2209 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2214 /****************************************************************************
2215 reload the services file
2216 **************************************************************************/
2217 BOOL reload_services(BOOL test)
2224 strcpy(fname,lp_configfile());
2225 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2227 strcpy(servicesf,fname);
2234 if (test && !lp_file_list_changed())
2237 lp_killunused(snum_used);
2239 ret = lp_load(servicesf,False);
2241 /* perhaps the config filename is now set */
2243 reload_services(True);
2252 set_socket_options(Client,"SO_KEEPALIVE");
2253 set_socket_options(Client,user_socket_options);
2257 create_mangled_stack(lp_mangledstack());
2259 /* this forces service parameters to be flushed */
2260 become_service(-1,True);
2267 /****************************************************************************
2268 this prevents zombie child processes
2269 ****************************************************************************/
2270 static int sig_hup()
2272 BlockSignals(True,SIGHUP);
2273 DEBUG(0,("Got SIGHUP\n"));
2274 reload_services(False);
2275 #ifndef DONT_REINSTALL_SIG
2276 signal(SIGHUP,SIGNAL_CAST sig_hup);
2278 BlockSignals(False,SIGHUP);
2282 /****************************************************************************
2283 Setup the groups a user belongs to.
2284 ****************************************************************************/
2285 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2286 int **p_igroups, gid_t **p_groups)
2288 if (-1 == initgroups(user,gid))
2292 DEBUG(0,("Unable to initgroups!\n"));
2293 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2294 DEBUG(0,("This is probably a problem with the account %s\n",user));
2302 ngroups = getgroups(0,&grp);
2305 igroups = (int *)malloc(sizeof(int)*ngroups);
2306 for (i=0;i<ngroups;i++)
2307 igroups[i] = 0x42424242;
2308 ngroups = getgroups(ngroups,(gid_t *)igroups);
2310 if (igroups[0] == 0x42424242)
2313 *p_ngroups = ngroups;
2315 /* The following bit of code is very strange. It is due to the
2316 fact that some OSes use int* and some use gid_t* for
2317 getgroups, and some (like SunOS) use both, one in prototypes,
2318 and one in man pages and the actual code. Thus we detect it
2319 dynamically using some very ugly code */
2322 /* does getgroups return ints or gid_t ?? */
2323 static BOOL groups_use_ints = True;
2325 if (groups_use_ints &&
2327 SVAL(igroups,2) == 0x4242)
2328 groups_use_ints = False;
2330 for (i=0;groups_use_ints && i<ngroups;i++)
2331 if (igroups[i] == 0x42424242)
2332 groups_use_ints = False;
2334 if (groups_use_ints)
2336 *p_igroups = igroups;
2337 *p_groups = (gid_t *)igroups;
2341 gid_t *groups = (gid_t *)igroups;
2342 igroups = (int *)malloc(sizeof(int)*ngroups);
2343 for (i=0;i<ngroups;i++)
2344 igroups[i] = groups[i];
2345 *p_igroups = igroups;
2346 *p_groups = (gid_t *)groups;
2349 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2350 for (i=0;i<ngroups;i++)
2351 DEBUG(3,("%d ",igroups[i]));
2357 /****************************************************************************
2358 make a connection to a service
2359 ****************************************************************************/
2360 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2364 struct passwd *pass = NULL;
2365 connection_struct *pcon;
2368 static BOOL first_connection = True;
2372 snum = find_service(service);
2375 if (strequal(service,"IPC$"))
2377 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2381 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2385 if (strequal(service,HOMES_NAME))
2387 if (*user && Get_Pwnam(user,True))
2388 return(make_connection(user,user,password,pwlen,dev,vuid));
2390 if (validated_username(vuid))
2392 strcpy(user,validated_username(vuid));
2393 return(make_connection(user,user,password,pwlen,dev,vuid));
2397 if (!lp_snum_ok(snum) || !check_access(snum)) {
2401 /* you can only connect to the IPC$ service as an ipc device */
2402 if (strequal(service,"IPC$"))
2405 if (*dev == '?' || !*dev)
2407 if (lp_print_ok(snum))
2408 strcpy(dev,"LPT1:");
2413 /* if the request is as a printer and you can't print then refuse */
2415 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2416 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2420 /* lowercase the user name */
2423 /* add it as a possible user name */
2424 add_session_user(service);
2426 /* shall we let them in? */
2427 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2429 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2433 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2436 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2440 pcon = &Connections[cnum];
2441 bzero((char *)pcon,sizeof(*pcon));
2443 /* find out some info about the user */
2444 pass = Get_Pwnam(user,True);
2448 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2452 pcon->read_only = lp_readonly(snum);
2456 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2457 string_sub(list,"%S",service);
2459 if (user_in_list(user,list))
2460 pcon->read_only = True;
2462 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2463 string_sub(list,"%S",service);
2465 if (user_in_list(user,list))
2466 pcon->read_only = False;
2469 /* admin user check */
2470 if (user_in_list(user,lp_admin_users(snum)) &&
2473 pcon->admin_user = True;
2474 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2477 pcon->admin_user = False;
2479 pcon->force_user = force;
2481 pcon->uid = pass->pw_uid;
2482 pcon->gid = pass->pw_gid;
2483 pcon->num_files_open = 0;
2484 pcon->lastused = time(NULL);
2485 pcon->service = snum;
2487 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2488 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2489 pcon->dirptr = NULL;
2490 pcon->veto_list = NULL;
2491 pcon->hide_list = NULL;
2492 string_set(&pcon->dirpath,"");
2493 string_set(&pcon->user,user);
2496 if (*lp_force_group(snum))
2501 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2502 /* default service may be a group name */
2503 string_sub(gname,"%S",service);
2504 gptr = (struct group *)getgrnam(gname);
2508 pcon->gid = gptr->gr_gid;
2509 DEBUG(3,("Forced group %s\n",gname));
2512 DEBUG(1,("Couldn't find group %s\n",gname));
2516 if (*lp_force_user(snum))
2518 struct passwd *pass2;
2520 strcpy(fuser,lp_force_user(snum));
2521 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2524 pcon->uid = pass2->pw_uid;
2525 string_set(&pcon->user,fuser);
2527 pcon->force_user = True;
2528 DEBUG(3,("Forced user %s\n",fuser));
2531 DEBUG(1,("Couldn't find user %s\n",fuser));
2536 strcpy(s,lp_pathname(snum));
2537 standard_sub(cnum,s);
2538 string_set(&pcon->connectpath,s);
2539 DEBUG(3,("Connect path is %s\n",s));
2542 /* groups stuff added by ih */
2544 pcon->groups = NULL;
2548 /* Find all the groups this uid is in and store them. Used by become_user() */
2549 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2551 /* check number of connections */
2552 if (!claim_connection(cnum,
2553 lp_servicename(SNUM(cnum)),
2554 lp_max_connections(SNUM(cnum)),False))
2556 DEBUG(1,("too many connections - rejected\n"));
2560 if (lp_status(SNUM(cnum)))
2561 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2563 first_connection = False;
2568 /* execute any "root preexec = " line */
2569 if (*lp_rootpreexec(SNUM(cnum)))
2572 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2573 standard_sub(cnum,cmd);
2574 DEBUG(5,("cmd=%s\n",cmd));
2575 smbrun(cmd,NULL,False);
2578 if (!become_user(cnum,pcon->vuid))
2580 DEBUG(0,("Can't become connected user!\n"));
2582 if (!IS_IPC(cnum)) {
2583 yield_connection(cnum,
2584 lp_servicename(SNUM(cnum)),
2585 lp_max_connections(SNUM(cnum)));
2586 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2591 if (ChDir(pcon->connectpath) != 0)
2593 DEBUG(0,("Can't change directory to %s (%s)\n",
2594 pcon->connectpath,strerror(errno)));
2597 if (!IS_IPC(cnum)) {
2598 yield_connection(cnum,
2599 lp_servicename(SNUM(cnum)),
2600 lp_max_connections(SNUM(cnum)));
2601 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2606 string_set(&pcon->origpath,pcon->connectpath);
2608 #if SOFTLINK_OPTIMISATION
2609 /* resolve any soft links early */
2612 strcpy(s,pcon->connectpath);
2614 string_set(&pcon->connectpath,s);
2615 ChDir(pcon->connectpath);
2619 num_connections_open++;
2620 add_session_user(user);
2622 /* execute any "preexec = " line */
2623 if (*lp_preexec(SNUM(cnum)))
2626 strcpy(cmd,lp_preexec(SNUM(cnum)));
2627 standard_sub(cnum,cmd);
2628 smbrun(cmd,NULL,False);
2631 /* we've finished with the sensitive stuff */
2634 /* Add veto/hide lists */
2635 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
2637 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
2638 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
2642 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2646 lp_servicename(SNUM(cnum)),user,
2656 /****************************************************************************
2657 find first available file slot
2658 ****************************************************************************/
2659 int find_free_file(void )
2662 /* we start at 1 here for an obscure reason I can't now remember,
2663 but I think is important :-) */
2664 for (i=1;i<MAX_OPEN_FILES;i++)
2667 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2671 /****************************************************************************
2672 find first available connection slot, starting from a random position.
2673 The randomisation stops problems with the server dieing and clients
2674 thinking the server is still available.
2675 ****************************************************************************/
2676 static int find_free_connection(int hash )
2680 hash = (hash % (MAX_CONNECTIONS-2))+1;
2684 for (i=hash+1;i!=hash;)
2686 if (!Connections[i].open && Connections[i].used == used)
2688 DEBUG(3,("found free connection number %d\n",i));
2692 if (i == MAX_CONNECTIONS)
2702 DEBUG(1,("ERROR! Out of connection structures\n"));
2707 /****************************************************************************
2708 reply for the core protocol
2709 ****************************************************************************/
2710 int reply_corep(char *outbuf)
2712 int outsize = set_message(outbuf,1,0,True);
2714 Protocol = PROTOCOL_CORE;
2720 /****************************************************************************
2721 reply for the coreplus protocol
2722 ****************************************************************************/
2723 int reply_coreplus(char *outbuf)
2725 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2726 int outsize = set_message(outbuf,13,0,True);
2727 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2728 readbraw and writebraw (possibly) */
2729 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2730 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2732 Protocol = PROTOCOL_COREPLUS;
2738 /****************************************************************************
2739 reply for the lanman 1.0 protocol
2740 ****************************************************************************/
2741 int reply_lanman1(char *outbuf)
2743 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2745 BOOL doencrypt = SMBENCRYPT();
2746 time_t t = time(NULL);
2747 /* We need to save and restore this as it can be destroyed
2748 if we call another server if security=server
2749 Thanks to Paul Nelson @ Thursby for pointing this out.
2751 uint16 mid = SVAL(outbuf, smb_mid);
2753 if (lp_security()>=SEC_USER) secword |= 1;
2754 if (doencrypt) secword |= 2;
2756 set_message(outbuf,13,doencrypt?8:0,True);
2757 SSVAL(outbuf,smb_vwv1,secword);
2759 /* Create a token value and add it to the outgoing packet. */
2761 generate_next_challenge(smb_buf(outbuf));
2764 Protocol = PROTOCOL_LANMAN1;
2766 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2767 DEBUG(3,("using password server validation\n"));
2769 if (doencrypt) set_challenge(smb_buf(outbuf));
2773 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2774 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2775 SSVAL(outbuf,smb_vwv2,max_recv);
2776 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2777 SSVAL(outbuf,smb_vwv4,1);
2778 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2779 readbraw writebraw (possibly) */
2780 SIVAL(outbuf,smb_vwv6,getpid());
2781 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2783 put_dos_date(outbuf,smb_vwv8,t);
2785 return (smb_len(outbuf)+4);
2789 /****************************************************************************
2790 reply for the lanman 2.0 protocol
2791 ****************************************************************************/
2792 int reply_lanman2(char *outbuf)
2794 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2796 BOOL doencrypt = SMBENCRYPT();
2797 time_t t = time(NULL);
2798 /* We need to save and restore this as it can be destroyed
2799 if we call another server if security=server
2800 Thanks to Paul Nelson @ Thursby for pointing this out.
2802 uint16 mid = SVAL(outbuf, smb_mid);
2804 if (lp_security()>=SEC_USER) secword |= 1;
2805 if (doencrypt) secword |= 2;
2807 set_message(outbuf,13,doencrypt?8:0,True);
2808 SSVAL(outbuf,smb_vwv1,secword);
2810 /* Create a token value and add it to the outgoing packet. */
2812 generate_next_challenge(smb_buf(outbuf));
2815 SIVAL(outbuf,smb_vwv6,getpid());
2817 Protocol = PROTOCOL_LANMAN2;
2819 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2820 DEBUG(3,("using password server validation\n"));
2822 if (doencrypt) set_challenge(smb_buf(outbuf));
2826 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2827 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2828 SSVAL(outbuf,smb_vwv2,max_recv);
2829 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2830 SSVAL(outbuf,smb_vwv4,1);
2831 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2832 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2833 put_dos_date(outbuf,smb_vwv8,t);
2835 return (smb_len(outbuf)+4);
2839 /****************************************************************************
2840 reply for the nt protocol
2841 ****************************************************************************/
2842 int reply_nt1(char *outbuf)
2844 /* dual names + lock_and_read + nt SMBs + remote API calls */
2845 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2847 other valid capabilities which we may support at some time...
2848 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2849 CAP_LARGE_FILES|CAP_LARGE_READX|
2850 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2854 BOOL doencrypt = SMBENCRYPT();
2855 time_t t = time(NULL);
2858 char challenge_len = 8;
2859 /* We need to save and restore this as it can be destroyed
2860 if we call another server if security=server
2861 Thanks to Paul Nelson @ Thursby for pointing this out.
2863 uint16 mid = SVAL(outbuf, smb_mid);
2865 if (lp_readraw() && lp_writeraw())
2867 capabilities |= CAP_RAW_MODE;
2870 if (lp_security()>=SEC_USER) secword |= 1;
2871 if (doencrypt) secword |= 2;
2873 /* decide where (if) to put the encryption challenge, and
2874 follow it with the OEM'd domain name
2876 encrypt_len = doencrypt?challenge_len:0;
2878 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
2880 data_len = encrypt_len + strlen(myworkgroup) + 1;
2883 set_message(outbuf,17,data_len,True);
2886 /* put the OEM'd domain name */
2887 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
2889 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
2892 CVAL(outbuf,smb_vwv1) = secword;
2894 /* Create a token value and add it to the outgoing packet. */
2897 generate_next_challenge(smb_buf(outbuf));
2899 /* Tell the nt machine how long the challenge is. */
2900 SSVALS(outbuf,smb_vwv16+1,challenge_len);
2904 Protocol = PROTOCOL_NT1;
2906 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2907 DEBUG(3,("using password server validation\n"));
2909 if (doencrypt) set_challenge(smb_buf(outbuf));
2913 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2914 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2915 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2916 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
2917 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
2918 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2919 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2920 put_long_date(outbuf+smb_vwv11+1,t);
2921 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2922 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
2924 return (smb_len(outbuf)+4);
2927 /* these are the protocol lists used for auto architecture detection:
2930 protocol [PC NETWORK PROGRAM 1.0]
2931 protocol [XENIX CORE]
2932 protocol [MICROSOFT NETWORKS 1.03]
2933 protocol [LANMAN1.0]
2934 protocol [Windows for Workgroups 3.1a]
2935 protocol [LM1.2X002]
2936 protocol [LANMAN2.1]
2937 protocol [NT LM 0.12]
2940 protocol [PC NETWORK PROGRAM 1.0]
2941 protocol [XENIX CORE]
2942 protocol [MICROSOFT NETWORKS 1.03]
2943 protocol [LANMAN1.0]
2944 protocol [Windows for Workgroups 3.1a]
2945 protocol [LM1.2X002]
2946 protocol [LANMAN2.1]
2947 protocol [NT LM 0.12]
2950 protocol [PC NETWORK PROGRAM 1.0]
2951 protocol [XENIX CORE]
2952 protocol [LANMAN1.0]
2953 protocol [LM1.2X002]
2954 protocol [LANMAN2.1]
2958 * Modified to recognize the architecture of the remote machine better.
2960 * This appears to be the matrix of which protocol is used by which
2962 Protocol WfWg Win95 WinNT OS/2
2963 PC NETWORK PROGRAM 1.0 1 1 1 1
2965 MICROSOFT NETWORKS 3.0 2 2
2967 MICROSOFT NETWORKS 1.03 3
2970 Windows for Workgroups 3.1a 5 5 5
2975 * tim@fsg.com 09/29/95
2978 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2979 #define ARCH_WIN95 0x2
2980 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2981 #define ARCH_WINNT 0x8
2982 #define ARCH_SAMBA 0x10
2984 #define ARCH_ALL 0x1F
2986 /* List of supported protocols, most desired first */
2990 int (*proto_reply_fn)(char *);
2992 } supported_protocols[] = {
2993 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2994 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2995 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2996 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2997 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2998 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2999 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3000 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3001 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3006 /****************************************************************************
3008 ****************************************************************************/
3009 static int reply_negprot(char *inbuf,char *outbuf)
3011 extern fstring remote_arch;
3012 int outsize = set_message(outbuf,1,0,True);
3017 int bcc = SVAL(smb_buf(inbuf),-2);
3018 int arch = ARCH_ALL;
3020 p = smb_buf(inbuf)+1;
3021 while (p < (smb_buf(inbuf) + bcc))
3024 DEBUG(3,("Requested protocol [%s]\n",p));
3025 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3026 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3027 else if (strcsequal(p,"DOS LM1.2X002"))
3028 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3029 else if (strcsequal(p,"DOS LANMAN2.1"))
3030 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3031 else if (strcsequal(p,"NT LM 0.12"))
3032 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3033 else if (strcsequal(p,"LANMAN2.1"))
3034 arch &= ( ARCH_WINNT | ARCH_OS2 );
3035 else if (strcsequal(p,"LM1.2X002"))
3036 arch &= ( ARCH_WINNT | ARCH_OS2 );
3037 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3039 else if (strcsequal(p,"XENIX CORE"))
3040 arch &= ( ARCH_WINNT | ARCH_OS2 );
3041 else if (strcsequal(p,"Samba")) {
3051 strcpy(remote_arch,"Samba");
3054 strcpy(remote_arch,"WfWg");
3057 strcpy(remote_arch,"Win95");
3060 strcpy(remote_arch,"WinNT");
3063 strcpy(remote_arch,"OS2");
3066 strcpy(remote_arch,"UNKNOWN");
3070 /* possibly reload - change of architecture */
3071 reload_services(True);
3073 /* a special case to stop password server loops */
3074 if (Index == 1 && strequal(remote_machine,myhostname) &&
3075 lp_security()==SEC_SERVER)
3076 exit_server("Password server loop!");
3078 /* Check for protocols, most desirable first */
3079 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3081 p = smb_buf(inbuf)+1;
3083 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3084 while (p < (smb_buf(inbuf) + bcc))
3086 if (strequal(p,supported_protocols[protocol].proto_name))
3095 SSVAL(outbuf,smb_vwv0,choice);
3097 extern fstring remote_proto;
3098 strcpy(remote_proto,supported_protocols[protocol].short_name);
3099 reload_services(True);
3100 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3101 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3104 DEBUG(0,("No protocol supported !\n"));
3106 SSVAL(outbuf,smb_vwv0,choice);
3108 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3114 /****************************************************************************
3115 close all open files for a connection
3116 ****************************************************************************/
3117 static void close_open_files(int cnum)
3120 for (i=0;i<MAX_OPEN_FILES;i++)
3121 if( Files[i].cnum == cnum && Files[i].open) {
3128 /****************************************************************************
3130 ****************************************************************************/
3131 void close_cnum(int cnum, uint16 vuid)
3133 DirCacheFlush(SNUM(cnum));
3137 if (!OPEN_CNUM(cnum))
3139 DEBUG(0,("Can't close cnum %d\n",cnum));
3143 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3145 remote_machine,client_addr(),
3146 lp_servicename(SNUM(cnum))));
3148 yield_connection(cnum,
3149 lp_servicename(SNUM(cnum)),
3150 lp_max_connections(SNUM(cnum)));
3152 if (lp_status(SNUM(cnum)))
3153 yield_connection(cnum,"STATUS.",MAXSTATUS);
3155 close_open_files(cnum);
3156 dptr_closecnum(cnum);
3158 /* execute any "postexec = " line */
3159 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3162 strcpy(cmd,lp_postexec(SNUM(cnum)));
3163 standard_sub(cnum,cmd);
3164 smbrun(cmd,NULL,False);
3169 /* execute any "root postexec = " line */
3170 if (*lp_rootpostexec(SNUM(cnum)))
3173 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3174 standard_sub(cnum,cmd);
3175 smbrun(cmd,NULL,False);
3178 Connections[cnum].open = False;
3179 num_connections_open--;
3180 if (Connections[cnum].ngroups && Connections[cnum].groups)
3182 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3183 free(Connections[cnum].groups);
3184 free(Connections[cnum].igroups);
3185 Connections[cnum].groups = NULL;
3186 Connections[cnum].igroups = NULL;
3187 Connections[cnum].ngroups = 0;
3190 free_namearray(Connections[cnum].veto_list);
3191 free_namearray(Connections[cnum].hide_list);
3193 string_set(&Connections[cnum].user,"");
3194 string_set(&Connections[cnum].dirpath,"");
3195 string_set(&Connections[cnum].connectpath,"");
3199 /****************************************************************************
3200 simple routines to do connection counting
3201 ****************************************************************************/
3202 BOOL yield_connection(int cnum,char *name,int max_connections)
3204 struct connect_record crec;
3207 int mypid = getpid();
3210 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3212 if (max_connections <= 0)
3215 bzero(&crec,sizeof(crec));
3217 strcpy(fname,lp_lockdir());
3218 standard_sub(cnum,fname);
3219 trim_string(fname,"","/");
3223 strcat(fname,".LCK");
3225 f = fopen(fname,"r+");
3228 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3232 fseek(f,0,SEEK_SET);
3234 /* find a free spot */
3235 for (i=0;i<max_connections;i++)
3237 if (fread(&crec,sizeof(crec),1,f) != 1)
3239 DEBUG(2,("Entry not found in lock file %s\n",fname));
3243 if (crec.pid == mypid && crec.cnum == cnum)
3247 if (crec.pid != mypid || crec.cnum != cnum)
3250 DEBUG(2,("Entry not found in lock file %s\n",fname));
3254 bzero((void *)&crec,sizeof(crec));
3256 /* remove our mark */
3257 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3258 fwrite(&crec,sizeof(crec),1,f) != 1)
3260 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3265 DEBUG(3,("Yield successful\n"));
3272 /****************************************************************************
3273 simple routines to do connection counting
3274 ****************************************************************************/
3275 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3277 struct connect_record crec;
3280 int snum = SNUM(cnum);
3284 if (max_connections <= 0)
3287 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3289 strcpy(fname,lp_lockdir());
3290 standard_sub(cnum,fname);
3291 trim_string(fname,"","/");
3293 if (!directory_exist(fname,NULL))
3298 strcat(fname,".LCK");
3300 if (!file_exist(fname,NULL))
3302 int oldmask = umask(022);
3303 f = fopen(fname,"w");
3308 total_recs = file_size(fname) / sizeof(crec);
3310 f = fopen(fname,"r+");
3314 DEBUG(1,("couldn't open lock file %s\n",fname));
3318 /* find a free spot */
3319 for (i=0;i<max_connections;i++)
3322 if (i>=total_recs ||
3323 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3324 fread(&crec,sizeof(crec),1,f) != 1)
3326 if (foundi < 0) foundi = i;
3330 if (Clear && crec.pid && !process_exists(crec.pid))
3332 fseek(f,i*sizeof(crec),SEEK_SET);
3333 bzero((void *)&crec,sizeof(crec));
3334 fwrite(&crec,sizeof(crec),1,f);
3335 if (foundi < 0) foundi = i;
3338 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3347 DEBUG(3,("no free locks in %s\n",fname));
3352 /* fill in the crec */
3353 bzero((void *)&crec,sizeof(crec));
3354 crec.magic = 0x280267;
3355 crec.pid = getpid();
3357 crec.uid = Connections[cnum].uid;
3358 crec.gid = Connections[cnum].gid;
3359 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3360 crec.start = time(NULL);
3362 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3363 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3366 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3367 fwrite(&crec,sizeof(crec),1,f) != 1)
3378 /*******************************************************************
3379 prepare to dump a core file - carefully!
3380 ********************************************************************/
3381 static BOOL dump_core(void)
3385 strcpy(dname,debugf);
3386 if ((p=strrchr(dname,'/'))) *p=0;
3387 strcat(dname,"/corefiles");
3389 sys_chown(dname,getuid(),getgid());
3391 if (chdir(dname)) return(False);
3394 #ifndef NO_GETRLIMIT
3398 getrlimit(RLIMIT_CORE, &rlp);
3399 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3400 setrlimit(RLIMIT_CORE, &rlp);
3401 getrlimit(RLIMIT_CORE, &rlp);
3402 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3408 DEBUG(0,("Dumping core in %s\n",dname));
3413 /****************************************************************************
3415 ****************************************************************************/
3416 void exit_server(char *reason)
3418 static int firsttime=1;
3421 if (!firsttime) exit(0);
3425 DEBUG(2,("Closing connections\n"));
3426 for (i=0;i<MAX_CONNECTIONS;i++)
3427 if (Connections[i].open)
3428 close_cnum(i,(uint16)-1);
3430 if (dcelogin_atmost_once)
3434 int oldlevel = DEBUGLEVEL;
3436 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3438 show_msg(last_inbuf);
3439 DEBUGLEVEL = oldlevel;
3440 DEBUG(0,("===============================================================\n"));
3442 if (dump_core()) return;
3446 #ifdef FAST_SHARE_MODES
3447 stop_share_mode_mgmt();
3448 #endif /* FAST_SHARE_MODES */
3450 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3454 /****************************************************************************
3455 do some standard substitutions in a string
3456 ****************************************************************************/
3457 void standard_sub(int cnum,char *string)
3459 if (VALID_CNUM(cnum)) {
3462 for ( s=string ; (p=strchr(s, '%')) != NULL ; s=p ) {
3464 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
3465 string_sub(p,"%H",home);
3469 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
3470 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
3471 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
3472 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
3473 case '\0' : p++; break; /* don't run off the end of the string */
3474 default : p+=2; break;
3478 standard_sub_basic(string);
3482 These flags determine some of the permissions required to do an operation
3484 Note that I don't set NEED_WRITE on some write operations because they
3485 are used by some brain-dead clients when printing, and I don't want to
3486 force write permissions on print services.
3488 #define AS_USER (1<<0)
3489 #define NEED_WRITE (1<<1)
3490 #define TIME_INIT (1<<2)
3491 #define CAN_IPC (1<<3)
3492 #define AS_GUEST (1<<5)
3496 define a list of possible SMB messages and their corresponding
3497 functions. Any message that has a NULL function is unimplemented -
3498 please feel free to contribute implementations!
3500 struct smb_message_struct
3514 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3515 {SMBtcon,"SMBtcon",reply_tcon,0},
3516 {SMBtdis,"SMBtdis",reply_tdis,0},
3517 {SMBexit,"SMBexit",reply_exit,0},
3518 {SMBioctl,"SMBioctl",reply_ioctl,0},
3519 {SMBecho,"SMBecho",reply_echo,0},
3520 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3521 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3522 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3523 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3524 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3525 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3526 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3527 {SMBopen,"SMBopen",reply_open,AS_USER},
3529 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3530 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3531 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3533 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3534 {SMBread,"SMBread",reply_read,AS_USER},
3535 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3536 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3537 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3538 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3539 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3540 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3542 /* this is a Pathworks specific call, allowing the
3543 changing of the root path */
3544 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3546 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3547 {SMBflush,"SMBflush",reply_flush,AS_USER},
3548 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3549 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3550 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3551 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3552 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3553 {SMBlock,"SMBlock",reply_lock,AS_USER},
3554 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3556 /* CORE+ PROTOCOL FOLLOWS */
3558 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3559 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3560 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3561 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3562 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3564 /* LANMAN1.0 PROTOCOL FOLLOWS */
3566 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3567 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3568 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3569 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3570 {SMBwritec,"SMBwritec",NULL,AS_USER},
3571 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3572 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3573 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3574 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3575 {SMBioctls,"SMBioctls",NULL,AS_USER},
3576 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3577 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3579 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3580 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3581 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3582 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3584 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3585 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3586 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3588 /* LANMAN2.0 PROTOCOL FOLLOWS */
3589 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3590 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3591 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3592 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3594 /* messaging routines */
3595 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3596 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3597 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3598 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3600 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3602 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3603 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3604 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3605 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3608 /****************************************************************************
3609 return a string containing the function name of a SMB command
3610 ****************************************************************************/
3611 char *smb_fn_name(int type)
3613 static char *unknown_name = "SMBunknown";
3614 static int num_smb_messages =
3615 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3618 for (match=0;match<num_smb_messages;match++)
3619 if (smb_messages[match].code == type)
3622 if (match == num_smb_messages)
3623 return(unknown_name);
3625 return(smb_messages[match].name);
3629 /****************************************************************************
3630 do a switch on the message type, and return the response size
3631 ****************************************************************************/
3632 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3636 static int num_smb_messages =
3637 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3641 struct timeval msg_start_time;
3642 struct timeval msg_end_time;
3643 static unsigned long total_time = 0;
3645 GetTimeOfDay(&msg_start_time);
3652 last_message = type;
3654 /* make sure this is an SMB packet */
3655 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3657 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3661 for (match=0;match<num_smb_messages;match++)
3662 if (smb_messages[match].code == type)
3665 if (match == num_smb_messages)
3667 DEBUG(0,("Unknown message type %d!\n",type));
3668 outsize = reply_unknown(inbuf,outbuf);
3672 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3673 if (smb_messages[match].fn)
3675 int cnum = SVAL(inbuf,smb_tid);
3676 int flags = smb_messages[match].flags;
3677 uint16 session_tag = SVAL(inbuf,smb_uid);
3679 /* does this protocol need to be run as root? */
3680 if (!(flags & AS_USER))
3683 /* does this protocol need to be run as the connected user? */
3684 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3685 if (flags & AS_GUEST)
3688 return(ERROR(ERRSRV,ERRinvnid));
3690 /* this code is to work around a bug is MS client 3 without
3691 introducing a security hole - it needs to be able to do
3692 print queue checks as guest if it isn't logged in properly */
3693 if (flags & AS_USER)
3696 /* does it need write permission? */
3697 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3698 return(ERROR(ERRSRV,ERRaccess));
3700 /* ipc services are limited */
3701 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3702 return(ERROR(ERRSRV,ERRaccess));
3704 /* load service specific parameters */
3705 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3706 return(ERROR(ERRSRV,ERRaccess));
3708 /* does this protocol need to be run as guest? */
3709 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3710 return(ERROR(ERRSRV,ERRaccess));
3714 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3718 outsize = reply_unknown(inbuf,outbuf);
3723 GetTimeOfDay(&msg_end_time);
3724 if (!(smb_messages[match].flags & TIME_INIT))
3726 smb_messages[match].time = 0;
3727 smb_messages[match].flags |= TIME_INIT;
3730 unsigned long this_time =
3731 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3732 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3733 smb_messages[match].time += this_time;
3734 total_time += this_time;
3736 DEBUG(2,("TIME %s %d usecs %g pct\n",
3737 smb_fn_name(type),smb_messages[match].time,
3738 (100.0*smb_messages[match].time) / total_time));
3745 /****************************************************************************
3746 construct a chained reply and add it to the already made reply
3747 **************************************************************************/
3748 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3750 static char *orig_inbuf;
3751 static char *orig_outbuf;
3752 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3753 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3754 char *inbuf2, *outbuf2;
3756 char inbuf_saved[smb_wct];
3757 char outbuf_saved[smb_wct];
3758 extern int chain_size;
3759 int wct = CVAL(outbuf,smb_wct);
3760 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3762 /* maybe its not chained */
3763 if (smb_com2 == 0xFF) {
3764 CVAL(outbuf,smb_vwv0) = 0xFF;
3768 if (chain_size == 0) {
3769 /* this is the first part of the chain */
3771 orig_outbuf = outbuf;
3774 /* we need to tell the client where the next part of the reply will be */
3775 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3776 CVAL(outbuf,smb_vwv0) = smb_com2;
3778 /* remember how much the caller added to the chain, only counting stuff
3779 after the parameter words */
3780 chain_size += outsize - smb_wct;
3782 /* work out pointers into the original packets. The
3783 headers on these need to be filled in */
3784 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3785 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3787 /* remember the original command type */
3788 smb_com1 = CVAL(orig_inbuf,smb_com);
3790 /* save the data which will be overwritten by the new headers */
3791 memcpy(inbuf_saved,inbuf2,smb_wct);
3792 memcpy(outbuf_saved,outbuf2,smb_wct);
3794 /* give the new packet the same header as the last part of the SMB */
3795 memmove(inbuf2,inbuf,smb_wct);
3797 /* create the in buffer */
3798 CVAL(inbuf2,smb_com) = smb_com2;
3800 /* create the out buffer */
3801 bzero(outbuf2,smb_size);
3802 set_message(outbuf2,0,0,True);
3803 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3805 memcpy(outbuf2+4,inbuf2+4,4);
3806 CVAL(outbuf2,smb_rcls) = SUCCESS;
3807 CVAL(outbuf2,smb_reh) = 0;
3808 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3810 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3811 SSVAL(outbuf2,smb_err,SUCCESS);
3812 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3813 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3814 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3815 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3817 DEBUG(3,("Chained message\n"));
3820 /* process the request */
3821 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3822 bufsize-chain_size);
3824 /* copy the new reply and request headers over the old ones, but
3825 preserve the smb_com field */
3826 memmove(orig_outbuf,outbuf2,smb_wct);
3827 CVAL(orig_outbuf,smb_com) = smb_com1;
3829 /* restore the saved data, being careful not to overwrite any
3830 data from the reply header */
3831 memcpy(inbuf2,inbuf_saved,smb_wct);
3833 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3834 if (ofs < 0) ofs = 0;
3835 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3843 /****************************************************************************
3844 construct a reply to the incoming packet
3845 ****************************************************************************/
3846 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3848 int type = CVAL(inbuf,smb_com);
3850 int msg_type = CVAL(inbuf,0);
3851 extern int chain_size;
3853 smb_last_time = time(NULL);
3858 bzero(outbuf,smb_size);
3861 return(reply_special(inbuf,outbuf));
3863 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3864 set_message(outbuf,0,0,True);
3866 memcpy(outbuf+4,inbuf+4,4);
3867 CVAL(outbuf,smb_rcls) = SUCCESS;
3868 CVAL(outbuf,smb_reh) = 0;
3869 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3871 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3872 SSVAL(outbuf,smb_err,SUCCESS);
3873 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3874 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3875 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3876 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3878 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3880 outsize += chain_size;
3883 smb_setlen(outbuf,outsize - 4);
3888 /****************************************************************************
3889 process commands from the client
3890 ****************************************************************************/
3891 static void process(void)
3893 static int trans_num = 0;
3897 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3898 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3899 if ((InBuffer == NULL) || (OutBuffer == NULL))
3902 InBuffer += SMB_ALIGNMENT;
3903 OutBuffer += SMB_ALIGNMENT;
3906 DEBUG(3,("priming nmbd\n"));
3909 ip = *interpret_addr2("localhost");
3910 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3912 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3922 int deadtime = lp_deadtime()*60;
3924 int last_keepalive=0;
3925 int service_load_counter = 0;
3928 deadtime = DEFAULT_SMBD_TIMEOUT;
3930 if (lp_readprediction())
3931 do_read_prediction();
3935 for (counter=SMBD_SELECT_LOOP;
3936 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3937 counter += SMBD_SELECT_LOOP)
3941 BOOL allidle = True;
3942 extern int keepalive;
3944 if (counter > 365 * 3600) /* big number of seconds. */
3947 service_load_counter = 0;
3950 if (smb_read_error == READ_EOF) {
3951 DEBUG(3,("end of file from client\n"));
3955 if (smb_read_error == READ_ERROR) {
3956 DEBUG(3,("receive_smb error (%s) exiting\n",
3963 /* become root again if waiting */
3966 /* check for smb.conf reload */
3967 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
3969 service_load_counter = counter;
3971 /* reload services, if files have changed. */
3972 reload_services(True);
3975 /* automatic timeout if all connections are closed */
3976 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3977 DEBUG(2,("%s Closing idle connection\n",timestring()));
3981 if (keepalive && (counter-last_keepalive)>keepalive) {
3982 extern int password_client;
3983 if (!send_keepalive(Client)) {
3984 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3987 /* also send a keepalive to the password server if its still
3989 if (password_client != -1)
3990 send_keepalive(password_client);
3991 last_keepalive = counter;
3994 /* check for connection timeouts */
3995 for (i=0;i<MAX_CONNECTIONS;i++)
3996 if (Connections[i].open)
3998 /* close dirptrs on connections that are idle */
3999 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4002 if (Connections[i].num_files_open > 0 ||
4003 (t-Connections[i].lastused)<deadtime)
4007 if (allidle && num_connections_open>0) {
4008 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4013 msg_type = CVAL(InBuffer,0);
4014 msg_flags = CVAL(InBuffer,1);
4015 type = CVAL(InBuffer,smb_com);
4017 len = smb_len(InBuffer);
4019 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
4023 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
4026 if(trans_num == 1 && VT_Check(InBuffer)) {
4036 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
4039 if (CVAL(OutBuffer,0) == 0)
4040 show_msg(OutBuffer);
4042 if (nread != smb_len(OutBuffer) + 4)
4044 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
4046 smb_len(OutBuffer)));
4049 send_smb(Client,OutBuffer);
4056 /****************************************************************************
4057 initialise connect, service and file structs
4058 ****************************************************************************/
4059 static void init_structs(void )
4062 get_myname(myhostname,NULL);
4064 for (i=0;i<MAX_CONNECTIONS;i++)
4066 Connections[i].open = False;
4067 Connections[i].num_files_open=0;
4068 Connections[i].lastused=0;
4069 Connections[i].used=False;
4070 string_init(&Connections[i].user,"");
4071 string_init(&Connections[i].dirpath,"");
4072 string_init(&Connections[i].connectpath,"");
4073 string_init(&Connections[i].origpath,"");
4076 for (i=0;i<MAX_OPEN_FILES;i++)
4078 Files[i].open = False;
4079 string_init(&Files[i].name,"");
4083 for (i=0;i<MAX_OPEN_FILES;i++)
4085 file_fd_struct *fd_ptr = &FileFd[i];
4086 fd_ptr->ref_count = 0;
4087 fd_ptr->dev = (int32)-1;
4088 fd_ptr->inode = (int32)-1;
4090 fd_ptr->fd_readonly = -1;
4091 fd_ptr->fd_writeonly = -1;
4092 fd_ptr->real_open_flags = -1;
4098 /****************************************************************************
4099 usage on the program
4100 ****************************************************************************/
4101 static void usage(char *pname)
4103 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4105 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4106 printf("Version %s\n",VERSION);
4107 printf("\t-D become a daemon\n");
4108 printf("\t-p port listen on the specified port\n");
4109 printf("\t-d debuglevel set the debuglevel\n");
4110 printf("\t-l log basename. Basename for log/debug files\n");
4111 printf("\t-s services file. Filename of services file\n");
4112 printf("\t-P passive only\n");
4113 printf("\t-a overwrite log file, don't append\n");
4118 /****************************************************************************
4120 ****************************************************************************/
4121 int main(int argc,char *argv[])
4123 extern BOOL append_log;
4124 /* shall I run as a daemon */
4125 BOOL is_daemon = False;
4126 int port = SMB_PORT;
4128 extern char *optarg;
4129 char pidFile[100] = { 0 };
4131 #ifdef NEED_AUTH_PARAMETERS
4132 set_auth_parameters(argc,argv);
4143 strcpy(debugf,SMBLOGFILE);
4145 setup_logging(argv[0],False);
4147 charset_initialise();
4149 /* make absolutely sure we run as root - to handle cases whre people
4150 are crazy enough to have it setuid */
4160 fault_setup(exit_server);
4161 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4163 /* we want total control over the permissions on created files,
4164 so set our umask to 0 */
4171 /* this is for people who can't start the program correctly */
4172 while (argc > 1 && (*argv[1] != '-'))
4178 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4182 strncpy(pidFile, optarg, sizeof(pidFile));
4185 strcpy(user_socket_options,optarg);
4188 strcpy(scope,optarg);
4192 extern BOOL passive;
4197 strcpy(servicesf,optarg);
4200 strcpy(debugf,optarg);
4204 extern BOOL append_log;
4205 append_log = !append_log;
4215 DEBUGLEVEL = atoi(optarg);
4218 port = atoi(optarg);
4231 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4232 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4234 #ifndef NO_GETRLIMIT
4235 #ifdef RLIMIT_NOFILE
4238 getrlimit(RLIMIT_NOFILE, &rlp);
4239 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4240 setrlimit(RLIMIT_NOFILE, &rlp);
4241 getrlimit(RLIMIT_NOFILE, &rlp);
4242 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4248 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4249 getuid(),getgid(),geteuid(),getegid()));
4251 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4253 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4259 if (!reload_services(False))
4262 codepage_initialise(lp_client_code_page());
4264 strcpy(myworkgroup, lp_workgroup());
4266 #ifndef NO_SIGNAL_TEST
4267 signal(SIGHUP,SIGNAL_CAST sig_hup);
4270 DEBUG(3,("%s loaded services\n",timestring()));
4272 if (!is_daemon && !is_a_socket(0))
4274 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4280 DEBUG(3,("%s becoming a daemon\n",timestring()));
4289 if ((fd = open(pidFile,
4293 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4295 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4298 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4300 DEBUG(0,("ERROR: smbd is already running\n"));
4303 sprintf(buf, "%u\n", (unsigned int) getpid());
4304 if (write(fd, buf, strlen(buf)) < 0)
4306 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4309 /* Leave pid file open & locked for the duration... */
4312 if (!open_sockets(is_daemon,port))
4315 #ifdef FAST_SHARE_MODES
4316 if (!start_share_mode_mgmt())
4318 #endif /* FAST_SHARE_MODES */
4320 /* possibly reload the services file. */
4321 reload_services(True);
4323 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4327 if (sys_chroot(lp_rootdir()) == 0)
4328 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4334 exit_server("normal exit");