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 base permission for directories:
134 dos directory is represented in unix by unix's dir bit and the exec bit
135 ****************************************************************************/
136 mode_t unix_mode(int cnum,int dosmode)
138 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
140 if ( !IS_DOS_READONLY(dosmode) )
141 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
143 if (IS_DOS_DIR(dosmode)) {
144 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
145 result &= (lp_dir_mode(SNUM(cnum)) | 0700);
147 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
150 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
153 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
156 result &= CREATE_MODE(cnum);
162 /****************************************************************************
163 change a unix mode to a dos mode
164 ****************************************************************************/
165 int dos_mode(int cnum,char *path,struct stat *sbuf)
168 extern struct current_user current_user;
170 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
171 if (!((sbuf->st_mode & S_IWOTH) ||
172 Connections[cnum].admin_user ||
173 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
174 ((sbuf->st_mode & S_IWGRP) &&
175 in_group(sbuf->st_gid,current_user.gid,
176 current_user.ngroups,current_user.igroups))))
179 if ((sbuf->st_mode & S_IWUSR) == 0)
183 if ((sbuf->st_mode & S_IXUSR) != 0)
186 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
189 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
192 if (S_ISDIR(sbuf->st_mode))
193 result = aDIR | (result & aRONLY);
196 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
200 /* hide files with a name starting with a . */
201 if (lp_hide_dot_files(SNUM(cnum)))
203 char *p = strrchr(path,'/');
209 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
217 /*******************************************************************
218 chmod a file - but preserve some bits
219 ********************************************************************/
220 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
229 if (sys_stat(fname,st)) return(-1);
232 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
234 if (dos_mode(cnum,fname,st) == dosmode) return(0);
236 unixmode = unix_mode(cnum,dosmode);
238 /* preserve the s bits */
239 mask |= (S_ISUID | S_ISGID);
241 /* preserve the t bit */
246 /* possibly preserve the x bits */
247 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
248 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
249 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
251 unixmode |= (st->st_mode & mask);
253 /* if we previously had any r bits set then leave them alone */
254 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
255 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
259 /* if we previously had any w bits set then leave them alone
260 if the new mode is not rdonly */
261 if (!IS_DOS_READONLY(dosmode) &&
262 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
263 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
267 return(sys_chmod(fname,unixmode));
271 /****************************************************************************
272 check if two filenames are equal
274 this needs to be careful about whether we are case sensitive
275 ****************************************************************************/
276 static BOOL fname_equal(char *name1, char *name2)
278 int l1 = strlen(name1);
279 int l2 = strlen(name2);
281 /* handle filenames ending in a single dot */
282 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
286 ret = fname_equal(name1,name2);
291 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
295 ret = fname_equal(name1,name2);
300 /* now normal filename handling */
302 return(strcmp(name1,name2) == 0);
304 return(strequal(name1,name2));
308 /****************************************************************************
309 mangle the 2nd name and check if it is then equal to the first name
310 ****************************************************************************/
311 static BOOL mangled_equal(char *name1, char *name2)
315 if (is_8_3(name2, True))
318 strcpy(tmpname,name2);
319 mangle_name_83(tmpname);
321 return(strequal(name1,tmpname));
325 /****************************************************************************
326 scan a directory to find a filename, matching without case sensitivity
328 If the name looks like a mangled name then try via the mangling functions
329 ****************************************************************************/
330 static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
337 mangled = is_mangled(name);
339 /* handle null paths */
343 if (docache && (dname = DirCacheCheck(path,name,snum))) {
349 check_mangled_stack(name);
351 /* open the directory */
352 if (!(cur_dir = OpenDir(path)))
354 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
358 /* now scan for matching names */
359 while ((dname = ReadDirName(cur_dir)))
362 (strequal(dname,".") || strequal(dname,"..")))
366 if (!name_map_mangle(name2,False,snum)) continue;
368 if ((mangled && mangled_equal(name,name2))
369 || fname_equal(name, name2))
371 /* we've found the file, change it's name and return */
372 if (docache) DirCacheAdd(path,name,dname,snum);
383 /****************************************************************************
384 This routine is called to convert names from the dos namespace to unix
385 namespace. It needs to handle any case conversions, mangling, format
388 We assume that we have already done a chdir() to the right "root" directory
391 The function will return False if some part of the name except for the last
392 part cannot be resolved
394 If the saved_last_component != 0, then the unmodified last component
395 of the pathname is returned there. This is used in an exceptional
396 case in reply_mv (so far). If saved_last_component == 0 then nothing
398 ****************************************************************************/
399 BOOL unix_convert(char *name,int cnum,pstring saved_last_component)
406 if(saved_last_component)
407 *saved_last_component = 0;
409 /* convert to basic unix format - removing \ chars and cleaning it up */
411 unix_clean_name(name);
413 /* names must be relative to the root of the service - trim any leading /.
414 also trim trailing /'s */
415 trim_string(name,"/","/");
418 * Ensure saved_last_component is valid even if file exists.
420 if(saved_last_component) {
421 end = strrchr(name, '/');
423 strcpy(saved_last_component, end + 1);
425 strcpy(saved_last_component, name);
428 if (!case_sensitive &&
429 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
432 /* check if it's a printer file */
433 if (Connections[cnum].printer)
435 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
439 sprintf(name2,"%.6s.XXXXXX",remote_machine);
440 /* sanitise the name */
441 for (s=name2 ; *s ; s++)
442 if (!issafe(*s)) *s = '_';
443 strcpy(name,(char *)mktemp(name2));
448 /* stat the name - if it exists then we are all done! */
449 if (sys_stat(name,&st) == 0)
452 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
454 /* a special case - if we don't have any mangling chars and are case
455 sensitive then searching won't help */
456 if (case_sensitive && !is_mangled(name) &&
457 !lp_strip_dot() && !use_mangled_map)
460 /* now we need to recursively match the name against the real
461 directory structure */
464 while (strncmp(start,"./",2) == 0)
467 /* now match each part of the path name separately, trying the names
468 as is first, then trying to scan the directory for matching names */
469 for (;start;start = (end?end+1:(char *)NULL))
471 /* pinpoint the end of this section of the filename */
472 end = strchr(start, '/');
474 /* chop the name at this point */
477 if(saved_last_component != 0)
478 strcpy(saved_last_component, end ? end + 1 : start);
480 /* check if the name exists up to this point */
481 if (sys_stat(name, &st) == 0)
483 /* it exists. it must either be a directory or this must be
484 the last part of the path for it to be OK */
485 if (end && !(st.st_mode & S_IFDIR))
487 /* an intermediate part of the name isn't a directory */
488 DEBUG(5,("Not a dir %s\n",start));
499 /* remember the rest of the pathname so it can be restored
501 if (end) strcpy(rest,end+1);
503 /* try to find this part of the path in the directory */
504 if (strchr(start,'?') || strchr(start,'*') ||
505 !scan_directory(dirpath, start, SNUM(cnum), end?True:False))
509 /* an intermediate part of the name can't be found */
510 DEBUG(5,("Intermediate not found %s\n",start));
515 /* just the last part of the name doesn't exist */
516 /* we may need to strupper() or strlower() it in case
517 this conversion is being used for file creation
519 /* if the filename is of mixed case then don't normalise it */
520 if (!case_preserve &&
521 (!strhasupper(start) || !strhaslower(start)))
524 /* check on the mangled stack to see if we can recover the
525 base of the filename */
526 if (is_mangled(start))
527 check_mangled_stack(start);
529 DEBUG(5,("New file %s\n",start));
533 /* restore the rest of the string */
536 strcpy(start+strlen(start)+1,rest);
537 end = start + strlen(start);
541 /* add to the dirpath that we have resolved so far */
542 if (*dirpath) strcat(dirpath,"/");
543 strcat(dirpath,start);
545 /* restore the / that we wiped out earlier */
549 /* the name has been resolved */
550 DEBUG(5,("conversion finished %s\n",name));
555 /****************************************************************************
556 normalise for DOS usage
557 ****************************************************************************/
558 static void disk_norm(int *bsize,int *dfree,int *dsize)
560 /* check if the disk is beyond the max disk size */
561 int maxdisksize = lp_maxdisksize();
563 /* convert to blocks - and don't overflow */
564 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
565 if (*dsize > maxdisksize) *dsize = maxdisksize;
566 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
571 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
576 if (*bsize > WORDMAX )
579 if (*dsize > WORDMAX)
581 if (*dfree > WORDMAX)
588 /****************************************************************************
589 return number of 1K blocks available on a path and total number
590 ****************************************************************************/
591 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
593 char *df_command = lp_dfree_command();
607 if (disk_quotas(path, bsize, dfree, dsize))
609 disk_norm(bsize,dfree,dsize);
610 return(((*bsize)/1024)*(*dfree));
615 /* possibly use system() to get the result */
616 if (df_command && *df_command)
622 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
623 sprintf(syscmd,"%s %s",df_command,path);
624 standard_sub_basic(syscmd);
626 ret = smbrun(syscmd,outfile,False);
627 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
630 FILE *f = fopen(outfile,"r");
636 fscanf(f,"%d %d %d",dsize,dfree,bsize);
640 DEBUG(0,("Can't open %s\n",outfile));
644 disk_norm(bsize,dfree,dsize);
645 return(((*bsize)/1024)*(*dfree));
649 DEBUG(1,("Warning - no statfs function\n"));
653 if (statfs(path,&fs,sizeof(fs),0) != 0)
656 if (statvfs(path, &fs))
659 if (statfs(path,&fs,sizeof(fs)) == -1)
661 if (statfs(path,&fs) == -1)
663 #endif /* USE_STATVFS */
666 DEBUG(3,("dfree call failed code errno=%d\n",errno));
670 return(((*bsize)/1024)*(*dfree));
675 *dfree = fs.fd_req.bfree;
676 *dsize = fs.fd_req.btot;
679 *bsize = fs.f_frsize;
682 /* eg: osf1 has f_fsize = fundamental filesystem block size,
683 f_bsize = optimal transfer block size (MX: 94-04-19) */
688 #endif /* USE_STATVFS */
693 *dfree = fs.f_bavail;
695 *dsize = fs.f_blocks;
698 #if defined(SCO) || defined(ISC) || defined(MIPS)
702 /* handle rediculous bsize values - some OSes are broken */
703 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
705 disk_norm(bsize,dfree,dsize);
711 DEBUG(0,("dfree seems to be broken on your system\n"));
712 *dsize = 20*1024*1024/(*bsize);
713 *dfree = MAX(1,*dfree);
715 return(((*bsize)/1024)*(*dfree));
720 /****************************************************************************
721 wrap it to get filenames right
722 ****************************************************************************/
723 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
725 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
730 /****************************************************************************
731 check a filename - possibly caling reducename
733 This is called by every routine before it allows an operation on a filename.
734 It does any final confirmation necessary to ensure that the filename is
735 a valid one for the user to access.
736 ****************************************************************************/
737 BOOL check_name(char *name,int cnum)
743 if( is_vetoed_path(name))
745 DEBUG(5,("file path name %s vetoed\n",name));
749 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
751 DEBUG(5,("check_name on %s failed\n",name));
756 /****************************************************************************
757 check a filename - possibly caling reducename
758 ****************************************************************************/
759 static void check_for_pipe(char *fname)
761 /* special case of pipe opens */
765 if (strstr(s,"pipe/"))
767 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
768 unix_ERR_class = ERRSRV;
769 unix_ERR_code = ERRaccess;
773 /****************************************************************************
774 fd support routines - attempt to do a sys_open
775 ****************************************************************************/
777 int fd_attempt_open(char *fname, int flags, int mode)
779 int fd = sys_open(fname,flags,mode);
781 /* Fix for files ending in '.' */
782 if((fd == -1) && (errno == ENOENT) &&
783 (strchr(fname,'.')==NULL))
786 fd = sys_open(fname,flags,mode);
789 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
790 if ((fd == -1) && (errno == ENAMETOOLONG))
793 char *p = strrchr(fname, '/');
795 if (p == fname) /* name is "/xxx" */
797 max_len = pathconf("/", _PC_NAME_MAX);
800 else if ((p == NULL) || (p == fname))
803 max_len = pathconf(".", _PC_NAME_MAX);
808 max_len = pathconf(fname, _PC_NAME_MAX);
812 if (strlen(p) > max_len)
814 char tmp = p[max_len];
817 if ((fd = sys_open(fname,flags,mode)) == -1)
825 /****************************************************************************
826 fd support routines - attempt to find an already open file by dev
827 and inode - increments the ref_count of the returned file_fd_struct *.
828 ****************************************************************************/
829 file_fd_struct *fd_get_already_open(struct stat *sbuf)
832 file_fd_struct *fd_ptr;
837 for(i = 0; i <= max_file_fd_used; i++) {
839 if((fd_ptr->ref_count > 0) &&
840 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
841 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
844 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
845 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
852 /****************************************************************************
853 fd support routines - attempt to find a empty slot in the FileFd array.
854 Increments the ref_count of the returned entry.
855 ****************************************************************************/
856 file_fd_struct *fd_get_new()
859 file_fd_struct *fd_ptr;
861 for(i = 0; i < MAX_OPEN_FILES; i++) {
863 if(fd_ptr->ref_count == 0) {
864 fd_ptr->dev = (uint32)-1;
865 fd_ptr->inode = (uint32)-1;
867 fd_ptr->fd_readonly = -1;
868 fd_ptr->fd_writeonly = -1;
869 fd_ptr->real_open_flags = -1;
871 /* Increment max used counter if neccessary, cuts down
872 on search time when re-using */
873 if(i > max_file_fd_used)
874 max_file_fd_used = i;
875 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
876 i, fd_ptr->dev, fd_ptr->inode));
880 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
885 /****************************************************************************
886 fd support routines - attempt to re-open an already open fd as O_RDWR.
887 Save the already open fd (we cannot close due to POSIX file locking braindamage.
888 ****************************************************************************/
890 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
892 int fd = sys_open( fname, O_RDWR, mode);
897 if(fd_ptr->real_open_flags == O_RDONLY)
898 fd_ptr->fd_readonly = fd_ptr->fd;
899 if(fd_ptr->real_open_flags == O_WRONLY)
900 fd_ptr->fd_writeonly = fd_ptr->fd;
903 fd_ptr->real_open_flags = O_RDWR;
906 /****************************************************************************
907 fd support routines - attempt to close the file referenced by this fd.
908 Decrements the ref_count and returns it.
909 ****************************************************************************/
910 int fd_attempt_close(file_fd_struct *fd_ptr)
912 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
914 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
915 fd_ptr->real_open_flags,
917 if(fd_ptr->ref_count > 0) {
919 if(fd_ptr->ref_count == 0) {
922 if(fd_ptr->fd_readonly != -1)
923 close(fd_ptr->fd_readonly);
924 if(fd_ptr->fd_writeonly != -1)
925 close(fd_ptr->fd_writeonly);
927 fd_ptr->fd_readonly = -1;
928 fd_ptr->fd_writeonly = -1;
929 fd_ptr->real_open_flags = -1;
930 fd_ptr->dev = (uint32)-1;
931 fd_ptr->inode = (uint32)-1;
934 return fd_ptr->ref_count;
937 /****************************************************************************
939 ****************************************************************************/
940 void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
942 extern struct current_user current_user;
945 file_fd_struct *fd_ptr;
947 Files[fnum].open = False;
948 Files[fnum].fd_ptr = 0;
951 strcpy(fname,fname1);
953 /* check permissions */
954 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
956 DEBUG(3,("Permission denied opening %s\n",fname));
957 check_for_pipe(fname);
961 /* this handles a bug in Win95 - it doesn't say to create the file when it
963 if (Connections[cnum].printer)
967 if (flags == O_WRONLY)
968 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
972 /* XXXX - is this OK?? */
973 /* this works around a utime bug but can cause other problems */
974 if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
979 * Ensure we have a valid struct stat so we can search the
983 if(stat(fname, &statbuf) < 0) {
984 if(errno != ENOENT) {
985 DEBUG(3,("Error doing stat on file %s (%s)\n",
986 fname,strerror(errno)));
988 check_for_pipe(fname);
998 * Check to see if we have this file already
999 * open. If we do, just use the already open fd and increment the
1000 * reference count (fd_get_already_open increments the ref_count).
1002 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1004 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1006 /* File was already open. */
1007 if((flags & O_CREAT) && (flags & O_EXCL)) {
1008 fd_ptr->ref_count--;
1014 * If not opened O_RDWR try
1015 * and do that here - a chmod may have been done
1016 * between the last open and now.
1018 if(fd_ptr->real_open_flags != O_RDWR)
1019 fd_attempt_reopen(fname, mode, fd_ptr);
1022 * Ensure that if we wanted write access
1023 * it has been opened for write, and if we wanted read it
1024 * was open for read.
1026 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1027 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1028 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1029 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1030 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1031 check_for_pipe(fname);
1032 fd_ptr->ref_count--;
1037 * If O_TRUNC was set, ensure we truncate the file.
1038 * open_file_shared explicitly clears this flag before
1039 * calling open_file, so we can safely do this here.
1042 ftruncate(fd_ptr->fd, 0);
1046 /* We need to allocate a new file_fd_struct (this increments the
1048 if((fd_ptr = fd_get_new()) == 0)
1051 * Whatever the requested flags, attempt read/write access,
1052 * as we don't know what flags future file opens may require.
1053 * If this fails, try again with the required flags.
1054 * Even if we open read/write when only read access was
1055 * requested the setting of the can_write flag in
1056 * the file_struct will protect us from errant
1057 * write requests. We never need to worry about O_APPEND
1058 * as this is not set anywhere in Samba.
1060 fd_ptr->real_open_flags = O_RDWR;
1061 /* Set the flags as needed without the read/write modes. */
1062 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1063 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1065 * On some systems opening a file for R/W access on a read only
1066 * filesystems sets errno to EROFS.
1069 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1070 #else /* No EROFS */
1071 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1073 if(flags & O_WRONLY) {
1074 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1075 fd_ptr->real_open_flags = O_WRONLY;
1077 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1078 fd_ptr->real_open_flags = O_RDONLY;
1083 if ((fd_ptr->fd >=0) &&
1084 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1088 strcpy(dname,fname);
1089 p = strrchr(dname,'/');
1091 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1092 lp_minprintspace(SNUM(cnum))) {
1093 fd_attempt_close(fd_ptr);
1094 Files[fnum].fd_ptr = 0;
1095 if(fd_ptr->ref_count == 0)
1104 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1105 fname,strerror(errno),flags));
1106 /* Ensure the ref_count is decremented. */
1107 fd_attempt_close(fd_ptr);
1108 check_for_pipe(fname);
1112 if (fd_ptr->fd >= 0)
1116 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1117 /* Error - backout !! */
1118 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1119 fd_ptr->fd, fname,strerror(errno)));
1120 /* Ensure the ref_count is decremented. */
1121 fd_attempt_close(fd_ptr);
1126 /* Set the correct entries in fd_ptr. */
1127 fd_ptr->dev = (uint32)sbuf->st_dev;
1128 fd_ptr->inode = (uint32)sbuf->st_ino;
1130 Files[fnum].fd_ptr = fd_ptr;
1131 Connections[cnum].num_files_open++;
1132 Files[fnum].mode = sbuf->st_mode;
1133 GetTimeOfDay(&Files[fnum].open_time);
1134 Files[fnum].uid = current_user.id;
1135 Files[fnum].size = 0;
1136 Files[fnum].pos = -1;
1137 Files[fnum].open = True;
1138 Files[fnum].mmap_ptr = NULL;
1139 Files[fnum].mmap_size = 0;
1140 Files[fnum].can_lock = True;
1141 Files[fnum].can_read = ((flags & O_WRONLY)==0);
1142 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1143 Files[fnum].share_mode = 0;
1144 Files[fnum].print_file = Connections[cnum].printer;
1145 Files[fnum].modified = False;
1146 Files[fnum].cnum = cnum;
1147 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1148 Files[fnum].wbmpx_ptr = NULL;
1151 * If the printer is marked as postscript output a leading
1152 * file identifier to ensure the file is treated as a raw
1154 * This has a similar effect as CtrlD=0 in WIN.INI file.
1155 * tim@fsg.com 09/06/94
1157 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1158 Files[fnum].can_write)
1160 DEBUG(3,("Writing postscript line\n"));
1161 write_file(fnum,"%!\n",3);
1164 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1165 timestring(),Connections[cnum].user,fname,
1166 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1167 Connections[cnum].num_files_open,fnum));
1172 /* mmap it if read-only */
1173 if (!Files[fnum].can_write)
1175 Files[fnum].mmap_size = file_size(fname);
1176 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1177 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1179 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1181 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1182 Files[fnum].mmap_ptr = NULL;
1188 /*******************************************************************
1190 ********************************************************************/
1191 void sync_file(int fnum)
1194 fsync(Files[fnum].fd_ptr->fd);
1198 /****************************************************************************
1199 run a file if it is a magic script
1200 ****************************************************************************/
1201 static void check_magic(int fnum,int cnum)
1203 if (!*lp_magicscript(SNUM(cnum)))
1206 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1210 if (!(p = strrchr(Files[fnum].name,'/')))
1211 p = Files[fnum].name;
1215 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1221 pstring magic_output;
1223 strcpy(fname,Files[fnum].name);
1225 if (*lp_magicoutput(SNUM(cnum)))
1226 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1228 sprintf(magic_output,"%s.out",fname);
1231 ret = smbrun(fname,magic_output,False);
1232 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1238 /****************************************************************************
1239 close a file - possibly invalidating the read prediction
1240 ****************************************************************************/
1241 void close_file(int fnum)
1243 files_struct *fs_p = &Files[fnum];
1244 int cnum = fs_p->cnum;
1245 uint32 dev = fs_p->fd_ptr->dev;
1246 uint32 inode = fs_p->fd_ptr->inode;
1247 share_lock_token token;
1249 invalidate_read_prediction(fs_p->fd_ptr->fd);
1251 Connections[cnum].num_files_open--;
1254 free((char *)fs_p->wbmpx_ptr);
1255 fs_p->wbmpx_ptr = NULL;
1261 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1262 fs_p->mmap_ptr = NULL;
1266 if (lp_share_modes(SNUM(cnum)))
1268 lock_share_entry( cnum, dev, inode, &token);
1269 del_share_mode(token, fnum);
1272 fd_attempt_close(fs_p->fd_ptr);
1274 if (lp_share_modes(SNUM(cnum)))
1275 unlock_share_entry( cnum, dev, inode, token);
1277 /* NT uses smbclose to start a print - weird */
1278 if (fs_p->print_file)
1281 /* check for magic scripts */
1282 check_magic(fnum,cnum);
1284 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1285 timestring(),Connections[cnum].user,fs_p->name,
1286 Connections[cnum].num_files_open));
1289 enum {AFAIL,AREAD,AWRITE,AALL};
1291 /*******************************************************************
1292 reproduce the share mode access table
1293 ********************************************************************/
1294 static int access_table(int new_deny,int old_deny,int old_mode,
1295 int share_pid,char *fname)
1297 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1299 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1300 if (old_deny == new_deny && share_pid == getpid())
1303 if (old_mode == 0) return(AREAD);
1305 /* the new smbpub.zip spec says that if the file extension is
1306 .com, .dll, .exe or .sym then allow the open. I will force
1307 it to read-only as this seems sensible although the spec is
1308 a little unclear on this. */
1309 if ((fname = strrchr(fname,'.'))) {
1310 if (strequal(fname,".com") ||
1311 strequal(fname,".dll") ||
1312 strequal(fname,".exe") ||
1313 strequal(fname,".sym"))
1323 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1324 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1325 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1328 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1329 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1330 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1333 if (old_deny==DENY_WRITE) return(AREAD);
1334 if (old_deny==DENY_READ) return(AWRITE);
1335 if (old_deny==DENY_NONE) return(AALL);
1341 /*******************************************************************
1342 check if the share mode on a file allows it to be deleted or unlinked
1343 return True if sharing doesn't prevent the operation
1344 ********************************************************************/
1345 BOOL check_file_sharing(int cnum,char *fname)
1349 min_share_mode_entry *old_shares = 0;
1350 int num_share_modes;
1352 share_lock_token token;
1355 if(!lp_share_modes(SNUM(cnum)))
1358 if (stat(fname,&sbuf) == -1) return(True);
1360 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1361 num_share_modes = get_share_modes(cnum, token,
1362 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1364 for( i = 0; i < num_share_modes; i++)
1366 if (old_shares[i].share_mode != DENY_DOS)
1369 if(old_shares[i].pid != pid);
1373 /* XXXX exactly what share mode combinations should be allowed for
1374 deleting/renaming? */
1375 /* If we got here then either there were no share modes or
1376 all share modes were DENY_DOS and the pid == getpid() */
1381 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1382 if(old_shares != NULL)
1383 free((char *)old_shares);
1387 /****************************************************************************
1389 Helper for open_file_shared.
1390 Truncate a file after checking locking; close file if locked.
1391 **************************************************************************/
1392 static void truncate_unless_locked(int fnum, int cnum)
1394 if (Files[fnum].can_write){
1395 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1398 unix_ERR_class = ERRDOS;
1399 unix_ERR_code = ERRlock;
1402 ftruncate(Files[fnum].fd_ptr->fd,0);
1407 /****************************************************************************
1408 open a file with a share mode
1409 ****************************************************************************/
1410 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1411 int mode,int *Access,int *action)
1413 files_struct *fs_p = &Files[fnum];
1416 int deny_mode = (share_mode>>4)&7;
1418 BOOL file_existed = file_exist(fname,&sbuf);
1419 BOOL share_locked = False;
1420 BOOL fcbopen = False;
1421 share_lock_token token;
1428 /* this is for OS/2 EAs - try and say we don't support them */
1429 if (strstr(fname,".+,;=[]."))
1431 unix_ERR_class = ERRDOS;
1432 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1436 if ((ofun & 0x3) == 0 && file_existed)
1444 if ((ofun & 0x3) == 2)
1447 /* note that we ignore the append flag as
1448 append does not mean the same thing under dos and unix */
1450 switch (share_mode&0xF)
1467 if (flags != O_RDONLY && file_existed &&
1468 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1478 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1480 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1485 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1487 if (lp_share_modes(SNUM(cnum)))
1491 min_share_mode_entry *old_shares = 0;
1496 dev = (uint32)sbuf.st_dev;
1497 inode = (uint32)sbuf.st_ino;
1498 lock_share_entry(cnum, dev, inode, &token);
1499 share_locked = True;
1500 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1503 for(i = 0; i < num_shares; i++)
1505 /* someone else has a share lock on it, check to see
1507 int old_open_mode = old_shares[i].share_mode &0xF;
1508 int old_deny_mode = (old_shares[i].share_mode >>4)&7;
1510 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2)
1512 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1513 deny_mode,old_deny_mode,old_open_mode,fname));
1514 free((char *)old_shares);
1516 unlock_share_entry(cnum, dev, inode, token);
1518 unix_ERR_class = ERRDOS;
1519 unix_ERR_code = ERRbadshare;
1524 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1525 old_shares[i].pid,fname);
1527 if ((access_allowed == AFAIL) ||
1528 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1529 (access_allowed == AREAD && flags == O_WRONLY) ||
1530 (access_allowed == AWRITE && flags == O_RDONLY))
1532 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1533 deny_mode,old_deny_mode,old_open_mode,
1534 old_shares[i].pid,fname,
1536 free((char *)old_shares);
1538 unlock_share_entry(cnum, dev, inode, token);
1540 unix_ERR_class = ERRDOS;
1541 unix_ERR_code = ERRbadshare;
1545 if (access_allowed == AREAD)
1548 if (access_allowed == AWRITE)
1553 free((char *)old_shares);
1556 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1557 flags,flags2,mode));
1559 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1560 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1563 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1570 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1572 /* We created the file - thus we must now lock the share entry before creating it. */
1573 dev = fs_p->fd_ptr->dev;
1574 inode = fs_p->fd_ptr->inode;
1575 lock_share_entry(cnum, dev, inode, &token);
1576 share_locked = True;
1592 fs_p->share_mode = (deny_mode<<4) | open_mode;
1595 (*Access) = open_mode;
1599 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1600 if (!file_existed) *action = 2;
1601 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1604 if ((flags2&O_TRUNC) && file_existed)
1605 truncate_unless_locked(fnum,cnum);
1607 if (lp_share_modes(SNUM(cnum)))
1608 set_share_mode(token, fnum);
1611 if (share_locked && lp_share_modes(SNUM(cnum)))
1612 unlock_share_entry( cnum, dev, inode, token);
1615 /****************************************************************************
1616 seek a file. Try to avoid the seek if possible
1617 ****************************************************************************/
1618 int seek_file(int fnum,int pos)
1621 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1624 Files[fnum].pos = lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) - offset;
1625 return(Files[fnum].pos);
1628 /****************************************************************************
1630 ****************************************************************************/
1631 int read_file(int fnum,char *data,int pos,int n)
1635 if (!Files[fnum].can_write)
1637 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1645 if (Files[fnum].mmap_ptr)
1647 int num = MIN(n,Files[fnum].mmap_size-pos);
1650 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1662 if (seek_file(fnum,pos) != pos)
1664 DEBUG(3,("Failed to seek to %d\n",pos));
1669 readret = read(Files[fnum].fd_ptr->fd,data,n);
1670 if (readret > 0) ret += readret;
1677 /****************************************************************************
1679 ****************************************************************************/
1680 int write_file(int fnum,char *data,int n)
1682 if (!Files[fnum].can_write) {
1687 if (!Files[fnum].modified) {
1689 Files[fnum].modified = True;
1690 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1691 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1692 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1693 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1698 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1702 /****************************************************************************
1703 load parameters specific to a connection/service
1704 ****************************************************************************/
1705 BOOL become_service(int cnum,BOOL do_chdir)
1707 extern char magic_char;
1708 static int last_cnum = -1;
1711 if (!OPEN_CNUM(cnum))
1717 Connections[cnum].lastused = smb_last_time;
1722 ChDir(Connections[cnum].connectpath) != 0 &&
1723 ChDir(Connections[cnum].origpath) != 0)
1725 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1726 Connections[cnum].connectpath,cnum));
1730 if (cnum == last_cnum)
1735 case_default = lp_defaultcase(snum);
1736 case_preserve = lp_preservecase(snum);
1737 short_case_preserve = lp_shortpreservecase(snum);
1738 case_mangle = lp_casemangle(snum);
1739 case_sensitive = lp_casesensitive(snum);
1740 magic_char = lp_magicchar(snum);
1741 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1746 /****************************************************************************
1747 find a service entry
1748 ****************************************************************************/
1749 int find_service(char *service)
1753 string_sub(service,"\\","/");
1755 iService = lp_servicenumber(service);
1757 /* now handle the special case of a home directory */
1760 char *phome_dir = get_home_dir(service);
1761 DEBUG(3,("checking for home directory %s gave %s\n",service,
1762 phome_dir?phome_dir:"(NULL)"));
1766 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1768 lp_add_home(service,iHomeService,phome_dir);
1769 iService = lp_servicenumber(service);
1774 /* If we still don't have a service, attempt to add it as a printer. */
1777 int iPrinterService;
1779 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1783 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1785 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1787 DEBUG(3,("%s is a valid printer name\n", service));
1788 DEBUG(3,("adding %s as a printer service\n", service));
1789 lp_add_printer(service,iPrinterService);
1790 iService = lp_servicenumber(service);
1792 DEBUG(0,("failed to add %s as a printer service!\n", service));
1795 DEBUG(3,("%s is not a valid printer name\n", service));
1799 /* just possibly it's a default service? */
1802 char *defservice = lp_defaultservice();
1803 if (defservice && *defservice && !strequal(defservice,service)) {
1804 iService = find_service(defservice);
1805 if (iService >= 0) {
1806 string_sub(service,"_","/");
1807 iService = lp_add_service(service,iService);
1813 if (!VALID_SNUM(iService))
1815 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1820 DEBUG(3,("find_service() failed to find service %s\n", service));
1826 /****************************************************************************
1827 create an error packet from a cached error.
1828 ****************************************************************************/
1829 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1831 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1833 int32 eclass = wbmpx->wr_errclass;
1834 int32 err = wbmpx->wr_error;
1836 /* We can now delete the auxiliary struct */
1837 free((char *)wbmpx);
1838 Files[fnum].wbmpx_ptr = NULL;
1839 return error_packet(inbuf,outbuf,eclass,err,line);
1848 } unix_smb_errmap[] =
1850 {EPERM,ERRDOS,ERRnoaccess},
1851 {EACCES,ERRDOS,ERRnoaccess},
1852 {ENOENT,ERRDOS,ERRbadfile},
1853 {EIO,ERRHRD,ERRgeneral},
1854 {EBADF,ERRSRV,ERRsrverror},
1855 {EINVAL,ERRSRV,ERRsrverror},
1856 {EEXIST,ERRDOS,ERRfilexists},
1857 {ENFILE,ERRDOS,ERRnofids},
1858 {EMFILE,ERRDOS,ERRnofids},
1859 {ENOSPC,ERRHRD,ERRdiskfull},
1861 {EDQUOT,ERRHRD,ERRdiskfull},
1864 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1867 {EXDEV,ERRDOS,ERRdiffdevice},
1869 {EROFS,ERRHRD,ERRnowrite},
1874 /****************************************************************************
1875 create an error packet from errno
1876 ****************************************************************************/
1877 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1879 int eclass=def_class;
1883 if (unix_ERR_class != SUCCESS)
1885 eclass = unix_ERR_class;
1886 ecode = unix_ERR_code;
1887 unix_ERR_class = SUCCESS;
1892 while (unix_smb_errmap[i].smbclass != 0)
1894 if (unix_smb_errmap[i].unixerror == errno)
1896 eclass = unix_smb_errmap[i].smbclass;
1897 ecode = unix_smb_errmap[i].smbcode;
1904 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1908 /****************************************************************************
1909 create an error packet. Normally called using the ERROR() macro
1910 ****************************************************************************/
1911 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1913 int outsize = set_message(outbuf,0,0,True);
1915 cmd = CVAL(inbuf,smb_com);
1917 CVAL(outbuf,smb_rcls) = error_class;
1918 SSVAL(outbuf,smb_err,error_code);
1920 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1923 (int)CVAL(inbuf,smb_com),
1924 smb_fn_name(CVAL(inbuf,smb_com)),
1929 DEBUG(3,("error string = %s\n",strerror(errno)));
1935 #ifndef SIGCLD_IGNORE
1936 /****************************************************************************
1937 this prevents zombie child processes
1938 ****************************************************************************/
1939 static int sig_cld()
1941 static int depth = 0;
1944 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1950 BlockSignals(True,SIGCLD);
1951 DEBUG(5,("got SIGCLD\n"));
1954 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1958 /* Stevens, Adv. Unix Prog. says that on system V you must call
1959 wait before reinstalling the signal handler, because the kernel
1960 calls the handler from within the signal-call when there is a
1961 child that has exited. This would lead to an infinite recursion
1962 if done vice versa. */
1964 #ifndef DONT_REINSTALL_SIG
1965 #ifdef SIGCLD_IGNORE
1966 signal(SIGCLD, SIG_IGN);
1968 signal(SIGCLD, SIGNAL_CAST sig_cld);
1973 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1976 BlockSignals(False,SIGCLD);
1981 /****************************************************************************
1982 this is called when the client exits abruptly
1983 **************************************************************************/
1984 static int sig_pipe()
1986 extern int password_client;
1987 BlockSignals(True,SIGPIPE);
1989 if (password_client != -1) {
1990 DEBUG(3,("lost connection to password server\n"));
1991 close(password_client);
1992 password_client = -1;
1993 #ifndef DONT_REINSTALL_SIG
1994 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1996 BlockSignals(False,SIGPIPE);
2000 exit_server("Got sigpipe\n");
2004 /****************************************************************************
2005 open the socket communication
2006 ****************************************************************************/
2007 static BOOL open_sockets(BOOL is_daemon,int port)
2014 struct sockaddr addr;
2015 int in_addrlen = sizeof(addr);
2018 #ifdef SIGCLD_IGNORE
2019 signal(SIGCLD, SIG_IGN);
2021 signal(SIGCLD, SIGNAL_CAST sig_cld);
2024 /* open an incoming socket */
2025 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2029 /* ready to listen */
2030 if (listen(s, 5) == -1)
2032 DEBUG(0,("listen: %s",strerror(errno)));
2040 /* now accept incoming connections - forking a new process
2041 for each incoming connection */
2042 DEBUG(2,("waiting for a connection\n"));
2045 Client = accept(s,&addr,&in_addrlen);
2047 if (Client == -1 && errno == EINTR)
2052 DEBUG(0,("accept: %s",strerror(errno)));
2056 #ifdef NO_FORK_DEBUG
2057 #ifndef NO_SIGNAL_TEST
2058 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2059 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2063 if (Client != -1 && fork()==0)
2065 #ifndef NO_SIGNAL_TEST
2066 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2067 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2069 /* close the listening socket */
2072 /* close our standard file descriptors */
2076 set_socket_options(Client,"SO_KEEPALIVE");
2077 set_socket_options(Client,user_socket_options);
2081 close(Client); /* The parent doesn't need this socket */
2087 /* We will abort gracefully when the client or remote system
2089 #ifndef NO_SIGNAL_TEST
2090 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2094 /* close our standard file descriptors */
2097 set_socket_options(Client,"SO_KEEPALIVE");
2098 set_socket_options(Client,user_socket_options);
2105 /****************************************************************************
2106 check if a snum is in use
2107 ****************************************************************************/
2108 BOOL snum_used(int snum)
2111 for (i=0;i<MAX_CONNECTIONS;i++)
2112 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2117 /****************************************************************************
2118 reload the services file
2119 **************************************************************************/
2120 BOOL reload_services(BOOL test)
2127 strcpy(fname,lp_configfile());
2128 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2130 strcpy(servicesf,fname);
2137 if (test && !lp_file_list_changed())
2140 lp_killunused(snum_used);
2142 ret = lp_load(servicesf,False);
2144 /* perhaps the config filename is now set */
2146 reload_services(True);
2155 set_socket_options(Client,"SO_KEEPALIVE");
2156 set_socket_options(Client,user_socket_options);
2160 create_mangled_stack(lp_mangledstack());
2162 /* this forces service parameters to be flushed */
2163 become_service(-1,True);
2170 /****************************************************************************
2171 this prevents zombie child processes
2172 ****************************************************************************/
2173 static int sig_hup()
2175 BlockSignals(True,SIGHUP);
2176 DEBUG(0,("Got SIGHUP\n"));
2177 reload_services(False);
2178 #ifndef DONT_REINSTALL_SIG
2179 signal(SIGHUP,SIGNAL_CAST sig_hup);
2181 BlockSignals(False,SIGHUP);
2185 /****************************************************************************
2186 Setup the groups a user belongs to.
2187 ****************************************************************************/
2188 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2189 int **p_igroups, gid_t **p_groups)
2191 if (-1 == initgroups(user,gid))
2195 DEBUG(0,("Unable to initgroups!\n"));
2196 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2197 DEBUG(0,("This is probably a problem with the account %s\n",user));
2205 ngroups = getgroups(0,&grp);
2208 igroups = (int *)malloc(sizeof(int)*ngroups);
2209 for (i=0;i<ngroups;i++)
2210 igroups[i] = 0x42424242;
2211 ngroups = getgroups(ngroups,(gid_t *)igroups);
2213 if (igroups[0] == 0x42424242)
2216 *p_ngroups = ngroups;
2218 /* The following bit of code is very strange. It is due to the
2219 fact that some OSes use int* and some use gid_t* for
2220 getgroups, and some (like SunOS) use both, one in prototypes,
2221 and one in man pages and the actual code. Thus we detect it
2222 dynamically using some very ugly code */
2225 /* does getgroups return ints or gid_t ?? */
2226 static BOOL groups_use_ints = True;
2228 if (groups_use_ints &&
2230 SVAL(igroups,2) == 0x4242)
2231 groups_use_ints = False;
2233 for (i=0;groups_use_ints && i<ngroups;i++)
2234 if (igroups[i] == 0x42424242)
2235 groups_use_ints = False;
2237 if (groups_use_ints)
2239 *p_igroups = igroups;
2240 *p_groups = (gid_t *)igroups;
2244 gid_t *groups = (gid_t *)igroups;
2245 igroups = (int *)malloc(sizeof(int)*ngroups);
2246 for (i=0;i<ngroups;i++)
2247 igroups[i] = groups[i];
2248 *p_igroups = igroups;
2249 *p_groups = (gid_t *)groups;
2252 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2253 for (i=0;i<ngroups;i++)
2254 DEBUG(3,("%d ",igroups[i]));
2260 /****************************************************************************
2261 make a connection to a service
2262 ****************************************************************************/
2263 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2267 struct passwd *pass = NULL;
2268 connection_struct *pcon;
2271 static BOOL first_connection = True;
2275 snum = find_service(service);
2278 if (strequal(service,"IPC$"))
2280 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2284 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2288 if (strequal(service,HOMES_NAME))
2290 if (*user && Get_Pwnam(user,True))
2291 return(make_connection(user,user,password,pwlen,dev,vuid));
2293 if (validated_username(vuid))
2295 strcpy(user,validated_username(vuid));
2296 return(make_connection(user,user,password,pwlen,dev,vuid));
2300 if (!lp_snum_ok(snum) || !check_access(snum)) {
2304 /* you can only connect to the IPC$ service as an ipc device */
2305 if (strequal(service,"IPC$"))
2308 if (*dev == '?' || !*dev)
2310 if (lp_print_ok(snum))
2311 strcpy(dev,"LPT1:");
2316 /* if the request is as a printer and you can't print then refuse */
2318 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2319 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2323 /* lowercase the user name */
2326 /* add it as a possible user name */
2327 add_session_user(service);
2329 /* shall we let them in? */
2330 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2332 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2336 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2339 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2343 pcon = &Connections[cnum];
2344 bzero((char *)pcon,sizeof(*pcon));
2346 /* find out some info about the user */
2347 pass = Get_Pwnam(user,True);
2351 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2355 pcon->read_only = lp_readonly(snum);
2359 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2360 string_sub(list,"%S",service);
2362 if (user_in_list(user,list))
2363 pcon->read_only = True;
2365 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2366 string_sub(list,"%S",service);
2368 if (user_in_list(user,list))
2369 pcon->read_only = False;
2372 /* admin user check */
2373 if (user_in_list(user,lp_admin_users(snum)) &&
2376 pcon->admin_user = True;
2377 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2380 pcon->admin_user = False;
2382 pcon->force_user = force;
2384 pcon->uid = pass->pw_uid;
2385 pcon->gid = pass->pw_gid;
2386 pcon->num_files_open = 0;
2387 pcon->lastused = time(NULL);
2388 pcon->service = snum;
2390 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2391 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2392 pcon->dirptr = NULL;
2393 string_set(&pcon->dirpath,"");
2394 string_set(&pcon->user,user);
2397 if (*lp_force_group(snum))
2402 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2403 /* default service may be a group name */
2404 string_sub(gname,"%S",service);
2405 gptr = (struct group *)getgrnam(gname);
2409 pcon->gid = gptr->gr_gid;
2410 DEBUG(3,("Forced group %s\n",gname));
2413 DEBUG(1,("Couldn't find group %s\n",gname));
2417 if (*lp_force_user(snum))
2419 struct passwd *pass2;
2421 strcpy(fuser,lp_force_user(snum));
2422 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2425 pcon->uid = pass2->pw_uid;
2426 string_set(&pcon->user,fuser);
2428 pcon->force_user = True;
2429 DEBUG(3,("Forced user %s\n",fuser));
2432 DEBUG(1,("Couldn't find user %s\n",fuser));
2437 strcpy(s,lp_pathname(snum));
2438 standard_sub(cnum,s);
2439 string_set(&pcon->connectpath,s);
2440 DEBUG(3,("Connect path is %s\n",s));
2443 /* groups stuff added by ih */
2445 pcon->groups = NULL;
2449 /* Find all the groups this uid is in and store them. Used by become_user() */
2450 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2452 /* check number of connections */
2453 if (!claim_connection(cnum,
2454 lp_servicename(SNUM(cnum)),
2455 lp_max_connections(SNUM(cnum)),False))
2457 DEBUG(1,("too many connections - rejected\n"));
2461 if (lp_status(SNUM(cnum)))
2462 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2464 first_connection = False;
2469 /* execute any "root preexec = " line */
2470 if (*lp_rootpreexec(SNUM(cnum)))
2473 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2474 standard_sub(cnum,cmd);
2475 DEBUG(5,("cmd=%s\n",cmd));
2476 smbrun(cmd,NULL,False);
2479 if (!become_user(cnum,pcon->vuid))
2481 DEBUG(0,("Can't become connected user!\n"));
2483 if (!IS_IPC(cnum)) {
2484 yield_connection(cnum,
2485 lp_servicename(SNUM(cnum)),
2486 lp_max_connections(SNUM(cnum)));
2487 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2492 if (ChDir(pcon->connectpath) != 0)
2494 DEBUG(0,("Can't change directory to %s (%s)\n",
2495 pcon->connectpath,strerror(errno)));
2498 if (!IS_IPC(cnum)) {
2499 yield_connection(cnum,
2500 lp_servicename(SNUM(cnum)),
2501 lp_max_connections(SNUM(cnum)));
2502 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2507 string_set(&pcon->origpath,pcon->connectpath);
2509 #if SOFTLINK_OPTIMISATION
2510 /* resolve any soft links early */
2513 strcpy(s,pcon->connectpath);
2515 string_set(&pcon->connectpath,s);
2516 ChDir(pcon->connectpath);
2520 num_connections_open++;
2521 add_session_user(user);
2523 /* execute any "preexec = " line */
2524 if (*lp_preexec(SNUM(cnum)))
2527 strcpy(cmd,lp_preexec(SNUM(cnum)));
2528 standard_sub(cnum,cmd);
2529 smbrun(cmd,NULL,False);
2532 /* we've finished with the sensitive stuff */
2536 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2540 lp_servicename(SNUM(cnum)),user,
2550 /****************************************************************************
2551 find first available file slot
2552 ****************************************************************************/
2553 int find_free_file(void )
2556 /* we start at 1 here for an obscure reason I can't now remember,
2557 but I think is important :-) */
2558 for (i=1;i<MAX_OPEN_FILES;i++)
2561 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2565 /****************************************************************************
2566 find first available connection slot, starting from a random position.
2567 The randomisation stops problems with the server dieing and clients
2568 thinking the server is still available.
2569 ****************************************************************************/
2570 static int find_free_connection(int hash )
2574 hash = (hash % (MAX_CONNECTIONS-2))+1;
2578 for (i=hash+1;i!=hash;)
2580 if (!Connections[i].open && Connections[i].used == used)
2582 DEBUG(3,("found free connection number %d\n",i));
2586 if (i == MAX_CONNECTIONS)
2596 DEBUG(1,("ERROR! Out of connection structures\n"));
2601 /****************************************************************************
2602 reply for the core protocol
2603 ****************************************************************************/
2604 int reply_corep(char *outbuf)
2606 int outsize = set_message(outbuf,1,0,True);
2608 Protocol = PROTOCOL_CORE;
2614 /****************************************************************************
2615 reply for the coreplus protocol
2616 ****************************************************************************/
2617 int reply_coreplus(char *outbuf)
2619 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2620 int outsize = set_message(outbuf,13,0,True);
2621 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2622 readbraw and writebraw (possibly) */
2623 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2624 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2626 Protocol = PROTOCOL_COREPLUS;
2632 /****************************************************************************
2633 reply for the lanman 1.0 protocol
2634 ****************************************************************************/
2635 int reply_lanman1(char *outbuf)
2637 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2639 BOOL doencrypt = SMBENCRYPT();
2640 time_t t = time(NULL);
2642 if (lp_security()>=SEC_USER) secword |= 1;
2643 if (doencrypt) secword |= 2;
2645 set_message(outbuf,13,doencrypt?8:0,True);
2646 SSVAL(outbuf,smb_vwv1,secword);
2648 /* Create a token value and add it to the outgoing packet. */
2650 generate_next_challenge(smb_buf(outbuf));
2653 Protocol = PROTOCOL_LANMAN1;
2655 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2656 DEBUG(3,("using password server validation\n"));
2658 if (doencrypt) set_challenge(smb_buf(outbuf));
2662 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2663 SSVAL(outbuf,smb_vwv2,max_recv);
2664 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2665 SSVAL(outbuf,smb_vwv4,1);
2666 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2667 readbraw writebraw (possibly) */
2668 SIVAL(outbuf,smb_vwv6,getpid());
2669 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2671 put_dos_date(outbuf,smb_vwv8,t);
2673 return (smb_len(outbuf)+4);
2677 /****************************************************************************
2678 reply for the lanman 2.0 protocol
2679 ****************************************************************************/
2680 int reply_lanman2(char *outbuf)
2682 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2684 BOOL doencrypt = SMBENCRYPT();
2685 time_t t = time(NULL);
2687 if (lp_security()>=SEC_USER) secword |= 1;
2688 if (doencrypt) secword |= 2;
2690 set_message(outbuf,13,doencrypt?8:0,True);
2691 SSVAL(outbuf,smb_vwv1,secword);
2693 /* Create a token value and add it to the outgoing packet. */
2695 generate_next_challenge(smb_buf(outbuf));
2698 SIVAL(outbuf,smb_vwv6,getpid());
2700 Protocol = PROTOCOL_LANMAN2;
2702 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2703 DEBUG(3,("using password server validation\n"));
2705 if (doencrypt) set_challenge(smb_buf(outbuf));
2709 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2710 SSVAL(outbuf,smb_vwv2,max_recv);
2711 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2712 SSVAL(outbuf,smb_vwv4,1);
2713 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2714 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2715 put_dos_date(outbuf,smb_vwv8,t);
2717 return (smb_len(outbuf)+4);
2721 /****************************************************************************
2722 reply for the nt protocol
2723 ****************************************************************************/
2724 int reply_nt1(char *outbuf)
2726 /* dual names + lock_and_read + nt SMBs + remote API calls */
2727 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2729 other valid capabilities which we may support at some time...
2730 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2731 CAP_LARGE_FILES|CAP_LARGE_READX|
2732 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2736 BOOL doencrypt = SMBENCRYPT();
2737 time_t t = time(NULL);
2740 char challenge_len = 8;
2742 if (lp_readraw() && lp_writeraw())
2744 capabilities |= CAP_RAW_MODE;
2747 if (lp_security()>=SEC_USER) secword |= 1;
2748 if (doencrypt) secword |= 2;
2750 /* decide where (if) to put the encryption challenge, and
2751 follow it with the OEM'd domain name
2753 encrypt_len = doencrypt?challenge_len:0;
2755 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
2757 data_len = encrypt_len + strlen(myworkgroup) + 1;
2760 set_message(outbuf,17,data_len,True);
2763 /* put the OEM'd domain name */
2764 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
2766 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
2769 CVAL(outbuf,smb_vwv1) = secword;
2771 /* Create a token value and add it to the outgoing packet. */
2774 generate_next_challenge(smb_buf(outbuf));
2776 /* Tell the nt machine how long the challenge is. */
2777 SSVALS(outbuf,smb_vwv16+1,challenge_len);
2781 Protocol = PROTOCOL_NT1;
2783 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2784 DEBUG(3,("using password server validation\n"));
2786 if (doencrypt) set_challenge(smb_buf(outbuf));
2790 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2791 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2792 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
2793 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
2794 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2795 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2796 put_long_date(outbuf+smb_vwv11+1,t);
2797 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2798 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
2800 return (smb_len(outbuf)+4);
2803 /* these are the protocol lists used for auto architecture detection:
2806 protocol [PC NETWORK PROGRAM 1.0]
2807 protocol [XENIX CORE]
2808 protocol [MICROSOFT NETWORKS 1.03]
2809 protocol [LANMAN1.0]
2810 protocol [Windows for Workgroups 3.1a]
2811 protocol [LM1.2X002]
2812 protocol [LANMAN2.1]
2813 protocol [NT LM 0.12]
2816 protocol [PC NETWORK PROGRAM 1.0]
2817 protocol [XENIX CORE]
2818 protocol [MICROSOFT NETWORKS 1.03]
2819 protocol [LANMAN1.0]
2820 protocol [Windows for Workgroups 3.1a]
2821 protocol [LM1.2X002]
2822 protocol [LANMAN2.1]
2823 protocol [NT LM 0.12]
2826 protocol [PC NETWORK PROGRAM 1.0]
2827 protocol [XENIX CORE]
2828 protocol [LANMAN1.0]
2829 protocol [LM1.2X002]
2830 protocol [LANMAN2.1]
2834 * Modified to recognize the architecture of the remote machine better.
2836 * This appears to be the matrix of which protocol is used by which
2838 Protocol WfWg Win95 WinNT OS/2
2839 PC NETWORK PROGRAM 1.0 1 1 1 1
2841 MICROSOFT NETWORKS 3.0 2 2
2843 MICROSOFT NETWORKS 1.03 3
2846 Windows for Workgroups 3.1a 5 5 5
2851 * tim@fsg.com 09/29/95
2854 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2855 #define ARCH_WIN95 0x2
2856 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2857 #define ARCH_WINNT 0x8
2858 #define ARCH_SAMBA 0x10
2860 #define ARCH_ALL 0x1F
2862 /* List of supported protocols, most desired first */
2866 int (*proto_reply_fn)(char *);
2868 } supported_protocols[] = {
2869 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2870 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2871 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2872 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2873 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2874 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2875 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2876 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2877 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2882 /****************************************************************************
2884 ****************************************************************************/
2885 static int reply_negprot(char *inbuf,char *outbuf)
2887 extern fstring remote_arch;
2888 int outsize = set_message(outbuf,1,0,True);
2893 int bcc = SVAL(smb_buf(inbuf),-2);
2894 int arch = ARCH_ALL;
2896 p = smb_buf(inbuf)+1;
2897 while (p < (smb_buf(inbuf) + bcc))
2900 DEBUG(3,("Requested protocol [%s]\n",p));
2901 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2902 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2903 else if (strcsequal(p,"DOS LM1.2X002"))
2904 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2905 else if (strcsequal(p,"DOS LANMAN2.1"))
2906 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2907 else if (strcsequal(p,"NT LM 0.12"))
2908 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2909 else if (strcsequal(p,"LANMAN2.1"))
2910 arch &= ( ARCH_WINNT | ARCH_OS2 );
2911 else if (strcsequal(p,"LM1.2X002"))
2912 arch &= ( ARCH_WINNT | ARCH_OS2 );
2913 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2915 else if (strcsequal(p,"XENIX CORE"))
2916 arch &= ( ARCH_WINNT | ARCH_OS2 );
2917 else if (strcsequal(p,"Samba")) {
2927 strcpy(remote_arch,"Samba");
2930 strcpy(remote_arch,"WfWg");
2933 strcpy(remote_arch,"Win95");
2936 strcpy(remote_arch,"WinNT");
2939 strcpy(remote_arch,"OS2");
2942 strcpy(remote_arch,"UNKNOWN");
2946 /* possibly reload - change of architecture */
2947 reload_services(True);
2949 /* a special case to stop password server loops */
2950 if (Index == 1 && strequal(remote_machine,myhostname) &&
2951 lp_security()==SEC_SERVER)
2952 exit_server("Password server loop!");
2954 /* Check for protocols, most desirable first */
2955 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2957 p = smb_buf(inbuf)+1;
2959 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2960 while (p < (smb_buf(inbuf) + bcc))
2962 if (strequal(p,supported_protocols[protocol].proto_name))
2971 SSVAL(outbuf,smb_vwv0,choice);
2973 extern fstring remote_proto;
2974 strcpy(remote_proto,supported_protocols[protocol].short_name);
2975 reload_services(True);
2976 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
2977 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
2980 DEBUG(0,("No protocol supported !\n"));
2982 SSVAL(outbuf,smb_vwv0,choice);
2984 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
2990 /****************************************************************************
2991 close all open files for a connection
2992 ****************************************************************************/
2993 static void close_open_files(int cnum)
2996 for (i=0;i<MAX_OPEN_FILES;i++)
2997 if( Files[i].cnum == cnum && Files[i].open) {
3004 /****************************************************************************
3006 ****************************************************************************/
3007 void close_cnum(int cnum, uint16 vuid)
3009 DirCacheFlush(SNUM(cnum));
3013 if (!OPEN_CNUM(cnum))
3015 DEBUG(0,("Can't close cnum %d\n",cnum));
3019 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3021 remote_machine,client_addr(),
3022 lp_servicename(SNUM(cnum))));
3024 yield_connection(cnum,
3025 lp_servicename(SNUM(cnum)),
3026 lp_max_connections(SNUM(cnum)));
3028 if (lp_status(SNUM(cnum)))
3029 yield_connection(cnum,"STATUS.",MAXSTATUS);
3031 close_open_files(cnum);
3032 dptr_closecnum(cnum);
3034 /* execute any "postexec = " line */
3035 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3038 strcpy(cmd,lp_postexec(SNUM(cnum)));
3039 standard_sub(cnum,cmd);
3040 smbrun(cmd,NULL,False);
3045 /* execute any "root postexec = " line */
3046 if (*lp_rootpostexec(SNUM(cnum)))
3049 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3050 standard_sub(cnum,cmd);
3051 smbrun(cmd,NULL,False);
3054 Connections[cnum].open = False;
3055 num_connections_open--;
3056 if (Connections[cnum].ngroups && Connections[cnum].groups)
3058 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3059 free(Connections[cnum].groups);
3060 free(Connections[cnum].igroups);
3061 Connections[cnum].groups = NULL;
3062 Connections[cnum].igroups = NULL;
3063 Connections[cnum].ngroups = 0;
3066 string_set(&Connections[cnum].user,"");
3067 string_set(&Connections[cnum].dirpath,"");
3068 string_set(&Connections[cnum].connectpath,"");
3072 /****************************************************************************
3073 simple routines to do connection counting
3074 ****************************************************************************/
3075 BOOL yield_connection(int cnum,char *name,int max_connections)
3077 struct connect_record crec;
3080 int mypid = getpid();
3083 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3085 if (max_connections <= 0)
3088 bzero(&crec,sizeof(crec));
3090 strcpy(fname,lp_lockdir());
3091 standard_sub(cnum,fname);
3092 trim_string(fname,"","/");
3096 strcat(fname,".LCK");
3098 f = fopen(fname,"r+");
3101 DEBUG(2,("Coudn't open lock file %s (%s)\n",fname,strerror(errno)));
3105 fseek(f,0,SEEK_SET);
3107 /* find a free spot */
3108 for (i=0;i<max_connections;i++)
3110 if (fread(&crec,sizeof(crec),1,f) != 1)
3112 DEBUG(2,("Entry not found in lock file %s\n",fname));
3116 if (crec.pid == mypid && crec.cnum == cnum)
3120 if (crec.pid != mypid || crec.cnum != cnum)
3123 DEBUG(2,("Entry not found in lock file %s\n",fname));
3127 bzero((void *)&crec,sizeof(crec));
3129 /* remove our mark */
3130 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3131 fwrite(&crec,sizeof(crec),1,f) != 1)
3133 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3138 DEBUG(3,("Yield successful\n"));
3145 /****************************************************************************
3146 simple routines to do connection counting
3147 ****************************************************************************/
3148 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3150 struct connect_record crec;
3153 int snum = SNUM(cnum);
3157 if (max_connections <= 0)
3160 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3162 strcpy(fname,lp_lockdir());
3163 standard_sub(cnum,fname);
3164 trim_string(fname,"","/");
3166 if (!directory_exist(fname,NULL))
3171 strcat(fname,".LCK");
3173 if (!file_exist(fname,NULL))
3175 int oldmask = umask(022);
3176 f = fopen(fname,"w");
3181 total_recs = file_size(fname) / sizeof(crec);
3183 f = fopen(fname,"r+");
3187 DEBUG(1,("couldn't open lock file %s\n",fname));
3191 /* find a free spot */
3192 for (i=0;i<max_connections;i++)
3195 if (i>=total_recs ||
3196 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3197 fread(&crec,sizeof(crec),1,f) != 1)
3199 if (foundi < 0) foundi = i;
3203 if (Clear && crec.pid && !process_exists(crec.pid))
3205 fseek(f,i*sizeof(crec),SEEK_SET);
3206 bzero((void *)&crec,sizeof(crec));
3207 fwrite(&crec,sizeof(crec),1,f);
3208 if (foundi < 0) foundi = i;
3211 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3220 DEBUG(3,("no free locks in %s\n",fname));
3225 /* fill in the crec */
3226 bzero((void *)&crec,sizeof(crec));
3227 crec.magic = 0x280267;
3228 crec.pid = getpid();
3230 crec.uid = Connections[cnum].uid;
3231 crec.gid = Connections[cnum].gid;
3232 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3233 crec.start = time(NULL);
3235 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3236 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3239 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3240 fwrite(&crec,sizeof(crec),1,f) != 1)
3251 /*******************************************************************
3252 prepare to dump a core file - carefully!
3253 ********************************************************************/
3254 static BOOL dump_core(void)
3258 strcpy(dname,debugf);
3259 if ((p=strrchr(dname,'/'))) *p=0;
3260 strcat(dname,"/corefiles");
3262 sys_chown(dname,getuid(),getgid());
3264 if (chdir(dname)) return(False);
3267 #ifndef NO_GETRLIMIT
3271 getrlimit(RLIMIT_CORE, &rlp);
3272 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3273 setrlimit(RLIMIT_CORE, &rlp);
3274 getrlimit(RLIMIT_CORE, &rlp);
3275 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3281 DEBUG(0,("Dumping core in %s\n",dname));
3286 /****************************************************************************
3288 ****************************************************************************/
3289 void exit_server(char *reason)
3291 static int firsttime=1;
3294 if (!firsttime) exit(0);
3298 DEBUG(2,("Closing connections\n"));
3299 for (i=0;i<MAX_CONNECTIONS;i++)
3300 if (Connections[i].open)
3303 if (dcelogin_atmost_once)
3307 int oldlevel = DEBUGLEVEL;
3309 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3311 show_msg(last_inbuf);
3312 DEBUGLEVEL = oldlevel;
3313 DEBUG(0,("===============================================================\n"));
3315 if (dump_core()) return;
3319 #ifdef FAST_SHARE_MODES
3320 stop_share_mode_mgmt();
3321 #endif /* FAST_SHARE_MODES */
3323 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3327 /****************************************************************************
3328 do some standard substitutions in a string
3329 ****************************************************************************/
3330 void standard_sub(int cnum,char *s)
3332 if (!strchr(s,'%')) return;
3334 if (VALID_CNUM(cnum))
3336 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
3337 string_sub(s,"%P",Connections[cnum].connectpath);
3338 string_sub(s,"%u",Connections[cnum].user);
3339 if (strstr(s,"%H")) {
3340 char *home = get_home_dir(Connections[cnum].user);
3341 if (home) string_sub(s,"%H",home);
3343 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
3345 standard_sub_basic(s);
3349 These flags determine some of the permissions required to do an operation
3351 Note that I don't set NEED_WRITE on some write operations because they
3352 are used by some brain-dead clients when printing, and I don't want to
3353 force write permissions on print services.
3355 #define AS_USER (1<<0)
3356 #define NEED_WRITE (1<<1)
3357 #define TIME_INIT (1<<2)
3358 #define CAN_IPC (1<<3)
3359 #define AS_GUEST (1<<5)
3363 define a list of possible SMB messages and their corresponding
3364 functions. Any message that has a NULL function is unimplemented -
3365 please feel free to contribute implementations!
3367 struct smb_message_struct
3381 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3382 {SMBtcon,"SMBtcon",reply_tcon,0},
3383 {SMBtdis,"SMBtdis",reply_tdis,0},
3384 {SMBexit,"SMBexit",reply_exit,0},
3385 {SMBioctl,"SMBioctl",reply_ioctl,0},
3386 {SMBecho,"SMBecho",reply_echo,0},
3387 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3388 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3389 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3390 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3391 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3392 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3393 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3394 {SMBopen,"SMBopen",reply_open,AS_USER},
3396 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3397 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3398 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3400 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3401 {SMBread,"SMBread",reply_read,AS_USER},
3402 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3403 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3404 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3405 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3406 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3407 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3409 /* this is a Pathworks specific call, allowing the
3410 changing of the root path */
3411 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3413 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3414 {SMBflush,"SMBflush",reply_flush,AS_USER},
3415 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3416 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3417 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3418 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3419 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3420 {SMBlock,"SMBlock",reply_lock,AS_USER},
3421 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3423 /* CORE+ PROTOCOL FOLLOWS */
3425 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3426 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3427 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3428 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3429 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3431 /* LANMAN1.0 PROTOCOL FOLLOWS */
3433 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3434 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3435 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3436 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3437 {SMBwritec,"SMBwritec",NULL,AS_USER},
3438 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3439 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3440 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3441 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3442 {SMBioctls,"SMBioctls",NULL,AS_USER},
3443 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3444 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3446 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3447 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3448 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3449 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3451 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3452 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3453 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3455 /* LANMAN2.0 PROTOCOL FOLLOWS */
3456 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3457 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3458 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3459 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3461 /* messaging routines */
3462 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3463 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3464 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3465 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3467 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3469 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3470 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3471 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3472 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3475 /****************************************************************************
3476 return a string containing the function name of a SMB command
3477 ****************************************************************************/
3478 char *smb_fn_name(int type)
3480 static char *unknown_name = "SMBunknown";
3481 static int num_smb_messages =
3482 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3485 for (match=0;match<num_smb_messages;match++)
3486 if (smb_messages[match].code == type)
3489 if (match == num_smb_messages)
3490 return(unknown_name);
3492 return(smb_messages[match].name);
3496 /****************************************************************************
3497 do a switch on the message type, and return the response size
3498 ****************************************************************************/
3499 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3503 static int num_smb_messages =
3504 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3508 struct timeval msg_start_time;
3509 struct timeval msg_end_time;
3510 static unsigned long total_time = 0;
3512 GetTimeOfDay(&msg_start_time);
3519 last_message = type;
3521 /* make sure this is an SMB packet */
3522 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3524 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3528 for (match=0;match<num_smb_messages;match++)
3529 if (smb_messages[match].code == type)
3532 if (match == num_smb_messages)
3534 DEBUG(0,("Unknown message type %d!\n",type));
3535 outsize = reply_unknown(inbuf,outbuf);
3539 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3540 if (smb_messages[match].fn)
3542 int cnum = SVAL(inbuf,smb_tid);
3543 int flags = smb_messages[match].flags;
3544 uint16 session_tag = SVAL(inbuf,smb_uid);
3546 /* does this protocol need to be run as root? */
3547 if (!(flags & AS_USER))
3550 /* does this protocol need to be run as the connected user? */
3551 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3552 if (flags & AS_GUEST)
3555 return(ERROR(ERRSRV,ERRinvnid));
3557 /* this code is to work around a bug is MS client 3 without
3558 introducing a security hole - it needs to be able to do
3559 print queue checks as guest if it isn't logged in properly */
3560 if (flags & AS_USER)
3563 /* does it need write permission? */
3564 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3565 return(ERROR(ERRSRV,ERRaccess));
3567 /* ipc services are limited */
3568 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3569 return(ERROR(ERRSRV,ERRaccess));
3571 /* load service specific parameters */
3572 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3573 return(ERROR(ERRSRV,ERRaccess));
3575 /* does this protocol need to be run as guest? */
3576 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3577 return(ERROR(ERRSRV,ERRaccess));
3581 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3585 outsize = reply_unknown(inbuf,outbuf);
3590 GetTimeOfDay(&msg_end_time);
3591 if (!(smb_messages[match].flags & TIME_INIT))
3593 smb_messages[match].time = 0;
3594 smb_messages[match].flags |= TIME_INIT;
3597 unsigned long this_time =
3598 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3599 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3600 smb_messages[match].time += this_time;
3601 total_time += this_time;
3603 DEBUG(2,("TIME %s %d usecs %g pct\n",
3604 smb_fn_name(type),smb_messages[match].time,
3605 (100.0*smb_messages[match].time) / total_time));
3612 /****************************************************************************
3613 construct a chained reply and add it to the already made reply
3614 **************************************************************************/
3615 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3617 static char *orig_inbuf;
3618 static char *orig_outbuf;
3619 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3620 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3621 char *inbuf2, *outbuf2;
3623 char inbuf_saved[smb_wct];
3624 char outbuf_saved[smb_wct];
3625 extern int chain_size;
3626 int wct = CVAL(outbuf,smb_wct);
3627 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3629 /* maybe its not chained */
3630 if (smb_com2 == 0xFF) {
3631 CVAL(outbuf,smb_vwv0) = 0xFF;
3635 if (chain_size == 0) {
3636 /* this is the first part of the chain */
3638 orig_outbuf = outbuf;
3641 /* we need to tell the client where the next part of the reply will be */
3642 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3643 CVAL(outbuf,smb_vwv0) = smb_com2;
3645 /* remember how much the caller added to the chain, only counting stuff
3646 after the parameter words */
3647 chain_size += outsize - smb_wct;
3649 /* work out pointers into the original packets. The
3650 headers on these need to be filled in */
3651 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3652 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3654 /* remember the original command type */
3655 smb_com1 = CVAL(orig_inbuf,smb_com);
3657 /* save the data which will be overwritten by the new headers */
3658 memcpy(inbuf_saved,inbuf2,smb_wct);
3659 memcpy(outbuf_saved,outbuf2,smb_wct);
3661 /* give the new packet the same header as the last part of the SMB */
3662 memmove(inbuf2,inbuf,smb_wct);
3664 /* create the in buffer */
3665 CVAL(inbuf2,smb_com) = smb_com2;
3667 /* create the out buffer */
3668 bzero(outbuf2,smb_size);
3669 set_message(outbuf2,0,0,True);
3670 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3672 memcpy(outbuf2+4,inbuf2+4,4);
3673 CVAL(outbuf2,smb_rcls) = SUCCESS;
3674 CVAL(outbuf2,smb_reh) = 0;
3675 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3677 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3678 SSVAL(outbuf2,smb_err,SUCCESS);
3679 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3680 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3681 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3682 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3684 DEBUG(3,("Chained message\n"));
3687 /* process the request */
3688 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3689 bufsize-chain_size);
3691 /* copy the new reply and request headers over the old ones, but
3692 preserve the smb_com field */
3693 memmove(orig_outbuf,outbuf2,smb_wct);
3694 CVAL(orig_outbuf,smb_com) = smb_com1;
3696 /* restore the saved data, being careful not to overwrite any
3697 data from the reply header */
3698 memcpy(inbuf2,inbuf_saved,smb_wct);
3700 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3701 if (ofs < 0) ofs = 0;
3702 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3710 /****************************************************************************
3711 construct a reply to the incoming packet
3712 ****************************************************************************/
3713 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3715 int type = CVAL(inbuf,smb_com);
3717 int msg_type = CVAL(inbuf,0);
3718 extern int chain_size;
3720 smb_last_time = time(NULL);
3725 bzero(outbuf,smb_size);
3728 return(reply_special(inbuf,outbuf));
3730 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3731 set_message(outbuf,0,0,True);
3733 memcpy(outbuf+4,inbuf+4,4);
3734 CVAL(outbuf,smb_rcls) = SUCCESS;
3735 CVAL(outbuf,smb_reh) = 0;
3736 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3738 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3739 SSVAL(outbuf,smb_err,SUCCESS);
3740 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3741 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3742 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3743 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3745 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3747 outsize += chain_size;
3750 smb_setlen(outbuf,outsize - 4);
3755 /****************************************************************************
3756 process commands from the client
3757 ****************************************************************************/
3758 static void process(void)
3760 static int trans_num = 0;
3764 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3765 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3766 if ((InBuffer == NULL) || (OutBuffer == NULL))
3769 InBuffer += SMB_ALIGNMENT;
3770 OutBuffer += SMB_ALIGNMENT;
3773 DEBUG(3,("priming nmbd\n"));
3776 ip = *interpret_addr2("localhost");
3777 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3779 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3789 int deadtime = lp_deadtime()*60;
3791 int last_keepalive=0;
3794 deadtime = DEFAULT_SMBD_TIMEOUT;
3796 if (lp_readprediction())
3797 do_read_prediction();
3801 for (counter=SMBD_SELECT_LOOP;
3802 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3803 counter += SMBD_SELECT_LOOP)
3807 BOOL allidle = True;
3808 extern int keepalive;
3810 if (smb_read_error == READ_EOF) {
3811 DEBUG(3,("end of file from client\n"));
3815 if (smb_read_error == READ_ERROR) {
3816 DEBUG(3,("receive_smb error (%s) exiting\n",
3823 /* become root again if waiting */
3826 /* check for smb.conf reload */
3827 if (!(counter%SMBD_RELOAD_CHECK))
3828 reload_services(True);
3831 /* check the share modes every 10 secs */
3832 if (!(counter%SHARE_MODES_CHECK))
3833 check_share_modes();
3835 /* clean the share modes every 5 minutes */
3836 if (!(counter%SHARE_MODES_CLEAN))
3837 clean_share_modes();
3840 /* automatic timeout if all connections are closed */
3841 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3842 DEBUG(2,("%s Closing idle connection\n",timestring()));
3846 if (keepalive && (counter-last_keepalive)>keepalive) {
3847 extern int password_client;
3848 if (!send_keepalive(Client)) {
3849 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3852 /* also send a keepalive to the password server if its still
3854 if (password_client != -1)
3855 send_keepalive(password_client);
3856 last_keepalive = counter;
3859 /* check for connection timeouts */
3860 for (i=0;i<MAX_CONNECTIONS;i++)
3861 if (Connections[i].open)
3863 /* close dirptrs on connections that are idle */
3864 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3867 if (Connections[i].num_files_open > 0 ||
3868 (t-Connections[i].lastused)<deadtime)
3872 if (allidle && num_connections_open>0) {
3873 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3878 msg_type = CVAL(InBuffer,0);
3879 msg_flags = CVAL(InBuffer,1);
3880 type = CVAL(InBuffer,smb_com);
3882 len = smb_len(InBuffer);
3884 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3888 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3891 if(trans_num == 1 && VT_Check(InBuffer)) {
3901 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
3904 if (CVAL(OutBuffer,0) == 0)
3905 show_msg(OutBuffer);
3907 if (nread != smb_len(OutBuffer) + 4)
3909 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3911 smb_len(OutBuffer)));
3914 send_smb(Client,OutBuffer);
3921 /****************************************************************************
3922 initialise connect, service and file structs
3923 ****************************************************************************/
3924 static void init_structs(void )
3927 get_myname(myhostname,NULL);
3929 for (i=0;i<MAX_CONNECTIONS;i++)
3931 Connections[i].open = False;
3932 Connections[i].num_files_open=0;
3933 Connections[i].lastused=0;
3934 Connections[i].used=False;
3935 string_init(&Connections[i].user,"");
3936 string_init(&Connections[i].dirpath,"");
3937 string_init(&Connections[i].connectpath,"");
3938 string_init(&Connections[i].origpath,"");
3941 for (i=0;i<MAX_OPEN_FILES;i++)
3943 Files[i].open = False;
3944 string_init(&Files[i].name,"");
3948 for (i=0;i<MAX_OPEN_FILES;i++)
3950 file_fd_struct *fd_ptr = &FileFd[i];
3951 fd_ptr->ref_count = 0;
3952 fd_ptr->dev = (int32)-1;
3953 fd_ptr->inode = (int32)-1;
3955 fd_ptr->fd_readonly = -1;
3956 fd_ptr->fd_writeonly = -1;
3957 fd_ptr->real_open_flags = -1;
3963 /****************************************************************************
3964 usage on the program
3965 ****************************************************************************/
3966 static void usage(char *pname)
3968 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3970 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3971 printf("Version %s\n",VERSION);
3972 printf("\t-D become a daemon\n");
3973 printf("\t-p port listen on the specified port\n");
3974 printf("\t-d debuglevel set the debuglevel\n");
3975 printf("\t-l log basename. Basename for log/debug files\n");
3976 printf("\t-s services file. Filename of services file\n");
3977 printf("\t-P passive only\n");
3978 printf("\t-a overwrite log file, don't append\n");
3983 /****************************************************************************
3985 ****************************************************************************/
3986 int main(int argc,char *argv[])
3988 extern BOOL append_log;
3989 /* shall I run as a daemon */
3990 BOOL is_daemon = False;
3991 int port = SMB_PORT;
3993 extern char *optarg;
3994 char pidFile[100] = { 0 };
3996 #ifdef NEED_AUTH_PARAMETERS
3997 set_auth_parameters(argc,argv);
4008 strcpy(debugf,SMBLOGFILE);
4010 setup_logging(argv[0],False);
4012 charset_initialise();
4014 /* make absolutely sure we run as root - to handle cases whre people
4015 are crazy enough to have it setuid */
4025 fault_setup(exit_server);
4026 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4028 /* we want total control over the permissions on created files,
4029 so set our umask to 0 */
4036 /* this is for people who can't start the program correctly */
4037 while (argc > 1 && (*argv[1] != '-'))
4043 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4047 strncpy(pidFile, optarg, sizeof(pidFile));
4050 strcpy(user_socket_options,optarg);
4053 strcpy(scope,optarg);
4057 extern BOOL passive;
4062 strcpy(servicesf,optarg);
4065 strcpy(debugf,optarg);
4069 extern BOOL append_log;
4070 append_log = !append_log;
4080 DEBUGLEVEL = atoi(optarg);
4083 port = atoi(optarg);
4096 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4097 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
4099 #ifndef NO_GETRLIMIT
4100 #ifdef RLIMIT_NOFILE
4103 getrlimit(RLIMIT_NOFILE, &rlp);
4104 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4105 setrlimit(RLIMIT_NOFILE, &rlp);
4106 getrlimit(RLIMIT_NOFILE, &rlp);
4107 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4113 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4114 getuid(),getgid(),geteuid(),getegid()));
4116 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4118 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4124 if (!reload_services(False))
4127 strcpy(myworkgroup, lp_workgroup());
4129 #ifndef NO_SIGNAL_TEST
4130 signal(SIGHUP,SIGNAL_CAST sig_hup);
4133 DEBUG(3,("%s loaded services\n",timestring()));
4135 if (!is_daemon && !is_a_socket(0))
4137 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4143 DEBUG(3,("%s becoming a daemon\n",timestring()));
4152 if ((fd = open(pidFile,
4153 O_NONBLOCK | O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4155 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4158 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4160 DEBUG(0,("ERROR: smbd is already running\n"));
4163 sprintf(buf, "%u\n", (unsigned int) getpid());
4164 if (write(fd, buf, strlen(buf)) < 0)
4166 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4169 /* Leave pid file open & locked for the duration... */
4172 if (!open_sockets(is_daemon,port))
4175 #ifdef FAST_SHARE_MODES
4176 if (!start_share_mode_mgmt())
4178 #endif /* FAST_SHARE_MODES */
4180 /* possibly reload the services file. */
4181 reload_services(True);
4183 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4187 if (sys_chroot(lp_rootdir()) == 0)
4188 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4194 exit_server("normal exit");