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;
29 char *InBuffer = NULL;
30 char *OutBuffer = NULL;
31 char *last_inbuf = NULL;
36 BOOL share_mode_pending = False;
38 /* the last message the was processed */
39 int last_message = -1;
41 /* a useful macro to debug the last message processed */
42 #define LAST_MESSAGE() smb_fn_name(last_message)
45 extern int DEBUGLEVEL;
46 extern int case_default;
47 extern BOOL case_sensitive;
48 extern BOOL case_preserve;
49 extern BOOL use_mangled_map;
50 extern BOOL short_case_preserve;
51 extern BOOL case_mangle;
52 extern time_t smb_last_time;
54 extern int smb_read_error;
56 extern pstring user_socket_options;
58 connection_struct Connections[MAX_CONNECTIONS];
59 files_struct Files[MAX_OPEN_FILES];
62 * Indirection for file fd's. Needed as POSIX locking
63 * is based on file/process, not fd/process.
65 file_fd_struct FileFd[MAX_OPEN_FILES];
66 int max_file_fd_used = 0;
71 * Size of data we can send to client. Set
72 * by the client for all protocols above CORE.
73 * Set by us for CORE protocol.
75 int max_send = BUFFER_SIZE;
77 * Size of the data we can receive. Set by us.
78 * Can be modified by the max xmit parameter.
80 int max_recv = BUFFER_SIZE;
82 /* a fnum to use when chaining */
85 /* number of open connections */
86 static int num_connections_open = 0;
88 extern fstring remote_machine;
92 /* these can be set by some functions to override the error codes */
93 int unix_ERR_class=SUCCESS;
97 extern int extra_time_offset;
99 extern pstring myhostname;
101 static int find_free_connection(int hash);
103 /* for readability... */
104 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
105 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
106 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
107 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
108 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
110 /****************************************************************************
111 when exiting, take the whole family
112 ****************************************************************************/
115 exit_server("caught signal");
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 (((int32)sbuf->st_dev) == fd_ptr->dev) &&
841 (((int32)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 = (int32)-1;
865 fd_ptr->inode = (int32)-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;
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 = (int32)sbuf->st_dev;
1128 fd_ptr->inode = (int32)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].share_pending = False;
1145 Files[fnum].print_file = Connections[cnum].printer;
1146 Files[fnum].modified = False;
1147 Files[fnum].cnum = cnum;
1148 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1149 Files[fnum].wbmpx_ptr = NULL;
1152 * If the printer is marked as postscript output a leading
1153 * file identifier to ensure the file is treated as a raw
1155 * This has a similar effect as CtrlD=0 in WIN.INI file.
1156 * tim@fsg.com 09/06/94
1158 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1159 Files[fnum].can_write)
1161 DEBUG(3,("Writing postscript line\n"));
1162 write_file(fnum,"%!\n",3);
1165 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1166 timestring(),Connections[cnum].user,fname,
1167 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1168 Connections[cnum].num_files_open,fnum));
1173 /* mmap it if read-only */
1174 if (!Files[fnum].can_write)
1176 Files[fnum].mmap_size = file_size(fname);
1177 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1178 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1180 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1182 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1183 Files[fnum].mmap_ptr = NULL;
1189 /*******************************************************************
1191 ********************************************************************/
1192 void sync_file(int fnum)
1195 fsync(Files[fnum].fd_ptr->fd);
1199 /****************************************************************************
1200 run a file if it is a magic script
1201 ****************************************************************************/
1202 static void check_magic(int fnum,int cnum)
1204 if (!*lp_magicscript(SNUM(cnum)))
1207 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1211 if (!(p = strrchr(Files[fnum].name,'/')))
1212 p = Files[fnum].name;
1216 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1222 pstring magic_output;
1224 strcpy(fname,Files[fnum].name);
1226 if (*lp_magicoutput(SNUM(cnum)))
1227 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1229 sprintf(magic_output,"%s.out",fname);
1232 ret = smbrun(fname,magic_output,False);
1233 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1239 /****************************************************************************
1240 close a file - possibly invalidating the read prediction
1241 ****************************************************************************/
1242 void close_file(int fnum)
1244 int cnum = Files[fnum].cnum;
1245 invalidate_read_prediction(Files[fnum].fd_ptr->fd);
1246 Files[fnum].open = False;
1247 Connections[cnum].num_files_open--;
1248 if(Files[fnum].wbmpx_ptr)
1250 free((char *)Files[fnum].wbmpx_ptr);
1251 Files[fnum].wbmpx_ptr = NULL;
1255 if(Files[fnum].mmap_ptr)
1257 munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size);
1258 Files[fnum].mmap_ptr = NULL;
1262 if (lp_share_modes(SNUM(cnum)))
1263 del_share_mode(fnum);
1265 fd_attempt_close(Files[fnum].fd_ptr);
1267 /* NT uses smbclose to start a print - weird */
1268 if (Files[fnum].print_file)
1271 /* check for magic scripts */
1272 check_magic(fnum,cnum);
1274 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1275 timestring(),Connections[cnum].user,Files[fnum].name,
1276 Connections[cnum].num_files_open));
1279 enum {AFAIL,AREAD,AWRITE,AALL};
1281 /*******************************************************************
1282 reproduce the share mode access table
1283 ********************************************************************/
1284 static int access_table(int new_deny,int old_deny,int old_mode,
1285 int share_pid,char *fname)
1287 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1289 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1290 if (old_deny == new_deny && share_pid == getpid())
1293 if (old_mode == 0) return(AREAD);
1295 /* the new smbpub.zip spec says that if the file extension is
1296 .com, .dll, .exe or .sym then allow the open. I will force
1297 it to read-only as this seems sensible although the spec is
1298 a little unclear on this. */
1299 if ((fname = strrchr(fname,'.'))) {
1300 if (strequal(fname,".com") ||
1301 strequal(fname,".dll") ||
1302 strequal(fname,".exe") ||
1303 strequal(fname,".sym"))
1313 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1314 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1315 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1318 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1319 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1320 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1323 if (old_deny==DENY_WRITE) return(AREAD);
1324 if (old_deny==DENY_READ) return(AWRITE);
1325 if (old_deny==DENY_NONE) return(AALL);
1331 /*******************************************************************
1332 check if the share mode on a file allows it to be deleted or unlinked
1333 return True if sharing doesn't prevent the operation
1334 ********************************************************************/
1335 BOOL check_file_sharing(int cnum,char *fname)
1338 int share_mode = get_share_mode_byname(cnum,fname,&pid);
1340 if (!pid || !share_mode) return(True);
1342 if (share_mode == DENY_DOS)
1343 return(pid == getpid());
1345 /* XXXX exactly what share mode combinations should be allowed for
1346 deleting/renaming? */
1350 /****************************************************************************
1352 Helper for open_file_shared.
1353 Truncate a file after checking locking; close file if locked.
1354 **************************************************************************/
1355 static void truncate_unless_locked(int fnum, int cnum)
1357 if (Files[fnum].can_write){
1358 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1361 unix_ERR_class = ERRDOS;
1362 unix_ERR_code = ERRlock;
1365 ftruncate(Files[fnum].fd_ptr->fd,0);
1370 /****************************************************************************
1371 open a file with a share mode
1372 ****************************************************************************/
1373 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1374 int mode,int *Access,int *action)
1378 int deny_mode = (share_mode>>4)&7;
1380 BOOL file_existed = file_exist(fname,&sbuf);
1381 BOOL fcbopen = False;
1384 Files[fnum].open = False;
1385 Files[fnum].fd_ptr = 0;
1387 /* this is for OS/2 EAs - try and say we don't support them */
1388 if (strstr(fname,".+,;=[].")) {
1389 unix_ERR_class = ERRDOS;
1390 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1394 if ((ofun & 0x3) == 0 && file_existed) {
1401 if ((ofun & 0x3) == 2)
1404 /* note that we ignore the append flag as
1405 append does not mean the same thing under dos and unix */
1407 switch (share_mode&0xF)
1424 if (flags != O_RDONLY && file_existed &&
1425 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) {
1433 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
1434 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1439 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1441 if (lp_share_modes(SNUM(cnum))) {
1445 old_share = get_share_mode(cnum,&sbuf,&share_pid);
1448 /* someone else has a share lock on it, check to see
1450 int old_open_mode = old_share&0xF;
1451 int old_deny_mode = (old_share>>4)&7;
1453 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) {
1454 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1455 deny_mode,old_deny_mode,old_open_mode,fname));
1457 unix_ERR_class = ERRDOS;
1458 unix_ERR_code = ERRbadshare;
1463 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1466 if ((access_allowed == AFAIL) ||
1467 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1468 (access_allowed == AREAD && flags == O_WRONLY) ||
1469 (access_allowed == AWRITE && flags == O_RDONLY)) {
1470 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1471 deny_mode,old_deny_mode,old_open_mode,
1475 unix_ERR_class = ERRDOS;
1476 unix_ERR_code = ERRbadshare;
1480 if (access_allowed == AREAD)
1483 if (access_allowed == AWRITE)
1489 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1490 flags,flags2,mode));
1492 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1493 if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) {
1495 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1498 if (Files[fnum].open) {
1512 Files[fnum].share_mode = (deny_mode<<4) | open_mode;
1513 Files[fnum].share_pending = True;
1516 (*Access) = open_mode;
1520 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1521 if (!file_existed) *action = 2;
1522 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1526 share_mode_pending = True;
1528 if ((flags2&O_TRUNC) && file_existed)
1529 truncate_unless_locked(fnum,cnum);
1535 /*******************************************************************
1536 check for files that we should now set our share modes on
1537 ********************************************************************/
1538 static void check_share_modes(void)
1541 for (i=0;i<MAX_OPEN_FILES;i++)
1542 if(Files[i].open && Files[i].share_pending) {
1543 if (lp_share_modes(SNUM(Files[i].cnum))) {
1545 get_share_mode_by_fnum(Files[i].cnum,i,&pid);
1547 set_share_mode(i,Files[i].share_mode);
1548 Files[i].share_pending = False;
1551 Files[i].share_pending = False;
1557 /****************************************************************************
1558 seek a file. Try to avoid the seek if possible
1559 ****************************************************************************/
1560 int seek_file(int fnum,int pos)
1563 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1566 Files[fnum].pos = lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) - offset;
1567 return(Files[fnum].pos);
1570 /****************************************************************************
1572 ****************************************************************************/
1573 int read_file(int fnum,char *data,int pos,int n)
1577 if (!Files[fnum].can_write)
1579 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1587 if (Files[fnum].mmap_ptr)
1589 int num = MIN(n,Files[fnum].mmap_size-pos);
1592 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1604 if (seek_file(fnum,pos) != pos)
1606 DEBUG(3,("Failed to seek to %d\n",pos));
1611 readret = read(Files[fnum].fd_ptr->fd,data,n);
1612 if (readret > 0) ret += readret;
1619 /****************************************************************************
1621 ****************************************************************************/
1622 int write_file(int fnum,char *data,int n)
1624 if (!Files[fnum].can_write) {
1629 if (!Files[fnum].modified) {
1631 Files[fnum].modified = True;
1632 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1633 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1634 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1635 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1640 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1644 /****************************************************************************
1645 load parameters specific to a connection/service
1646 ****************************************************************************/
1647 BOOL become_service(int cnum,BOOL do_chdir)
1649 extern char magic_char;
1650 static int last_cnum = -1;
1653 if (!OPEN_CNUM(cnum))
1659 Connections[cnum].lastused = smb_last_time;
1664 ChDir(Connections[cnum].connectpath) != 0 &&
1665 ChDir(Connections[cnum].origpath) != 0)
1667 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1668 Connections[cnum].connectpath,cnum));
1672 if (cnum == last_cnum)
1677 case_default = lp_defaultcase(snum);
1678 case_preserve = lp_preservecase(snum);
1679 short_case_preserve = lp_shortpreservecase(snum);
1680 case_mangle = lp_casemangle(snum);
1681 case_sensitive = lp_casesensitive(snum);
1682 magic_char = lp_magicchar(snum);
1683 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1688 /****************************************************************************
1689 find a service entry
1690 ****************************************************************************/
1691 int find_service(char *service)
1695 string_sub(service,"\\","/");
1697 iService = lp_servicenumber(service);
1699 /* now handle the special case of a home directory */
1702 char *phome_dir = get_home_dir(service);
1703 DEBUG(3,("checking for home directory %s gave %s\n",service,
1704 phome_dir?phome_dir:"(NULL)"));
1708 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1710 lp_add_home(service,iHomeService,phome_dir);
1711 iService = lp_servicenumber(service);
1716 /* If we still don't have a service, attempt to add it as a printer. */
1719 int iPrinterService;
1721 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1725 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1727 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1729 DEBUG(3,("%s is a valid printer name\n", service));
1730 DEBUG(3,("adding %s as a printer service\n", service));
1731 lp_add_printer(service,iPrinterService);
1732 iService = lp_servicenumber(service);
1734 DEBUG(0,("failed to add %s as a printer service!\n", service));
1737 DEBUG(3,("%s is not a valid printer name\n", service));
1741 /* just possibly it's a default service? */
1744 char *defservice = lp_defaultservice();
1745 if (defservice && *defservice && !strequal(defservice,service)) {
1746 iService = find_service(defservice);
1747 if (iService >= 0) {
1748 string_sub(service,"_","/");
1749 iService = lp_add_service(service,iService);
1755 if (!VALID_SNUM(iService))
1757 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1762 DEBUG(3,("find_service() failed to find service %s\n", service));
1768 /****************************************************************************
1769 create an error packet from a cached error.
1770 ****************************************************************************/
1771 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1773 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1775 int32 eclass = wbmpx->wr_errclass;
1776 int32 err = wbmpx->wr_error;
1778 /* We can now delete the auxiliary struct */
1779 free((char *)wbmpx);
1780 Files[fnum].wbmpx_ptr = NULL;
1781 return error_packet(inbuf,outbuf,eclass,err,line);
1790 } unix_smb_errmap[] =
1792 {EPERM,ERRDOS,ERRnoaccess},
1793 {EACCES,ERRDOS,ERRnoaccess},
1794 {ENOENT,ERRDOS,ERRbadfile},
1795 {EIO,ERRHRD,ERRgeneral},
1796 {EBADF,ERRSRV,ERRsrverror},
1797 {EINVAL,ERRSRV,ERRsrverror},
1798 {EEXIST,ERRDOS,ERRfilexists},
1799 {ENFILE,ERRDOS,ERRnofids},
1800 {EMFILE,ERRDOS,ERRnofids},
1801 {ENOSPC,ERRHRD,ERRdiskfull},
1803 {EDQUOT,ERRHRD,ERRdiskfull},
1806 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1809 {EXDEV,ERRDOS,ERRdiffdevice},
1811 {EROFS,ERRHRD,ERRnowrite},
1816 /****************************************************************************
1817 create an error packet from errno
1818 ****************************************************************************/
1819 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1821 int eclass=def_class;
1825 if (unix_ERR_class != SUCCESS)
1827 eclass = unix_ERR_class;
1828 ecode = unix_ERR_code;
1829 unix_ERR_class = SUCCESS;
1834 while (unix_smb_errmap[i].smbclass != 0)
1836 if (unix_smb_errmap[i].unixerror == errno)
1838 eclass = unix_smb_errmap[i].smbclass;
1839 ecode = unix_smb_errmap[i].smbcode;
1846 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1850 /****************************************************************************
1851 create an error packet. Normally called using the ERROR() macro
1852 ****************************************************************************/
1853 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1855 int outsize = set_message(outbuf,0,0,True);
1857 cmd = CVAL(inbuf,smb_com);
1859 CVAL(outbuf,smb_rcls) = error_class;
1860 SSVAL(outbuf,smb_err,error_code);
1862 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1865 (int)CVAL(inbuf,smb_com),
1866 smb_fn_name(CVAL(inbuf,smb_com)),
1871 DEBUG(3,("error string = %s\n",strerror(errno)));
1877 #ifndef SIGCLD_IGNORE
1878 /****************************************************************************
1879 this prevents zombie child processes
1880 ****************************************************************************/
1881 static int sig_cld()
1883 static int depth = 0;
1886 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1892 BlockSignals(True,SIGCLD);
1893 DEBUG(5,("got SIGCLD\n"));
1896 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1900 /* Stevens, Adv. Unix Prog. says that on system V you must call
1901 wait before reinstalling the signal handler, because the kernel
1902 calls the handler from within the signal-call when there is a
1903 child that has exited. This would lead to an infinite recursion
1904 if done vice versa. */
1906 #ifndef DONT_REINSTALL_SIG
1907 #ifdef SIGCLD_IGNORE
1908 signal(SIGCLD, SIG_IGN);
1910 signal(SIGCLD, SIGNAL_CAST sig_cld);
1915 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1918 BlockSignals(False,SIGCLD);
1923 /****************************************************************************
1924 this is called when the client exits abruptly
1925 **************************************************************************/
1926 static int sig_pipe()
1928 extern int password_client;
1929 BlockSignals(True,SIGPIPE);
1931 if (password_client != -1) {
1932 DEBUG(3,("lost connection to password server\n"));
1933 close(password_client);
1934 password_client = -1;
1935 #ifndef DONT_REINSTALL_SIG
1936 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1938 BlockSignals(False,SIGPIPE);
1942 exit_server("Got sigpipe\n");
1946 /****************************************************************************
1947 open the socket communication
1948 ****************************************************************************/
1949 static BOOL open_sockets(BOOL is_daemon,int port)
1956 struct sockaddr addr;
1957 int in_addrlen = sizeof(addr);
1960 #ifdef SIGCLD_IGNORE
1961 signal(SIGCLD, SIG_IGN);
1963 signal(SIGCLD, SIGNAL_CAST sig_cld);
1966 /* open an incoming socket */
1967 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
1971 /* ready to listen */
1972 if (listen(s, 5) == -1)
1974 DEBUG(0,("listen: %s",strerror(errno)));
1982 /* now accept incoming connections - forking a new process
1983 for each incoming connection */
1984 DEBUG(2,("waiting for a connection\n"));
1987 Client = accept(s,&addr,&in_addrlen);
1989 if (Client == -1 && errno == EINTR)
1994 DEBUG(0,("accept: %s",strerror(errno)));
1998 #ifdef NO_FORK_DEBUG
1999 #ifndef NO_SIGNAL_TEST
2000 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2001 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2005 if (Client != -1 && fork()==0)
2007 #ifndef NO_SIGNAL_TEST
2008 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2009 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2011 /* close the listening socket */
2014 /* close our standard file descriptors */
2018 set_socket_options(Client,"SO_KEEPALIVE");
2019 set_socket_options(Client,user_socket_options);
2023 close(Client); /* The parent doesn't need this socket */
2029 /* We will abort gracefully when the client or remote system
2031 #ifndef NO_SIGNAL_TEST
2032 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2036 /* close our standard file descriptors */
2039 set_socket_options(Client,"SO_KEEPALIVE");
2040 set_socket_options(Client,user_socket_options);
2047 /****************************************************************************
2048 check if a snum is in use
2049 ****************************************************************************/
2050 BOOL snum_used(int snum)
2053 for (i=0;i<MAX_CONNECTIONS;i++)
2054 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2059 /****************************************************************************
2060 reload the services file
2061 **************************************************************************/
2062 BOOL reload_services(BOOL test)
2069 strcpy(fname,lp_configfile());
2070 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2072 strcpy(servicesf,fname);
2079 if (test && !lp_file_list_changed())
2082 lp_killunused(snum_used);
2084 ret = lp_load(servicesf,False);
2086 /* perhaps the config filename is now set */
2088 reload_services(True);
2097 set_socket_options(Client,"SO_KEEPALIVE");
2098 set_socket_options(Client,user_socket_options);
2102 create_mangled_stack(lp_mangledstack());
2104 /* this forces service parameters to be flushed */
2105 become_service(-1,True);
2112 /****************************************************************************
2113 this prevents zombie child processes
2114 ****************************************************************************/
2115 static int sig_hup()
2117 BlockSignals(True,SIGHUP);
2118 DEBUG(0,("Got SIGHUP\n"));
2119 reload_services(False);
2120 #ifndef DONT_REINSTALL_SIG
2121 signal(SIGHUP,SIGNAL_CAST sig_hup);
2123 BlockSignals(False,SIGHUP);
2127 /****************************************************************************
2128 Setup the groups a user belongs to.
2129 ****************************************************************************/
2130 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2131 int **p_igroups, gid_t **p_groups)
2133 if (-1 == initgroups(user,gid))
2137 DEBUG(0,("Unable to initgroups!\n"));
2138 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2139 DEBUG(0,("This is probably a problem with the account %s\n",user));
2147 ngroups = getgroups(0,&grp);
2150 igroups = (int *)malloc(sizeof(int)*ngroups);
2151 for (i=0;i<ngroups;i++)
2152 igroups[i] = 0x42424242;
2153 ngroups = getgroups(ngroups,(gid_t *)igroups);
2155 if (igroups[0] == 0x42424242)
2158 *p_ngroups = ngroups;
2160 /* The following bit of code is very strange. It is due to the
2161 fact that some OSes use int* and some use gid_t* for
2162 getgroups, and some (like SunOS) use both, one in prototypes,
2163 and one in man pages and the actual code. Thus we detect it
2164 dynamically using some very ugly code */
2167 /* does getgroups return ints or gid_t ?? */
2168 static BOOL groups_use_ints = True;
2170 if (groups_use_ints &&
2172 SVAL(igroups,2) == 0x4242)
2173 groups_use_ints = False;
2175 for (i=0;groups_use_ints && i<ngroups;i++)
2176 if (igroups[i] == 0x42424242)
2177 groups_use_ints = False;
2179 if (groups_use_ints)
2181 *p_igroups = igroups;
2182 *p_groups = (gid_t *)igroups;
2186 gid_t *groups = (gid_t *)igroups;
2187 igroups = (int *)malloc(sizeof(int)*ngroups);
2188 for (i=0;i<ngroups;i++)
2189 igroups[i] = groups[i];
2190 *p_igroups = igroups;
2191 *p_groups = (gid_t *)groups;
2194 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2195 for (i=0;i<ngroups;i++)
2196 DEBUG(3,("%d ",igroups[i]));
2202 /****************************************************************************
2203 make a connection to a service
2204 ****************************************************************************/
2205 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2209 struct passwd *pass = NULL;
2210 connection_struct *pcon;
2213 static BOOL first_connection = True;
2217 snum = find_service(service);
2220 if (strequal(service,"IPC$"))
2222 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2226 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2230 if (strequal(service,HOMES_NAME))
2232 if (*user && Get_Pwnam(user,True))
2233 return(make_connection(user,user,password,pwlen,dev,vuid));
2235 if (validated_username(vuid))
2237 strcpy(user,validated_username(vuid));
2238 return(make_connection(user,user,password,pwlen,dev,vuid));
2242 if (!lp_snum_ok(snum) || !check_access(snum)) {
2246 /* you can only connect to the IPC$ service as an ipc device */
2247 if (strequal(service,"IPC$"))
2250 if (*dev == '?' || !*dev)
2252 if (lp_print_ok(snum))
2253 strcpy(dev,"LPT1:");
2258 /* if the request is as a printer and you can't print then refuse */
2260 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2261 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2265 /* lowercase the user name */
2268 /* add it as a possible user name */
2269 add_session_user(service);
2271 /* shall we let them in? */
2272 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2274 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2278 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2281 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2285 pcon = &Connections[cnum];
2286 bzero((char *)pcon,sizeof(*pcon));
2288 /* find out some info about the user */
2289 pass = Get_Pwnam(user,True);
2293 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2297 pcon->read_only = lp_readonly(snum);
2301 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2302 string_sub(list,"%S",service);
2304 if (user_in_list(user,list))
2305 pcon->read_only = True;
2307 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2308 string_sub(list,"%S",service);
2310 if (user_in_list(user,list))
2311 pcon->read_only = False;
2314 /* admin user check */
2315 if (user_in_list(user,lp_admin_users(snum)) &&
2318 pcon->admin_user = True;
2319 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2322 pcon->admin_user = False;
2324 pcon->force_user = force;
2326 pcon->uid = pass->pw_uid;
2327 pcon->gid = pass->pw_gid;
2328 pcon->num_files_open = 0;
2329 pcon->lastused = time(NULL);
2330 pcon->service = snum;
2332 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2333 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2334 pcon->dirptr = NULL;
2335 string_set(&pcon->dirpath,"");
2336 string_set(&pcon->user,user);
2339 if (*lp_force_group(snum))
2344 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2345 /* default service may be a group name */
2346 string_sub(gname,"%S",service);
2347 gptr = (struct group *)getgrnam(gname);
2351 pcon->gid = gptr->gr_gid;
2352 DEBUG(3,("Forced group %s\n",gname));
2355 DEBUG(1,("Couldn't find group %s\n",gname));
2359 if (*lp_force_user(snum))
2361 struct passwd *pass2;
2363 strcpy(fuser,lp_force_user(snum));
2364 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2367 pcon->uid = pass2->pw_uid;
2368 string_set(&pcon->user,fuser);
2370 pcon->force_user = True;
2371 DEBUG(3,("Forced user %s\n",fuser));
2374 DEBUG(1,("Couldn't find user %s\n",fuser));
2379 strcpy(s,lp_pathname(snum));
2380 standard_sub(cnum,s);
2381 string_set(&pcon->connectpath,s);
2382 DEBUG(3,("Connect path is %s\n",s));
2385 /* groups stuff added by ih */
2387 pcon->groups = NULL;
2391 /* Find all the groups this uid is in and store them. Used by become_user() */
2392 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2394 /* check number of connections */
2395 if (!claim_connection(cnum,
2396 lp_servicename(SNUM(cnum)),
2397 lp_max_connections(SNUM(cnum)),False))
2399 DEBUG(1,("too many connections - rejected\n"));
2403 if (lp_status(SNUM(cnum)))
2404 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2406 first_connection = False;
2411 /* execute any "root preexec = " line */
2412 if (*lp_rootpreexec(SNUM(cnum)))
2415 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2416 standard_sub(cnum,cmd);
2417 DEBUG(5,("cmd=%s\n",cmd));
2418 smbrun(cmd,NULL,False);
2421 if (!become_user(cnum,pcon->vuid))
2423 DEBUG(0,("Can't become connected user!\n"));
2425 if (!IS_IPC(cnum)) {
2426 yield_connection(cnum,
2427 lp_servicename(SNUM(cnum)),
2428 lp_max_connections(SNUM(cnum)));
2429 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2434 if (ChDir(pcon->connectpath) != 0)
2436 DEBUG(0,("Can't change directory to %s (%s)\n",
2437 pcon->connectpath,strerror(errno)));
2440 if (!IS_IPC(cnum)) {
2441 yield_connection(cnum,
2442 lp_servicename(SNUM(cnum)),
2443 lp_max_connections(SNUM(cnum)));
2444 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2449 string_set(&pcon->origpath,pcon->connectpath);
2451 #if SOFTLINK_OPTIMISATION
2452 /* resolve any soft links early */
2455 strcpy(s,pcon->connectpath);
2457 string_set(&pcon->connectpath,s);
2458 ChDir(pcon->connectpath);
2462 num_connections_open++;
2463 add_session_user(user);
2465 /* execute any "preexec = " line */
2466 if (*lp_preexec(SNUM(cnum)))
2469 strcpy(cmd,lp_preexec(SNUM(cnum)));
2470 standard_sub(cnum,cmd);
2471 smbrun(cmd,NULL,False);
2474 /* we've finished with the sensitive stuff */
2478 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2482 lp_servicename(SNUM(cnum)),user,
2492 /****************************************************************************
2493 find first available file slot
2494 ****************************************************************************/
2495 int find_free_file(void )
2498 /* we start at 1 here for an obscure reason I can't now remember,
2499 but I think is important :-) */
2500 for (i=1;i<MAX_OPEN_FILES;i++)
2503 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2507 /****************************************************************************
2508 find first available connection slot, starting from a random position.
2509 The randomisation stops problems with the server dieing and clients
2510 thinking the server is still available.
2511 ****************************************************************************/
2512 static int find_free_connection(int hash )
2516 hash = (hash % (MAX_CONNECTIONS-2))+1;
2520 for (i=hash+1;i!=hash;)
2522 if (!Connections[i].open && Connections[i].used == used)
2524 DEBUG(3,("found free connection number %d\n",i));
2528 if (i == MAX_CONNECTIONS)
2538 DEBUG(1,("ERROR! Out of connection structures\n"));
2543 /****************************************************************************
2544 reply for the core protocol
2545 ****************************************************************************/
2546 int reply_corep(char *outbuf)
2548 int outsize = set_message(outbuf,1,0,True);
2550 Protocol = PROTOCOL_CORE;
2556 /****************************************************************************
2557 reply for the coreplus protocol
2558 ****************************************************************************/
2559 int reply_coreplus(char *outbuf)
2561 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2562 int outsize = set_message(outbuf,13,0,True);
2563 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2564 readbraw and writebraw (possibly) */
2565 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2566 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2568 Protocol = PROTOCOL_COREPLUS;
2574 /****************************************************************************
2575 reply for the lanman 1.0 protocol
2576 ****************************************************************************/
2577 int reply_lanman1(char *outbuf)
2579 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2581 BOOL doencrypt = SMBENCRYPT();
2582 time_t t = time(NULL);
2584 if (lp_security()>=SEC_USER) secword |= 1;
2585 if (doencrypt) secword |= 2;
2587 set_message(outbuf,13,doencrypt?8:0,True);
2588 SSVAL(outbuf,smb_vwv1,secword);
2590 /* Create a token value and add it to the outgoing packet. */
2592 generate_next_challenge(smb_buf(outbuf));
2595 Protocol = PROTOCOL_LANMAN1;
2597 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2598 DEBUG(3,("using password server validation\n"));
2600 if (doencrypt) set_challenge(smb_buf(outbuf));
2604 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2605 SSVAL(outbuf,smb_vwv2,max_recv);
2606 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2607 SSVAL(outbuf,smb_vwv4,1);
2608 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2609 readbraw writebraw (possibly) */
2610 SIVAL(outbuf,smb_vwv6,getpid());
2611 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2613 put_dos_date(outbuf,smb_vwv8,t);
2615 return (smb_len(outbuf)+4);
2619 /****************************************************************************
2620 reply for the lanman 2.0 protocol
2621 ****************************************************************************/
2622 int reply_lanman2(char *outbuf)
2624 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2626 BOOL doencrypt = SMBENCRYPT();
2627 time_t t = time(NULL);
2629 if (lp_security()>=SEC_USER) secword |= 1;
2630 if (doencrypt) secword |= 2;
2632 set_message(outbuf,13,doencrypt?8:0,True);
2633 SSVAL(outbuf,smb_vwv1,secword);
2635 /* Create a token value and add it to the outgoing packet. */
2637 generate_next_challenge(smb_buf(outbuf));
2640 SIVAL(outbuf,smb_vwv6,getpid());
2642 Protocol = PROTOCOL_LANMAN2;
2644 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2645 DEBUG(3,("using password server validation\n"));
2647 if (doencrypt) set_challenge(smb_buf(outbuf));
2651 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2652 SSVAL(outbuf,smb_vwv2,max_recv);
2653 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2654 SSVAL(outbuf,smb_vwv4,1);
2655 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2656 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2657 put_dos_date(outbuf,smb_vwv8,t);
2659 return (smb_len(outbuf)+4);
2663 /****************************************************************************
2664 reply for the nt protocol
2665 ****************************************************************************/
2666 int reply_nt1(char *outbuf)
2668 /* dual names + lock_and_read + nt SMBs + remote API calls */
2669 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2671 other valid capabilities which we may support at some time...
2672 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2673 CAP_LARGE_FILES|CAP_LARGE_READX|
2674 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2678 BOOL doencrypt = SMBENCRYPT();
2679 time_t t = time(NULL);
2682 char challenge_len = 8;
2684 if (lp_readraw() && lp_writeraw())
2686 capabilities |= CAP_RAW_MODE;
2689 if (lp_security()>=SEC_USER) secword |= 1;
2690 if (doencrypt) secword |= 2;
2692 /* decide where (if) to put the encryption challenge, and
2693 follow it with the OEM'd domain name
2695 encrypt_len = doencrypt?challenge_len:0;
2697 data_len = encrypt_len + 2*(strlen(lp_workgroup())+1);
2699 data_len = encrypt_len + strlen(lp_workgroup()) + 1;
2702 set_message(outbuf,17,data_len,True);
2705 /* put the OEM'd domain name */
2706 PutUniCode(smb_buf(outbuf)+encrypt_len,lp_workgroup());
2708 strcpy(smb_buf(outbuf)+encrypt_len, lp_workgroup());
2711 CVAL(outbuf,smb_vwv1) = secword;
2713 /* Create a token value and add it to the outgoing packet. */
2716 generate_next_challenge(smb_buf(outbuf));
2718 /* Tell the nt machine how long the challenge is. */
2719 SSVALS(outbuf,smb_vwv16+1,challenge_len);
2723 Protocol = PROTOCOL_NT1;
2725 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2726 DEBUG(3,("using password server validation\n"));
2728 if (doencrypt) set_challenge(smb_buf(outbuf));
2732 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2733 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2734 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
2735 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
2736 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2737 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2738 put_long_date(outbuf+smb_vwv11+1,t);
2739 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2740 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
2742 return (smb_len(outbuf)+4);
2745 /* these are the protocol lists used for auto architecture detection:
2748 protocol [PC NETWORK PROGRAM 1.0]
2749 protocol [XENIX CORE]
2750 protocol [MICROSOFT NETWORKS 1.03]
2751 protocol [LANMAN1.0]
2752 protocol [Windows for Workgroups 3.1a]
2753 protocol [LM1.2X002]
2754 protocol [LANMAN2.1]
2755 protocol [NT LM 0.12]
2758 protocol [PC NETWORK PROGRAM 1.0]
2759 protocol [XENIX CORE]
2760 protocol [MICROSOFT NETWORKS 1.03]
2761 protocol [LANMAN1.0]
2762 protocol [Windows for Workgroups 3.1a]
2763 protocol [LM1.2X002]
2764 protocol [LANMAN2.1]
2765 protocol [NT LM 0.12]
2768 protocol [PC NETWORK PROGRAM 1.0]
2769 protocol [XENIX CORE]
2770 protocol [LANMAN1.0]
2771 protocol [LM1.2X002]
2772 protocol [LANMAN2.1]
2776 * Modified to recognize the architecture of the remote machine better.
2778 * This appears to be the matrix of which protocol is used by which
2780 Protocol WfWg Win95 WinNT OS/2
2781 PC NETWORK PROGRAM 1.0 1 1 1 1
2783 MICROSOFT NETWORKS 3.0 2 2
2785 MICROSOFT NETWORKS 1.03 3
2788 Windows for Workgroups 3.1a 5 5 5
2793 * tim@fsg.com 09/29/95
2796 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2797 #define ARCH_WIN95 0x2
2798 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2799 #define ARCH_WINNT 0x8
2800 #define ARCH_SAMBA 0x10
2802 #define ARCH_ALL 0x1F
2804 /* List of supported protocols, most desired first */
2808 int (*proto_reply_fn)(char *);
2810 } supported_protocols[] = {
2811 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2812 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2813 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2814 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2815 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2816 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2817 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2818 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2819 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2824 /****************************************************************************
2826 ****************************************************************************/
2827 static int reply_negprot(char *inbuf,char *outbuf)
2829 extern fstring remote_arch;
2830 int outsize = set_message(outbuf,1,0,True);
2835 int bcc = SVAL(smb_buf(inbuf),-2);
2836 int arch = ARCH_ALL;
2838 p = smb_buf(inbuf)+1;
2839 while (p < (smb_buf(inbuf) + bcc))
2842 DEBUG(3,("Requested protocol [%s]\n",p));
2843 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2844 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2845 else if (strcsequal(p,"DOS LM1.2X002"))
2846 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2847 else if (strcsequal(p,"DOS LANMAN2.1"))
2848 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2849 else if (strcsequal(p,"NT LM 0.12"))
2850 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2851 else if (strcsequal(p,"LANMAN2.1"))
2852 arch &= ( ARCH_WINNT | ARCH_OS2 );
2853 else if (strcsequal(p,"LM1.2X002"))
2854 arch &= ( ARCH_WINNT | ARCH_OS2 );
2855 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2857 else if (strcsequal(p,"XENIX CORE"))
2858 arch &= ( ARCH_WINNT | ARCH_OS2 );
2859 else if (strcsequal(p,"Samba")) {
2869 strcpy(remote_arch,"Samba");
2872 strcpy(remote_arch,"WfWg");
2875 strcpy(remote_arch,"Win95");
2878 strcpy(remote_arch,"WinNT");
2881 strcpy(remote_arch,"OS2");
2884 strcpy(remote_arch,"UNKNOWN");
2888 /* possibly reload - change of architecture */
2889 reload_services(True);
2891 /* a special case to stop password server loops */
2892 if (Index == 1 && strequal(remote_machine,myhostname) &&
2893 lp_security()==SEC_SERVER)
2894 exit_server("Password server loop!");
2896 /* Check for protocols, most desirable first */
2897 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2899 p = smb_buf(inbuf)+1;
2901 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2902 while (p < (smb_buf(inbuf) + bcc))
2904 if (strequal(p,supported_protocols[protocol].proto_name))
2913 SSVAL(outbuf,smb_vwv0,choice);
2915 extern fstring remote_proto;
2916 strcpy(remote_proto,supported_protocols[protocol].short_name);
2917 reload_services(True);
2918 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
2919 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
2922 DEBUG(0,("No protocol supported !\n"));
2924 SSVAL(outbuf,smb_vwv0,choice);
2926 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
2932 /****************************************************************************
2933 close all open files for a connection
2934 ****************************************************************************/
2935 static void close_open_files(int cnum)
2938 for (i=0;i<MAX_OPEN_FILES;i++)
2939 if( Files[i].cnum == cnum && Files[i].open) {
2946 /****************************************************************************
2948 ****************************************************************************/
2949 void close_cnum(int cnum, uint16 vuid)
2951 DirCacheFlush(SNUM(cnum));
2955 if (!OPEN_CNUM(cnum))
2957 DEBUG(0,("Can't close cnum %d\n",cnum));
2961 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
2963 remote_machine,client_addr(),
2964 lp_servicename(SNUM(cnum))));
2966 yield_connection(cnum,
2967 lp_servicename(SNUM(cnum)),
2968 lp_max_connections(SNUM(cnum)));
2970 if (lp_status(SNUM(cnum)))
2971 yield_connection(cnum,"STATUS.",MAXSTATUS);
2973 close_open_files(cnum);
2974 dptr_closecnum(cnum);
2976 /* execute any "postexec = " line */
2977 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
2980 strcpy(cmd,lp_postexec(SNUM(cnum)));
2981 standard_sub(cnum,cmd);
2982 smbrun(cmd,NULL,False);
2987 /* execute any "root postexec = " line */
2988 if (*lp_rootpostexec(SNUM(cnum)))
2991 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
2992 standard_sub(cnum,cmd);
2993 smbrun(cmd,NULL,False);
2996 Connections[cnum].open = False;
2997 num_connections_open--;
2998 if (Connections[cnum].ngroups && Connections[cnum].groups)
3000 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3001 free(Connections[cnum].groups);
3002 free(Connections[cnum].igroups);
3003 Connections[cnum].groups = NULL;
3004 Connections[cnum].igroups = NULL;
3005 Connections[cnum].ngroups = 0;
3008 string_set(&Connections[cnum].user,"");
3009 string_set(&Connections[cnum].dirpath,"");
3010 string_set(&Connections[cnum].connectpath,"");
3014 /****************************************************************************
3015 simple routines to do connection counting
3016 ****************************************************************************/
3017 BOOL yield_connection(int cnum,char *name,int max_connections)
3019 struct connect_record crec;
3022 int mypid = getpid();
3025 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3027 if (max_connections <= 0)
3030 bzero(&crec,sizeof(crec));
3032 strcpy(fname,lp_lockdir());
3033 standard_sub(cnum,fname);
3034 trim_string(fname,"","/");
3038 strcat(fname,".LCK");
3040 f = fopen(fname,"r+");
3043 DEBUG(2,("Coudn't open lock file %s (%s)\n",fname,strerror(errno)));
3047 fseek(f,0,SEEK_SET);
3049 /* find a free spot */
3050 for (i=0;i<max_connections;i++)
3052 if (fread(&crec,sizeof(crec),1,f) != 1)
3054 DEBUG(2,("Entry not found in lock file %s\n",fname));
3058 if (crec.pid == mypid && crec.cnum == cnum)
3062 if (crec.pid != mypid || crec.cnum != cnum)
3065 DEBUG(2,("Entry not found in lock file %s\n",fname));
3069 bzero((void *)&crec,sizeof(crec));
3071 /* remove our mark */
3072 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3073 fwrite(&crec,sizeof(crec),1,f) != 1)
3075 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3080 DEBUG(3,("Yield successful\n"));
3087 /****************************************************************************
3088 simple routines to do connection counting
3089 ****************************************************************************/
3090 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3092 struct connect_record crec;
3095 int snum = SNUM(cnum);
3099 if (max_connections <= 0)
3102 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3104 strcpy(fname,lp_lockdir());
3105 standard_sub(cnum,fname);
3106 trim_string(fname,"","/");
3108 if (!directory_exist(fname,NULL))
3113 strcat(fname,".LCK");
3115 if (!file_exist(fname,NULL))
3117 int oldmask = umask(022);
3118 f = fopen(fname,"w");
3123 total_recs = file_size(fname) / sizeof(crec);
3125 f = fopen(fname,"r+");
3129 DEBUG(1,("couldn't open lock file %s\n",fname));
3133 /* find a free spot */
3134 for (i=0;i<max_connections;i++)
3137 if (i>=total_recs ||
3138 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3139 fread(&crec,sizeof(crec),1,f) != 1)
3141 if (foundi < 0) foundi = i;
3145 if (Clear && crec.pid && !process_exists(crec.pid))
3147 fseek(f,i*sizeof(crec),SEEK_SET);
3148 bzero((void *)&crec,sizeof(crec));
3149 fwrite(&crec,sizeof(crec),1,f);
3150 if (foundi < 0) foundi = i;
3153 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3162 DEBUG(3,("no free locks in %s\n",fname));
3167 /* fill in the crec */
3168 bzero((void *)&crec,sizeof(crec));
3169 crec.magic = 0x280267;
3170 crec.pid = getpid();
3172 crec.uid = Connections[cnum].uid;
3173 crec.gid = Connections[cnum].gid;
3174 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3175 crec.start = time(NULL);
3177 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3178 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3181 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3182 fwrite(&crec,sizeof(crec),1,f) != 1)
3193 /*******************************************************************
3194 prepare to dump a core file - carefully!
3195 ********************************************************************/
3196 static BOOL dump_core(void)
3200 strcpy(dname,debugf);
3201 if ((p=strrchr(dname,'/'))) *p=0;
3202 strcat(dname,"/corefiles");
3204 sys_chown(dname,getuid(),getgid());
3206 if (chdir(dname)) return(False);
3209 #ifndef NO_GETRLIMIT
3213 getrlimit(RLIMIT_CORE, &rlp);
3214 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3215 setrlimit(RLIMIT_CORE, &rlp);
3216 getrlimit(RLIMIT_CORE, &rlp);
3217 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3223 DEBUG(0,("Dumping core in %s\n",dname));
3228 /****************************************************************************
3230 ****************************************************************************/
3231 void exit_server(char *reason)
3233 static int firsttime=1;
3236 if (!firsttime) exit(0);
3240 DEBUG(2,("Closing connections\n"));
3241 for (i=0;i<MAX_CONNECTIONS;i++)
3242 if (Connections[i].open)
3245 if (dcelogin_atmost_once)
3249 int oldlevel = DEBUGLEVEL;
3251 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3253 show_msg(last_inbuf);
3254 DEBUGLEVEL = oldlevel;
3255 DEBUG(0,("===============================================================\n"));
3257 if (dump_core()) return;
3261 #if FAST_SHARE_MODES
3262 stop_share_mode_mgmt();
3265 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3269 /****************************************************************************
3270 do some standard substitutions in a string
3271 ****************************************************************************/
3272 void standard_sub(int cnum,char *s)
3274 if (!strchr(s,'%')) return;
3276 if (VALID_CNUM(cnum))
3278 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
3279 string_sub(s,"%P",Connections[cnum].connectpath);
3280 string_sub(s,"%u",Connections[cnum].user);
3281 if (strstr(s,"%H")) {
3282 char *home = get_home_dir(Connections[cnum].user);
3283 if (home) string_sub(s,"%H",home);
3285 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
3287 standard_sub_basic(s);
3291 These flags determine some of the permissions required to do an operation
3293 Note that I don't set NEED_WRITE on some write operations because they
3294 are used by some brain-dead clients when printing, and I don't want to
3295 force write permissions on print services.
3297 #define AS_USER (1<<0)
3298 #define NEED_WRITE (1<<1)
3299 #define TIME_INIT (1<<2)
3300 #define CAN_IPC (1<<3)
3301 #define AS_GUEST (1<<5)
3305 define a list of possible SMB messages and their corresponding
3306 functions. Any message that has a NULL function is unimplemented -
3307 please feel free to contribute implementations!
3309 struct smb_message_struct
3323 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3324 {SMBtcon,"SMBtcon",reply_tcon,0},
3325 {SMBtdis,"SMBtdis",reply_tdis,0},
3326 {SMBexit,"SMBexit",reply_exit,0},
3327 {SMBioctl,"SMBioctl",reply_ioctl,0},
3328 {SMBecho,"SMBecho",reply_echo,0},
3329 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3330 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3331 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3332 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3333 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3334 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3335 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3336 {SMBopen,"SMBopen",reply_open,AS_USER},
3338 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3339 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3340 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3342 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3343 {SMBread,"SMBread",reply_read,AS_USER},
3344 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3345 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3346 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3347 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3348 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3349 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3351 /* this is a Pathworks specific call, allowing the
3352 changing of the root path */
3353 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3355 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3356 {SMBflush,"SMBflush",reply_flush,AS_USER},
3357 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3358 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3359 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3360 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3361 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3362 {SMBlock,"SMBlock",reply_lock,AS_USER},
3363 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3365 /* CORE+ PROTOCOL FOLLOWS */
3367 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3368 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3369 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3370 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3371 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3373 /* LANMAN1.0 PROTOCOL FOLLOWS */
3375 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3376 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3377 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3378 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3379 {SMBwritec,"SMBwritec",NULL,AS_USER},
3380 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3381 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3382 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3383 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3384 {SMBioctls,"SMBioctls",NULL,AS_USER},
3385 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3386 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3388 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3389 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3390 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3391 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3393 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3394 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3395 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3397 /* LANMAN2.0 PROTOCOL FOLLOWS */
3398 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3399 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3400 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3401 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3403 /* messaging routines */
3404 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3405 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3406 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3407 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3409 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3411 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3412 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3413 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3414 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3417 /****************************************************************************
3418 return a string containing the function name of a SMB command
3419 ****************************************************************************/
3420 char *smb_fn_name(int type)
3422 static char *unknown_name = "SMBunknown";
3423 static int num_smb_messages =
3424 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3427 for (match=0;match<num_smb_messages;match++)
3428 if (smb_messages[match].code == type)
3431 if (match == num_smb_messages)
3432 return(unknown_name);
3434 return(smb_messages[match].name);
3438 /****************************************************************************
3439 do a switch on the message type, and return the response size
3440 ****************************************************************************/
3441 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3445 static int num_smb_messages =
3446 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3450 struct timeval msg_start_time;
3451 struct timeval msg_end_time;
3452 static unsigned long total_time = 0;
3454 GetTimeOfDay(&msg_start_time);
3461 last_message = type;
3463 /* make sure this is an SMB packet */
3464 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3466 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3470 for (match=0;match<num_smb_messages;match++)
3471 if (smb_messages[match].code == type)
3474 if (match == num_smb_messages)
3476 DEBUG(0,("Unknown message type %d!\n",type));
3477 outsize = reply_unknown(inbuf,outbuf);
3481 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3482 if (smb_messages[match].fn)
3484 int cnum = SVAL(inbuf,smb_tid);
3485 int flags = smb_messages[match].flags;
3486 uint16 session_tag = SVAL(inbuf,smb_uid);
3488 /* does this protocol need to be run as root? */
3489 if (!(flags & AS_USER))
3492 /* does this protocol need to be run as the connected user? */
3493 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3494 if (flags & AS_GUEST)
3497 return(ERROR(ERRSRV,ERRinvnid));
3499 /* this code is to work around a bug is MS client 3 without
3500 introducing a security hole - it needs to be able to do
3501 print queue checks as guest if it isn't logged in properly */
3502 if (flags & AS_USER)
3505 /* does it need write permission? */
3506 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3507 return(ERROR(ERRSRV,ERRaccess));
3509 /* ipc services are limited */
3510 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3511 return(ERROR(ERRSRV,ERRaccess));
3513 /* load service specific parameters */
3514 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3515 return(ERROR(ERRSRV,ERRaccess));
3517 /* does this protocol need to be run as guest? */
3518 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3519 return(ERROR(ERRSRV,ERRaccess));
3523 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3527 outsize = reply_unknown(inbuf,outbuf);
3532 GetTimeOfDay(&msg_end_time);
3533 if (!(smb_messages[match].flags & TIME_INIT))
3535 smb_messages[match].time = 0;
3536 smb_messages[match].flags |= TIME_INIT;
3539 unsigned long this_time =
3540 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3541 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3542 smb_messages[match].time += this_time;
3543 total_time += this_time;
3545 DEBUG(2,("TIME %s %d usecs %g pct\n",
3546 smb_fn_name(type),smb_messages[match].time,
3547 (100.0*smb_messages[match].time) / total_time));
3554 /****************************************************************************
3555 construct a chained reply and add it to the already made reply
3556 **************************************************************************/
3557 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3559 static char *orig_inbuf;
3560 static char *orig_outbuf;
3561 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3562 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3563 char *inbuf2, *outbuf2;
3565 char inbuf_saved[smb_wct];
3566 char outbuf_saved[smb_wct];
3567 extern int chain_size;
3568 int wct = CVAL(outbuf,smb_wct);
3569 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3571 /* maybe its not chained */
3572 if (smb_com2 == 0xFF) {
3573 CVAL(outbuf,smb_vwv0) = 0xFF;
3577 if (chain_size == 0) {
3578 /* this is the first part of the chain */
3580 orig_outbuf = outbuf;
3583 /* we need to tell the client where the next part of the reply will be */
3584 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3585 CVAL(outbuf,smb_vwv0) = smb_com2;
3587 /* remember how much the caller added to the chain, only counting stuff
3588 after the parameter words */
3589 chain_size += outsize - smb_wct;
3591 /* work out pointers into the original packets. The
3592 headers on these need to be filled in */
3593 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3594 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3596 /* remember the original command type */
3597 smb_com1 = CVAL(orig_inbuf,smb_com);
3599 /* save the data which will be overwritten by the new headers */
3600 memcpy(inbuf_saved,inbuf2,smb_wct);
3601 memcpy(outbuf_saved,outbuf2,smb_wct);
3603 /* give the new packet the same header as the last part of the SMB */
3604 memmove(inbuf2,inbuf,smb_wct);
3606 /* create the in buffer */
3607 CVAL(inbuf2,smb_com) = smb_com2;
3609 /* create the out buffer */
3610 bzero(outbuf2,smb_size);
3611 set_message(outbuf2,0,0,True);
3612 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3614 memcpy(outbuf2+4,inbuf2+4,4);
3615 CVAL(outbuf2,smb_rcls) = SUCCESS;
3616 CVAL(outbuf2,smb_reh) = 0;
3617 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3619 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3620 SSVAL(outbuf2,smb_err,SUCCESS);
3621 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3622 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3623 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3624 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3626 DEBUG(3,("Chained message\n"));
3629 /* process the request */
3630 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3631 bufsize-chain_size);
3633 /* copy the new reply and request headers over the old ones, but
3634 preserve the smb_com field */
3635 memmove(orig_outbuf,outbuf2,smb_wct);
3636 CVAL(orig_outbuf,smb_com) = smb_com1;
3638 /* restore the saved data, being careful not to overwrite any
3639 data from the reply header */
3640 memcpy(inbuf2,inbuf_saved,smb_wct);
3642 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3643 if (ofs < 0) ofs = 0;
3644 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3652 /****************************************************************************
3653 construct a reply to the incoming packet
3654 ****************************************************************************/
3655 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3657 int type = CVAL(inbuf,smb_com);
3659 int msg_type = CVAL(inbuf,0);
3660 extern int chain_size;
3662 smb_last_time = time(NULL);
3667 bzero(outbuf,smb_size);
3670 return(reply_special(inbuf,outbuf));
3672 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3673 set_message(outbuf,0,0,True);
3675 memcpy(outbuf+4,inbuf+4,4);
3676 CVAL(outbuf,smb_rcls) = SUCCESS;
3677 CVAL(outbuf,smb_reh) = 0;
3678 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3680 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3681 SSVAL(outbuf,smb_err,SUCCESS);
3682 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3683 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3684 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3685 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3687 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3689 outsize += chain_size;
3692 smb_setlen(outbuf,outsize - 4);
3697 /****************************************************************************
3698 process commands from the client
3699 ****************************************************************************/
3700 static void process(void)
3702 static int trans_num = 0;
3706 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3707 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3708 if ((InBuffer == NULL) || (OutBuffer == NULL))
3711 InBuffer += SMB_ALIGNMENT;
3712 OutBuffer += SMB_ALIGNMENT;
3715 DEBUG(3,("priming nmbd\n"));
3718 ip = *interpret_addr2("localhost");
3719 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3721 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3731 int deadtime = lp_deadtime()*60;
3733 int last_keepalive=0;
3736 deadtime = DEFAULT_SMBD_TIMEOUT;
3738 if (lp_readprediction())
3739 do_read_prediction();
3742 extern pstring share_del_pending;
3743 if (*share_del_pending) {
3745 if (!unlink(share_del_pending))
3746 DEBUG(3,("Share file deleted %s\n",share_del_pending));
3748 DEBUG(2,("Share del failed of %s\n",share_del_pending));
3749 share_del_pending[0] = 0;
3753 if (share_mode_pending) {
3755 check_share_modes();
3756 share_mode_pending=False;
3761 for (counter=SMBD_SELECT_LOOP;
3762 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3763 counter += SMBD_SELECT_LOOP)
3767 BOOL allidle = True;
3768 extern int keepalive;
3770 if (smb_read_error == READ_EOF) {
3771 DEBUG(3,("end of file from client\n"));
3775 if (smb_read_error == READ_ERROR) {
3776 DEBUG(3,("receive_smb error (%s) exiting\n",
3783 /* become root again if waiting */
3786 /* check for smb.conf reload */
3787 if (!(counter%SMBD_RELOAD_CHECK))
3788 reload_services(True);
3790 /* check the share modes every 10 secs */
3791 if (!(counter%SHARE_MODES_CHECK))
3792 check_share_modes();
3794 /* clean the share modes every 5 minutes */
3795 if (!(counter%SHARE_MODES_CLEAN))
3796 clean_share_modes();
3798 /* automatic timeout if all connections are closed */
3799 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3800 DEBUG(2,("%s Closing idle connection\n",timestring()));
3804 if (keepalive && (counter-last_keepalive)>keepalive) {
3805 extern int password_client;
3806 if (!send_keepalive(Client)) {
3807 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3810 /* also send a keepalive to the password server if its still
3812 if (password_client != -1)
3813 send_keepalive(password_client);
3814 last_keepalive = counter;
3817 /* check for connection timeouts */
3818 for (i=0;i<MAX_CONNECTIONS;i++)
3819 if (Connections[i].open)
3821 /* close dirptrs on connections that are idle */
3822 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3825 if (Connections[i].num_files_open > 0 ||
3826 (t-Connections[i].lastused)<deadtime)
3830 if (allidle && num_connections_open>0) {
3831 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3836 msg_type = CVAL(InBuffer,0);
3837 msg_flags = CVAL(InBuffer,1);
3838 type = CVAL(InBuffer,smb_com);
3840 len = smb_len(InBuffer);
3842 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3846 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3849 if(trans_num == 1 && VT_Check(InBuffer)) {
3859 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
3862 if (CVAL(OutBuffer,0) == 0)
3863 show_msg(OutBuffer);
3865 if (nread != smb_len(OutBuffer) + 4)
3867 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3869 smb_len(OutBuffer)));
3872 send_smb(Client,OutBuffer);
3879 /****************************************************************************
3880 initialise connect, service and file structs
3881 ****************************************************************************/
3882 static void init_structs(void )
3885 get_myname(myhostname,NULL);
3887 for (i=0;i<MAX_CONNECTIONS;i++)
3889 Connections[i].open = False;
3890 Connections[i].num_files_open=0;
3891 Connections[i].lastused=0;
3892 Connections[i].used=False;
3893 string_init(&Connections[i].user,"");
3894 string_init(&Connections[i].dirpath,"");
3895 string_init(&Connections[i].connectpath,"");
3896 string_init(&Connections[i].origpath,"");
3899 for (i=0;i<MAX_OPEN_FILES;i++)
3901 Files[i].open = False;
3902 string_init(&Files[i].name,"");
3906 for (i=0;i<MAX_OPEN_FILES;i++)
3908 file_fd_struct *fd_ptr = &FileFd[i];
3909 fd_ptr->ref_count = 0;
3910 fd_ptr->dev = (int32)-1;
3911 fd_ptr->inode = (int32)-1;
3913 fd_ptr->fd_readonly = -1;
3914 fd_ptr->fd_writeonly = -1;
3915 fd_ptr->real_open_flags = -1;
3921 /****************************************************************************
3922 usage on the program
3923 ****************************************************************************/
3924 static void usage(char *pname)
3926 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3928 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3929 printf("Version %s\n",VERSION);
3930 printf("\t-D become a daemon\n");
3931 printf("\t-p port listen on the specified port\n");
3932 printf("\t-d debuglevel set the debuglevel\n");
3933 printf("\t-l log basename. Basename for log/debug files\n");
3934 printf("\t-s services file. Filename of services file\n");
3935 printf("\t-P passive only\n");
3936 printf("\t-a overwrite log file, don't append\n");
3941 /****************************************************************************
3943 ****************************************************************************/
3944 int main(int argc,char *argv[])
3946 extern BOOL append_log;
3947 /* shall I run as a daemon */
3948 BOOL is_daemon = False;
3949 int port = SMB_PORT;
3951 extern char *optarg;
3952 char pidFile[100] = { 0 };
3954 #ifdef NEED_AUTH_PARAMETERS
3955 set_auth_parameters(argc,argv);
3966 strcpy(debugf,SMBLOGFILE);
3968 setup_logging(argv[0],False);
3970 charset_initialise();
3972 /* make absolutely sure we run as root - to handle cases whre people
3973 are crazy enough to have it setuid */
3983 fault_setup(exit_server);
3984 signal(SIGTERM , SIGNAL_CAST dflt_sig);
3986 /* we want total control over the permissions on created files,
3987 so set our umask to 0 */
3994 /* this is for people who can't start the program correctly */
3995 while (argc > 1 && (*argv[1] != '-'))
4001 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4005 strncpy(pidFile, optarg, sizeof(pidFile));
4008 strcpy(user_socket_options,optarg);
4011 strcpy(scope,optarg);
4015 extern BOOL passive;
4020 strcpy(servicesf,optarg);
4023 strcpy(debugf,optarg);
4027 extern BOOL append_log;
4028 append_log = !append_log;
4038 DEBUGLEVEL = atoi(optarg);
4041 port = atoi(optarg);
4054 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4055 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
4057 #ifndef NO_GETRLIMIT
4058 #ifdef RLIMIT_NOFILE
4061 getrlimit(RLIMIT_NOFILE, &rlp);
4062 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4063 setrlimit(RLIMIT_NOFILE, &rlp);
4064 getrlimit(RLIMIT_NOFILE, &rlp);
4065 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4071 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4072 getuid(),getgid(),geteuid(),getegid()));
4074 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4076 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4082 if (!reload_services(False))
4085 #ifndef NO_SIGNAL_TEST
4086 signal(SIGHUP,SIGNAL_CAST sig_hup);
4089 DEBUG(3,("%s loaded services\n",timestring()));
4091 if (!is_daemon && !is_a_socket(0))
4093 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4099 DEBUG(3,("%s becoming a daemon\n",timestring()));
4108 if ((fd = open(pidFile,
4109 O_NONBLOCK | O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4111 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4114 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4116 DEBUG(0,("ERROR: smbd is already running\n"));
4119 sprintf(buf, "%u\n", (unsigned int) getpid());
4120 if (write(fd, buf, strlen(buf)) < 0)
4122 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4125 /* Leave pid file open & locked for the duration... */
4128 if (!open_sockets(is_daemon,port))
4131 #if FAST_SHARE_MODES
4132 if (!start_share_mode_mgmt())
4136 /* possibly reload the services file. */
4137 reload_services(True);
4139 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4143 if (sys_chroot(lp_rootdir()) == 0)
4144 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4150 exit_server("normal exit");