2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 extern time_t smb_last_time;
53 extern int smb_read_error;
55 extern pstring user_socket_options;
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
70 * Size of data we can send to client. Set
71 * by the client for all protocols above CORE.
72 * Set by us for CORE protocol.
74 int max_send = BUFFER_SIZE;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv = BUFFER_SIZE;
81 /* a fnum to use when chaining */
84 /* number of open connections */
85 static int num_connections_open = 0;
87 extern fstring remote_machine;
91 /* these can be set by some functions to override the error codes */
92 int unix_ERR_class=SUCCESS;
96 extern int extra_time_offset;
98 extern pstring myhostname;
100 static int find_free_connection(int hash);
102 /* for readability... */
103 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
104 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
105 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
106 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
107 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
109 /****************************************************************************
110 when exiting, take the whole family
111 ****************************************************************************/
114 exit_server("caught signal");
115 return 0; /* Keep -Wall happy :-) */
117 /****************************************************************************
118 Send a SIGTERM to our process group.
119 *****************************************************************************/
122 if(am_parent) kill(0,SIGTERM);
125 /****************************************************************************
126 change a dos mode to a unix mode
127 base permission for files:
128 everybody gets read bit set
129 dos readonly is represented in unix by removing everyone's write bit
130 dos archive is represented in unix by the user's execute bit
131 dos system is represented in unix by the group's execute bit
132 dos hidden is represented in unix by the other's execute bit
133 base permission for directories:
134 dos directory is represented in unix by unix's dir bit and the exec bit
135 ****************************************************************************/
136 mode_t unix_mode(int cnum,int dosmode)
138 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
140 if ( !IS_DOS_READONLY(dosmode) )
141 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
143 if (IS_DOS_DIR(dosmode)) {
144 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
145 result &= (lp_dir_mode(SNUM(cnum)) | 0700);
147 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
150 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
153 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
156 result &= CREATE_MODE(cnum);
162 /****************************************************************************
163 change a unix mode to a dos mode
164 ****************************************************************************/
165 int dos_mode(int cnum,char *path,struct stat *sbuf)
168 extern struct current_user current_user;
170 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
171 if (!((sbuf->st_mode & S_IWOTH) ||
172 Connections[cnum].admin_user ||
173 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
174 ((sbuf->st_mode & S_IWGRP) &&
175 in_group(sbuf->st_gid,current_user.gid,
176 current_user.ngroups,current_user.igroups))))
179 if ((sbuf->st_mode & S_IWUSR) == 0)
183 if ((sbuf->st_mode & S_IXUSR) != 0)
186 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
189 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
192 if (S_ISDIR(sbuf->st_mode))
193 result = aDIR | (result & aRONLY);
196 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
200 /* hide files with a name starting with a . */
201 if (lp_hide_dot_files(SNUM(cnum)))
203 char *p = strrchr(path,'/');
209 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
217 /*******************************************************************
218 chmod a file - but preserve some bits
219 ********************************************************************/
220 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
229 if (sys_stat(fname,st)) return(-1);
232 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
234 if (dos_mode(cnum,fname,st) == dosmode) return(0);
236 unixmode = unix_mode(cnum,dosmode);
238 /* preserve the s bits */
239 mask |= (S_ISUID | S_ISGID);
241 /* preserve the t bit */
246 /* possibly preserve the x bits */
247 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
248 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
249 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
251 unixmode |= (st->st_mode & mask);
253 /* if we previously had any r bits set then leave them alone */
254 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
255 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
259 /* if we previously had any w bits set then leave them alone
260 if the new mode is not rdonly */
261 if (!IS_DOS_READONLY(dosmode) &&
262 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
263 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
267 return(sys_chmod(fname,unixmode));
271 /****************************************************************************
272 check if two filenames are equal
274 this needs to be careful about whether we are case sensitive
275 ****************************************************************************/
276 static BOOL fname_equal(char *name1, char *name2)
278 int l1 = strlen(name1);
279 int l2 = strlen(name2);
281 /* handle filenames ending in a single dot */
282 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
286 ret = fname_equal(name1,name2);
291 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
295 ret = fname_equal(name1,name2);
300 /* now normal filename handling */
302 return(strcmp(name1,name2) == 0);
304 return(strequal(name1,name2));
308 /****************************************************************************
309 mangle the 2nd name and check if it is then equal to the first name
310 ****************************************************************************/
311 static BOOL mangled_equal(char *name1, char *name2)
315 if (is_8_3(name2, True))
318 strcpy(tmpname,name2);
319 mangle_name_83(tmpname);
321 return(strequal(name1,tmpname));
325 /****************************************************************************
326 scan a directory to find a filename, matching without case sensitivity
328 If the name looks like a mangled name then try via the mangling functions
329 ****************************************************************************/
330 static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
337 mangled = is_mangled(name);
339 /* handle null paths */
343 if (docache && (dname = DirCacheCheck(path,name,snum))) {
349 check_mangled_stack(name);
351 /* open the directory */
352 if (!(cur_dir = OpenDir(path)))
354 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
358 /* now scan for matching names */
359 while ((dname = ReadDirName(cur_dir)))
362 (strequal(dname,".") || strequal(dname,"..")))
366 if (!name_map_mangle(name2,False,snum)) continue;
368 if ((mangled && mangled_equal(name,name2))
369 || fname_equal(name, name2))
371 /* we've found the file, change it's name and return */
372 if (docache) DirCacheAdd(path,name,dname,snum);
383 /****************************************************************************
384 This routine is called to convert names from the dos namespace to unix
385 namespace. It needs to handle any case conversions, mangling, format
388 We assume that we have already done a chdir() to the right "root" directory
391 The function will return False if some part of the name except for the last
392 part cannot be resolved
394 If the saved_last_component != 0, then the unmodified last component
395 of the pathname is returned there. This is used in an exceptional
396 case in reply_mv (so far). If saved_last_component == 0 then nothing
398 ****************************************************************************/
399 BOOL unix_convert(char *name,int cnum,pstring saved_last_component)
406 if(saved_last_component)
407 *saved_last_component = 0;
409 /* convert to basic unix format - removing \ chars and cleaning it up */
411 unix_clean_name(name);
413 /* names must be relative to the root of the service - trim any leading /.
414 also trim trailing /'s */
415 trim_string(name,"/","/");
418 * Ensure saved_last_component is valid even if file exists.
420 if(saved_last_component) {
421 end = strrchr(name, '/');
423 strcpy(saved_last_component, end + 1);
425 strcpy(saved_last_component, name);
428 if (!case_sensitive &&
429 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
432 /* check if it's a printer file */
433 if (Connections[cnum].printer)
435 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
439 sprintf(name2,"%.6s.XXXXXX",remote_machine);
440 /* sanitise the name */
441 for (s=name2 ; *s ; s++)
442 if (!issafe(*s)) *s = '_';
443 strcpy(name,(char *)mktemp(name2));
448 /* stat the name - if it exists then we are all done! */
449 if (sys_stat(name,&st) == 0)
452 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
454 /* a special case - if we don't have any mangling chars and are case
455 sensitive then searching won't help */
456 if (case_sensitive && !is_mangled(name) &&
457 !lp_strip_dot() && !use_mangled_map)
460 /* now we need to recursively match the name against the real
461 directory structure */
464 while (strncmp(start,"./",2) == 0)
467 /* now match each part of the path name separately, trying the names
468 as is first, then trying to scan the directory for matching names */
469 for (;start;start = (end?end+1:(char *)NULL))
471 /* pinpoint the end of this section of the filename */
472 end = strchr(start, '/');
474 /* chop the name at this point */
477 if(saved_last_component != 0)
478 strcpy(saved_last_component, end ? end + 1 : start);
480 /* check if the name exists up to this point */
481 if (sys_stat(name, &st) == 0)
483 /* it exists. it must either be a directory or this must be
484 the last part of the path for it to be OK */
485 if (end && !(st.st_mode & S_IFDIR))
487 /* an intermediate part of the name isn't a directory */
488 DEBUG(5,("Not a dir %s\n",start));
499 /* remember the rest of the pathname so it can be restored
501 if (end) strcpy(rest,end+1);
503 /* try to find this part of the path in the directory */
504 if (strchr(start,'?') || strchr(start,'*') ||
505 !scan_directory(dirpath, start, SNUM(cnum), end?True:False))
509 /* an intermediate part of the name can't be found */
510 DEBUG(5,("Intermediate not found %s\n",start));
515 /* just the last part of the name doesn't exist */
516 /* we may need to strupper() or strlower() it in case
517 this conversion is being used for file creation
519 /* if the filename is of mixed case then don't normalise it */
520 if (!case_preserve &&
521 (!strhasupper(start) || !strhaslower(start)))
524 /* check on the mangled stack to see if we can recover the
525 base of the filename */
526 if (is_mangled(start))
527 check_mangled_stack(start);
529 DEBUG(5,("New file %s\n",start));
533 /* restore the rest of the string */
536 strcpy(start+strlen(start)+1,rest);
537 end = start + strlen(start);
541 /* add to the dirpath that we have resolved so far */
542 if (*dirpath) strcat(dirpath,"/");
543 strcat(dirpath,start);
545 /* restore the / that we wiped out earlier */
549 /* the name has been resolved */
550 DEBUG(5,("conversion finished %s\n",name));
555 /****************************************************************************
556 normalise for DOS usage
557 ****************************************************************************/
558 static void disk_norm(int *bsize,int *dfree,int *dsize)
560 /* check if the disk is beyond the max disk size */
561 int maxdisksize = lp_maxdisksize();
563 /* convert to blocks - and don't overflow */
564 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
565 if (*dsize > maxdisksize) *dsize = maxdisksize;
566 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
571 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
576 if (*bsize > WORDMAX )
579 if (*dsize > WORDMAX)
581 if (*dfree > WORDMAX)
588 /****************************************************************************
589 return number of 1K blocks available on a path and total number
590 ****************************************************************************/
591 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
593 char *df_command = lp_dfree_command();
607 if (disk_quotas(path, bsize, dfree, dsize))
609 disk_norm(bsize,dfree,dsize);
610 return(((*bsize)/1024)*(*dfree));
615 /* possibly use system() to get the result */
616 if (df_command && *df_command)
622 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
623 sprintf(syscmd,"%s %s",df_command,path);
624 standard_sub_basic(syscmd);
626 ret = smbrun(syscmd,outfile,False);
627 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
630 FILE *f = fopen(outfile,"r");
636 fscanf(f,"%d %d %d",dsize,dfree,bsize);
640 DEBUG(0,("Can't open %s\n",outfile));
644 disk_norm(bsize,dfree,dsize);
645 return(((*bsize)/1024)*(*dfree));
649 DEBUG(1,("Warning - no statfs function\n"));
653 if (statfs(path,&fs,sizeof(fs),0) != 0)
656 if (statvfs(path, &fs))
659 if (statfs(path,&fs,sizeof(fs)) == -1)
661 if (statfs(path,&fs) == -1)
663 #endif /* USE_STATVFS */
666 DEBUG(3,("dfree call failed code errno=%d\n",errno));
670 return(((*bsize)/1024)*(*dfree));
675 *dfree = fs.fd_req.bfree;
676 *dsize = fs.fd_req.btot;
679 *bsize = fs.f_frsize;
682 /* eg: osf1 has f_fsize = fundamental filesystem block size,
683 f_bsize = optimal transfer block size (MX: 94-04-19) */
688 #endif /* USE_STATVFS */
693 *dfree = fs.f_bavail;
695 *dsize = fs.f_blocks;
698 #if defined(SCO) || defined(ISC) || defined(MIPS)
702 /* handle rediculous bsize values - some OSes are broken */
703 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
705 disk_norm(bsize,dfree,dsize);
711 DEBUG(0,("dfree seems to be broken on your system\n"));
712 *dsize = 20*1024*1024/(*bsize);
713 *dfree = MAX(1,*dfree);
715 return(((*bsize)/1024)*(*dfree));
720 /****************************************************************************
721 wrap it to get filenames right
722 ****************************************************************************/
723 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
725 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
730 /****************************************************************************
731 check a filename - possibly caling reducename
733 This is called by every routine before it allows an operation on a filename.
734 It does any final confirmation necessary to ensure that the filename is
735 a valid one for the user to access.
736 ****************************************************************************/
737 BOOL check_name(char *name,int cnum)
743 if( is_vetoed_path(name))
745 DEBUG(5,("file path name %s vetoed\n",name));
749 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
751 DEBUG(5,("check_name on %s failed\n",name));
756 /****************************************************************************
757 check a filename - possibly caling reducename
758 ****************************************************************************/
759 static void check_for_pipe(char *fname)
761 /* special case of pipe opens */
765 if (strstr(s,"pipe/"))
767 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
768 unix_ERR_class = ERRSRV;
769 unix_ERR_code = ERRaccess;
773 /****************************************************************************
774 fd support routines - attempt to do a sys_open
775 ****************************************************************************/
777 int fd_attempt_open(char *fname, int flags, int mode)
779 int fd = sys_open(fname,flags,mode);
781 /* Fix for files ending in '.' */
782 if((fd == -1) && (errno == ENOENT) &&
783 (strchr(fname,'.')==NULL))
786 fd = sys_open(fname,flags,mode);
789 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
790 if ((fd == -1) && (errno == ENAMETOOLONG))
793 char *p = strrchr(fname, '/');
795 if (p == fname) /* name is "/xxx" */
797 max_len = pathconf("/", _PC_NAME_MAX);
800 else if ((p == NULL) || (p == fname))
803 max_len = pathconf(".", _PC_NAME_MAX);
808 max_len = pathconf(fname, _PC_NAME_MAX);
812 if (strlen(p) > max_len)
814 char tmp = p[max_len];
817 if ((fd = sys_open(fname,flags,mode)) == -1)
825 /****************************************************************************
826 fd support routines - attempt to find an already open file by dev
827 and inode - increments the ref_count of the returned file_fd_struct *.
828 ****************************************************************************/
829 file_fd_struct *fd_get_already_open(struct stat *sbuf)
832 file_fd_struct *fd_ptr;
837 for(i = 0; i <= max_file_fd_used; i++) {
839 if((fd_ptr->ref_count > 0) &&
840 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
841 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
844 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
845 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
852 /****************************************************************************
853 fd support routines - attempt to find a empty slot in the FileFd array.
854 Increments the ref_count of the returned entry.
855 ****************************************************************************/
856 file_fd_struct *fd_get_new()
859 file_fd_struct *fd_ptr;
861 for(i = 0; i < MAX_OPEN_FILES; i++) {
863 if(fd_ptr->ref_count == 0) {
864 fd_ptr->dev = (uint32)-1;
865 fd_ptr->inode = (uint32)-1;
867 fd_ptr->fd_readonly = -1;
868 fd_ptr->fd_writeonly = -1;
869 fd_ptr->real_open_flags = -1;
871 /* Increment max used counter if neccessary, cuts down
872 on search time when re-using */
873 if(i > max_file_fd_used)
874 max_file_fd_used = i;
875 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
876 i, fd_ptr->dev, fd_ptr->inode));
880 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
885 /****************************************************************************
886 fd support routines - attempt to re-open an already open fd as O_RDWR.
887 Save the already open fd (we cannot close due to POSIX file locking braindamage.
888 ****************************************************************************/
890 void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
892 int fd = sys_open( fname, O_RDWR, mode);
897 if(fd_ptr->real_open_flags == O_RDONLY)
898 fd_ptr->fd_readonly = fd_ptr->fd;
899 if(fd_ptr->real_open_flags == O_WRONLY)
900 fd_ptr->fd_writeonly = fd_ptr->fd;
903 fd_ptr->real_open_flags = O_RDWR;
906 /****************************************************************************
907 fd support routines - attempt to close the file referenced by this fd.
908 Decrements the ref_count and returns it.
909 ****************************************************************************/
910 int fd_attempt_close(file_fd_struct *fd_ptr)
912 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
914 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
915 fd_ptr->real_open_flags,
917 if(fd_ptr->ref_count > 0) {
919 if(fd_ptr->ref_count == 0) {
922 if(fd_ptr->fd_readonly != -1)
923 close(fd_ptr->fd_readonly);
924 if(fd_ptr->fd_writeonly != -1)
925 close(fd_ptr->fd_writeonly);
927 fd_ptr->fd_readonly = -1;
928 fd_ptr->fd_writeonly = -1;
929 fd_ptr->real_open_flags = -1;
930 fd_ptr->dev = (uint32)-1;
931 fd_ptr->inode = (uint32)-1;
934 return fd_ptr->ref_count;
937 /****************************************************************************
939 ****************************************************************************/
940 static 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--;
1038 /* We need to allocate a new file_fd_struct (this increments the
1040 if((fd_ptr = fd_get_new()) == 0)
1043 * Whatever the requested flags, attempt read/write access,
1044 * as we don't know what flags future file opens may require.
1045 * If this fails, try again with the required flags.
1046 * Even if we open read/write when only read access was
1047 * requested the setting of the can_write flag in
1048 * the file_struct will protect us from errant
1049 * write requests. We never need to worry about O_APPEND
1050 * as this is not set anywhere in Samba.
1052 fd_ptr->real_open_flags = O_RDWR;
1053 /* Set the flags as needed without the read/write modes. */
1054 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1055 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1057 * On some systems opening a file for R/W access on a read only
1058 * filesystems sets errno to EROFS.
1061 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1062 #else /* No EROFS */
1063 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1065 if(flags & O_WRONLY) {
1066 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1067 fd_ptr->real_open_flags = O_WRONLY;
1069 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1070 fd_ptr->real_open_flags = O_RDONLY;
1075 if ((fd_ptr->fd >=0) &&
1076 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1080 strcpy(dname,fname);
1081 p = strrchr(dname,'/');
1083 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1084 lp_minprintspace(SNUM(cnum))) {
1085 fd_attempt_close(fd_ptr);
1086 Files[fnum].fd_ptr = 0;
1087 if(fd_ptr->ref_count == 0)
1096 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1097 fname,strerror(errno),flags));
1098 /* Ensure the ref_count is decremented. */
1099 fd_attempt_close(fd_ptr);
1100 check_for_pipe(fname);
1104 if (fd_ptr->fd >= 0)
1108 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1109 /* Error - backout !! */
1110 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1111 fd_ptr->fd, fname,strerror(errno)));
1112 /* Ensure the ref_count is decremented. */
1113 fd_attempt_close(fd_ptr);
1118 /* Set the correct entries in fd_ptr. */
1119 fd_ptr->dev = (uint32)sbuf->st_dev;
1120 fd_ptr->inode = (uint32)sbuf->st_ino;
1122 Files[fnum].fd_ptr = fd_ptr;
1123 Connections[cnum].num_files_open++;
1124 Files[fnum].mode = sbuf->st_mode;
1125 GetTimeOfDay(&Files[fnum].open_time);
1126 Files[fnum].uid = current_user.id;
1127 Files[fnum].size = 0;
1128 Files[fnum].pos = -1;
1129 Files[fnum].open = True;
1130 Files[fnum].mmap_ptr = NULL;
1131 Files[fnum].mmap_size = 0;
1132 Files[fnum].can_lock = True;
1133 Files[fnum].can_read = ((flags & O_WRONLY)==0);
1134 Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1135 Files[fnum].share_mode = 0;
1136 Files[fnum].print_file = Connections[cnum].printer;
1137 Files[fnum].modified = False;
1138 Files[fnum].cnum = cnum;
1139 string_set(&Files[fnum].name,dos_to_unix(fname,False));
1140 Files[fnum].wbmpx_ptr = NULL;
1143 * If the printer is marked as postscript output a leading
1144 * file identifier to ensure the file is treated as a raw
1146 * This has a similar effect as CtrlD=0 in WIN.INI file.
1147 * tim@fsg.com 09/06/94
1149 if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
1150 Files[fnum].can_write)
1152 DEBUG(3,("Writing postscript line\n"));
1153 write_file(fnum,"%!\n",3);
1156 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1157 timestring(),Connections[cnum].user,fname,
1158 BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
1159 Connections[cnum].num_files_open,fnum));
1164 /* mmap it if read-only */
1165 if (!Files[fnum].can_write)
1167 Files[fnum].mmap_size = file_size(fname);
1168 Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
1169 PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
1171 if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
1173 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1174 Files[fnum].mmap_ptr = NULL;
1180 /*******************************************************************
1182 ********************************************************************/
1183 void sync_file(int fnum)
1186 fsync(Files[fnum].fd_ptr->fd);
1190 /****************************************************************************
1191 run a file if it is a magic script
1192 ****************************************************************************/
1193 static void check_magic(int fnum,int cnum)
1195 if (!*lp_magicscript(SNUM(cnum)))
1198 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1202 if (!(p = strrchr(Files[fnum].name,'/')))
1203 p = Files[fnum].name;
1207 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1213 pstring magic_output;
1215 strcpy(fname,Files[fnum].name);
1217 if (*lp_magicoutput(SNUM(cnum)))
1218 strcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1220 sprintf(magic_output,"%s.out",fname);
1223 ret = smbrun(fname,magic_output,False);
1224 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1230 /****************************************************************************
1231 close a file - possibly invalidating the read prediction
1232 ****************************************************************************/
1233 void close_file(int fnum)
1235 files_struct *fs_p = &Files[fnum];
1236 int cnum = fs_p->cnum;
1237 uint32 dev = fs_p->fd_ptr->dev;
1238 uint32 inode = fs_p->fd_ptr->inode;
1239 share_lock_token token;
1241 invalidate_read_prediction(fs_p->fd_ptr->fd);
1243 Connections[cnum].num_files_open--;
1246 free((char *)fs_p->wbmpx_ptr);
1247 fs_p->wbmpx_ptr = NULL;
1253 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1254 fs_p->mmap_ptr = NULL;
1258 if (lp_share_modes(SNUM(cnum)))
1260 lock_share_entry( cnum, dev, inode, &token);
1261 del_share_mode(token, fnum);
1264 fd_attempt_close(fs_p->fd_ptr);
1266 if (lp_share_modes(SNUM(cnum)))
1267 unlock_share_entry( cnum, dev, inode, token);
1269 /* NT uses smbclose to start a print - weird */
1270 if (fs_p->print_file)
1273 /* check for magic scripts */
1274 check_magic(fnum,cnum);
1276 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1277 timestring(),Connections[cnum].user,fs_p->name,
1278 Connections[cnum].num_files_open));
1281 enum {AFAIL,AREAD,AWRITE,AALL};
1283 /*******************************************************************
1284 reproduce the share mode access table
1285 ********************************************************************/
1286 static int access_table(int new_deny,int old_deny,int old_mode,
1287 int share_pid,char *fname)
1289 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1291 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1292 if (old_deny == new_deny && share_pid == getpid())
1295 if (old_mode == 0) return(AREAD);
1297 /* the new smbpub.zip spec says that if the file extension is
1298 .com, .dll, .exe or .sym then allow the open. I will force
1299 it to read-only as this seems sensible although the spec is
1300 a little unclear on this. */
1301 if ((fname = strrchr(fname,'.'))) {
1302 if (strequal(fname,".com") ||
1303 strequal(fname,".dll") ||
1304 strequal(fname,".exe") ||
1305 strequal(fname,".sym"))
1315 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1316 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1317 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1320 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1321 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1322 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1325 if (old_deny==DENY_WRITE) return(AREAD);
1326 if (old_deny==DENY_READ) return(AWRITE);
1327 if (old_deny==DENY_NONE) return(AALL);
1333 /*******************************************************************
1334 check if the share mode on a file allows it to be deleted or unlinked
1335 return True if sharing doesn't prevent the operation
1336 ********************************************************************/
1337 BOOL check_file_sharing(int cnum,char *fname)
1341 min_share_mode_entry *old_shares = 0;
1342 int num_share_modes;
1344 share_lock_token token;
1347 if(!lp_share_modes(SNUM(cnum)))
1350 if (stat(fname,&sbuf) == -1) return(True);
1352 lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
1353 num_share_modes = get_share_modes(cnum, token,
1354 (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
1356 for( i = 0; i < num_share_modes; i++)
1358 if (old_shares[i].share_mode != DENY_DOS)
1361 if(old_shares[i].pid != pid)
1365 /* XXXX exactly what share mode combinations should be allowed for
1366 deleting/renaming? */
1367 /* If we got here then either there were no share modes or
1368 all share modes were DENY_DOS and the pid == getpid() */
1373 unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
1374 if(old_shares != NULL)
1375 free((char *)old_shares);
1379 /****************************************************************************
1381 Helper for open_file_shared.
1382 Truncate a file after checking locking; close file if locked.
1383 **************************************************************************/
1384 static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
1387 if (Files[fnum].can_write){
1388 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1389 /* If share modes are in force for this connection we
1390 have the share entry locked. Unlock it before closing. */
1391 if (*share_locked && lp_share_modes(SNUM(cnum)))
1392 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1393 Files[fnum].fd_ptr->inode, token);
1395 /* Share mode no longer locked. */
1396 *share_locked = False;
1398 unix_ERR_class = ERRDOS;
1399 unix_ERR_code = ERRlock;
1402 ftruncate(Files[fnum].fd_ptr->fd,0);
1407 /****************************************************************************
1408 open a file with a share mode
1409 ****************************************************************************/
1410 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1411 int mode,int *Access,int *action)
1413 files_struct *fs_p = &Files[fnum];
1416 int deny_mode = (share_mode>>4)&7;
1418 BOOL file_existed = file_exist(fname,&sbuf);
1419 BOOL share_locked = False;
1420 BOOL fcbopen = False;
1421 share_lock_token token;
1428 /* this is for OS/2 EAs - try and say we don't support them */
1429 if (strstr(fname,".+,;=[]."))
1431 unix_ERR_class = ERRDOS;
1432 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1436 if ((ofun & 0x3) == 0 && file_existed)
1444 if ((ofun & 0x3) == 2)
1447 /* note that we ignore the append flag as
1448 append does not mean the same thing under dos and unix */
1450 switch (share_mode&0xF)
1467 if (flags != O_RDONLY && file_existed &&
1468 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1478 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1480 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1485 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1487 if (lp_share_modes(SNUM(cnum)))
1491 min_share_mode_entry *old_shares = 0;
1496 dev = (uint32)sbuf.st_dev;
1497 inode = (uint32)sbuf.st_ino;
1498 lock_share_entry(cnum, dev, inode, &token);
1499 share_locked = True;
1500 num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
1503 for(i = 0; i < num_shares; i++)
1505 /* someone else has a share lock on it, check to see
1507 int old_open_mode = old_shares[i].share_mode &0xF;
1508 int old_deny_mode = (old_shares[i].share_mode >>4)&7;
1510 if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2)
1512 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1513 deny_mode,old_deny_mode,old_open_mode,fname));
1514 free((char *)old_shares);
1516 unlock_share_entry(cnum, dev, inode, token);
1518 unix_ERR_class = ERRDOS;
1519 unix_ERR_code = ERRbadshare;
1524 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1525 old_shares[i].pid,fname);
1527 if ((access_allowed == AFAIL) ||
1528 (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
1529 (access_allowed == AREAD && flags == O_WRONLY) ||
1530 (access_allowed == AWRITE && flags == O_RDONLY))
1532 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1533 deny_mode,old_deny_mode,old_open_mode,
1534 old_shares[i].pid,fname,
1536 free((char *)old_shares);
1538 unlock_share_entry(cnum, dev, inode, token);
1540 unix_ERR_class = ERRDOS;
1541 unix_ERR_code = ERRbadshare;
1545 if (access_allowed == AREAD)
1548 if (access_allowed == AWRITE)
1553 free((char *)old_shares);
1556 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1557 flags,flags2,mode));
1559 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1560 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1563 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1570 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1572 /* We created the file - thus we must now lock the share entry before creating it. */
1573 dev = fs_p->fd_ptr->dev;
1574 inode = fs_p->fd_ptr->inode;
1575 lock_share_entry(cnum, dev, inode, &token);
1576 share_locked = True;
1592 fs_p->share_mode = (deny_mode<<4) | open_mode;
1595 (*Access) = open_mode;
1599 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1600 if (!file_existed) *action = 2;
1601 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1603 /* We must create the share mode entry before truncate as
1604 truncate can fail due to locking and have to close the
1605 file (which expects the share_mode_entry to be there).
1607 if (lp_share_modes(SNUM(cnum)))
1608 set_share_mode(token, fnum);
1610 if ((flags2&O_TRUNC) && file_existed)
1611 truncate_unless_locked(fnum,cnum,token,&share_locked);
1614 if (share_locked && lp_share_modes(SNUM(cnum)))
1615 unlock_share_entry( cnum, dev, inode, token);
1618 /****************************************************************************
1619 seek a file. Try to avoid the seek if possible
1620 ****************************************************************************/
1621 int seek_file(int fnum,int pos)
1624 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1627 Files[fnum].pos = lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) - offset;
1628 return(Files[fnum].pos);
1631 /****************************************************************************
1633 ****************************************************************************/
1634 int read_file(int fnum,char *data,int pos,int n)
1638 if (!Files[fnum].can_write)
1640 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1648 if (Files[fnum].mmap_ptr)
1650 int num = MIN(n,Files[fnum].mmap_size-pos);
1653 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1665 if (seek_file(fnum,pos) != pos)
1667 DEBUG(3,("Failed to seek to %d\n",pos));
1672 readret = read(Files[fnum].fd_ptr->fd,data,n);
1673 if (readret > 0) ret += readret;
1680 /****************************************************************************
1682 ****************************************************************************/
1683 int write_file(int fnum,char *data,int n)
1685 if (!Files[fnum].can_write) {
1690 if (!Files[fnum].modified) {
1692 Files[fnum].modified = True;
1693 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
1694 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
1695 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
1696 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
1701 return(write_data(Files[fnum].fd_ptr->fd,data,n));
1705 /****************************************************************************
1706 load parameters specific to a connection/service
1707 ****************************************************************************/
1708 BOOL become_service(int cnum,BOOL do_chdir)
1710 extern char magic_char;
1711 static int last_cnum = -1;
1714 if (!OPEN_CNUM(cnum))
1720 Connections[cnum].lastused = smb_last_time;
1725 ChDir(Connections[cnum].connectpath) != 0 &&
1726 ChDir(Connections[cnum].origpath) != 0)
1728 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1729 Connections[cnum].connectpath,cnum));
1733 if (cnum == last_cnum)
1738 case_default = lp_defaultcase(snum);
1739 case_preserve = lp_preservecase(snum);
1740 short_case_preserve = lp_shortpreservecase(snum);
1741 case_mangle = lp_casemangle(snum);
1742 case_sensitive = lp_casesensitive(snum);
1743 magic_char = lp_magicchar(snum);
1744 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
1749 /****************************************************************************
1750 find a service entry
1751 ****************************************************************************/
1752 int find_service(char *service)
1756 string_sub(service,"\\","/");
1758 iService = lp_servicenumber(service);
1760 /* now handle the special case of a home directory */
1763 char *phome_dir = get_home_dir(service);
1764 DEBUG(3,("checking for home directory %s gave %s\n",service,
1765 phome_dir?phome_dir:"(NULL)"));
1769 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
1771 lp_add_home(service,iHomeService,phome_dir);
1772 iService = lp_servicenumber(service);
1777 /* If we still don't have a service, attempt to add it as a printer. */
1780 int iPrinterService;
1782 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
1786 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
1788 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
1790 DEBUG(3,("%s is a valid printer name\n", service));
1791 DEBUG(3,("adding %s as a printer service\n", service));
1792 lp_add_printer(service,iPrinterService);
1793 iService = lp_servicenumber(service);
1795 DEBUG(0,("failed to add %s as a printer service!\n", service));
1798 DEBUG(3,("%s is not a valid printer name\n", service));
1802 /* just possibly it's a default service? */
1805 char *defservice = lp_defaultservice();
1806 if (defservice && *defservice && !strequal(defservice,service)) {
1807 iService = find_service(defservice);
1808 if (iService >= 0) {
1809 string_sub(service,"_","/");
1810 iService = lp_add_service(service,iService);
1816 if (!VALID_SNUM(iService))
1818 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
1823 DEBUG(3,("find_service() failed to find service %s\n", service));
1829 /****************************************************************************
1830 create an error packet from a cached error.
1831 ****************************************************************************/
1832 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
1834 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
1836 int32 eclass = wbmpx->wr_errclass;
1837 int32 err = wbmpx->wr_error;
1839 /* We can now delete the auxiliary struct */
1840 free((char *)wbmpx);
1841 Files[fnum].wbmpx_ptr = NULL;
1842 return error_packet(inbuf,outbuf,eclass,err,line);
1851 } unix_smb_errmap[] =
1853 {EPERM,ERRDOS,ERRnoaccess},
1854 {EACCES,ERRDOS,ERRnoaccess},
1855 {ENOENT,ERRDOS,ERRbadfile},
1856 {EIO,ERRHRD,ERRgeneral},
1857 {EBADF,ERRSRV,ERRsrverror},
1858 {EINVAL,ERRSRV,ERRsrverror},
1859 {EEXIST,ERRDOS,ERRfilexists},
1860 {ENFILE,ERRDOS,ERRnofids},
1861 {EMFILE,ERRDOS,ERRnofids},
1862 {ENOSPC,ERRHRD,ERRdiskfull},
1864 {EDQUOT,ERRHRD,ERRdiskfull},
1867 {ENOTEMPTY,ERRDOS,ERRnoaccess},
1870 {EXDEV,ERRDOS,ERRdiffdevice},
1872 {EROFS,ERRHRD,ERRnowrite},
1877 /****************************************************************************
1878 create an error packet from errno
1879 ****************************************************************************/
1880 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
1882 int eclass=def_class;
1886 if (unix_ERR_class != SUCCESS)
1888 eclass = unix_ERR_class;
1889 ecode = unix_ERR_code;
1890 unix_ERR_class = SUCCESS;
1895 while (unix_smb_errmap[i].smbclass != 0)
1897 if (unix_smb_errmap[i].unixerror == errno)
1899 eclass = unix_smb_errmap[i].smbclass;
1900 ecode = unix_smb_errmap[i].smbcode;
1907 return(error_packet(inbuf,outbuf,eclass,ecode,line));
1911 /****************************************************************************
1912 create an error packet. Normally called using the ERROR() macro
1913 ****************************************************************************/
1914 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
1916 int outsize = set_message(outbuf,0,0,True);
1918 cmd = CVAL(inbuf,smb_com);
1920 CVAL(outbuf,smb_rcls) = error_class;
1921 SSVAL(outbuf,smb_err,error_code);
1923 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1926 (int)CVAL(inbuf,smb_com),
1927 smb_fn_name(CVAL(inbuf,smb_com)),
1932 DEBUG(3,("error string = %s\n",strerror(errno)));
1938 #ifndef SIGCLD_IGNORE
1939 /****************************************************************************
1940 this prevents zombie child processes
1941 ****************************************************************************/
1942 static int sig_cld()
1944 static int depth = 0;
1947 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1953 BlockSignals(True,SIGCLD);
1954 DEBUG(5,("got SIGCLD\n"));
1957 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
1961 /* Stevens, Adv. Unix Prog. says that on system V you must call
1962 wait before reinstalling the signal handler, because the kernel
1963 calls the handler from within the signal-call when there is a
1964 child that has exited. This would lead to an infinite recursion
1965 if done vice versa. */
1967 #ifndef DONT_REINSTALL_SIG
1968 #ifdef SIGCLD_IGNORE
1969 signal(SIGCLD, SIG_IGN);
1971 signal(SIGCLD, SIGNAL_CAST sig_cld);
1976 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
1979 BlockSignals(False,SIGCLD);
1984 /****************************************************************************
1985 this is called when the client exits abruptly
1986 **************************************************************************/
1987 static int sig_pipe()
1989 extern int password_client;
1990 BlockSignals(True,SIGPIPE);
1992 if (password_client != -1) {
1993 DEBUG(3,("lost connection to password server\n"));
1994 close(password_client);
1995 password_client = -1;
1996 #ifndef DONT_REINSTALL_SIG
1997 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
1999 BlockSignals(False,SIGPIPE);
2003 exit_server("Got sigpipe\n");
2007 /****************************************************************************
2008 open the socket communication
2009 ****************************************************************************/
2010 static BOOL open_sockets(BOOL is_daemon,int port)
2017 struct sockaddr addr;
2018 int in_addrlen = sizeof(addr);
2021 #ifdef SIGCLD_IGNORE
2022 signal(SIGCLD, SIG_IGN);
2024 signal(SIGCLD, SIGNAL_CAST sig_cld);
2027 /* open an incoming socket */
2028 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2032 /* ready to listen */
2033 if (listen(s, 5) == -1)
2035 DEBUG(0,("listen: %s",strerror(errno)));
2043 /* now accept incoming connections - forking a new process
2044 for each incoming connection */
2045 DEBUG(2,("waiting for a connection\n"));
2048 Client = accept(s,&addr,&in_addrlen);
2050 if (Client == -1 && errno == EINTR)
2055 DEBUG(0,("accept: %s",strerror(errno)));
2059 #ifdef NO_FORK_DEBUG
2060 #ifndef NO_SIGNAL_TEST
2061 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2062 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2066 if (Client != -1 && fork()==0)
2068 /* Child code ... */
2069 #ifndef NO_SIGNAL_TEST
2070 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2071 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2073 /* close the listening socket */
2076 /* close our standard file descriptors */
2080 set_socket_options(Client,"SO_KEEPALIVE");
2081 set_socket_options(Client,user_socket_options);
2083 /* Reset global variables in util.c so that
2084 client substitutions will be done correctly
2087 reset_globals_after_fork();
2090 close(Client); /* The parent doesn't need this socket */
2096 /* We will abort gracefully when the client or remote system
2098 #ifndef NO_SIGNAL_TEST
2099 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2103 /* close our standard file descriptors */
2106 set_socket_options(Client,"SO_KEEPALIVE");
2107 set_socket_options(Client,user_socket_options);
2114 /****************************************************************************
2115 check if a snum is in use
2116 ****************************************************************************/
2117 BOOL snum_used(int snum)
2120 for (i=0;i<MAX_CONNECTIONS;i++)
2121 if (OPEN_CNUM(i) && (SNUM(i) == snum))
2126 /****************************************************************************
2127 reload the services file
2128 **************************************************************************/
2129 BOOL reload_services(BOOL test)
2136 strcpy(fname,lp_configfile());
2137 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
2139 strcpy(servicesf,fname);
2146 if (test && !lp_file_list_changed())
2149 lp_killunused(snum_used);
2151 ret = lp_load(servicesf,False);
2153 /* perhaps the config filename is now set */
2155 reload_services(True);
2164 set_socket_options(Client,"SO_KEEPALIVE");
2165 set_socket_options(Client,user_socket_options);
2169 create_mangled_stack(lp_mangledstack());
2171 /* this forces service parameters to be flushed */
2172 become_service(-1,True);
2179 /****************************************************************************
2180 this prevents zombie child processes
2181 ****************************************************************************/
2182 static int sig_hup()
2184 BlockSignals(True,SIGHUP);
2185 DEBUG(0,("Got SIGHUP\n"));
2186 reload_services(False);
2187 #ifndef DONT_REINSTALL_SIG
2188 signal(SIGHUP,SIGNAL_CAST sig_hup);
2190 BlockSignals(False,SIGHUP);
2194 /****************************************************************************
2195 Setup the groups a user belongs to.
2196 ****************************************************************************/
2197 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
2198 int **p_igroups, gid_t **p_groups)
2200 if (-1 == initgroups(user,gid))
2204 DEBUG(0,("Unable to initgroups!\n"));
2205 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
2206 DEBUG(0,("This is probably a problem with the account %s\n",user));
2214 ngroups = getgroups(0,&grp);
2217 igroups = (int *)malloc(sizeof(int)*ngroups);
2218 for (i=0;i<ngroups;i++)
2219 igroups[i] = 0x42424242;
2220 ngroups = getgroups(ngroups,(gid_t *)igroups);
2222 if (igroups[0] == 0x42424242)
2225 *p_ngroups = ngroups;
2227 /* The following bit of code is very strange. It is due to the
2228 fact that some OSes use int* and some use gid_t* for
2229 getgroups, and some (like SunOS) use both, one in prototypes,
2230 and one in man pages and the actual code. Thus we detect it
2231 dynamically using some very ugly code */
2234 /* does getgroups return ints or gid_t ?? */
2235 static BOOL groups_use_ints = True;
2237 if (groups_use_ints &&
2239 SVAL(igroups,2) == 0x4242)
2240 groups_use_ints = False;
2242 for (i=0;groups_use_ints && i<ngroups;i++)
2243 if (igroups[i] == 0x42424242)
2244 groups_use_ints = False;
2246 if (groups_use_ints)
2248 *p_igroups = igroups;
2249 *p_groups = (gid_t *)igroups;
2253 gid_t *groups = (gid_t *)igroups;
2254 igroups = (int *)malloc(sizeof(int)*ngroups);
2255 for (i=0;i<ngroups;i++)
2256 igroups[i] = groups[i];
2257 *p_igroups = igroups;
2258 *p_groups = (gid_t *)groups;
2261 DEBUG(3,("%s is in %d groups\n",user,ngroups));
2262 for (i=0;i<ngroups;i++)
2263 DEBUG(3,("%d ",igroups[i]));
2269 /****************************************************************************
2270 make a connection to a service
2271 ****************************************************************************/
2272 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
2276 struct passwd *pass = NULL;
2277 connection_struct *pcon;
2280 static BOOL first_connection = True;
2284 snum = find_service(service);
2287 if (strequal(service,"IPC$"))
2289 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2293 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
2297 if (strequal(service,HOMES_NAME))
2299 if (*user && Get_Pwnam(user,True))
2300 return(make_connection(user,user,password,pwlen,dev,vuid));
2302 if (validated_username(vuid))
2304 strcpy(user,validated_username(vuid));
2305 return(make_connection(user,user,password,pwlen,dev,vuid));
2309 if (!lp_snum_ok(snum) || !check_access(snum)) {
2313 /* you can only connect to the IPC$ service as an ipc device */
2314 if (strequal(service,"IPC$"))
2317 if (*dev == '?' || !*dev)
2319 if (lp_print_ok(snum))
2320 strcpy(dev,"LPT1:");
2325 /* if the request is as a printer and you can't print then refuse */
2327 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
2328 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2332 /* lowercase the user name */
2335 /* add it as a possible user name */
2336 add_session_user(service);
2338 /* shall we let them in? */
2339 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
2341 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
2345 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
2348 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2352 pcon = &Connections[cnum];
2353 bzero((char *)pcon,sizeof(*pcon));
2355 /* find out some info about the user */
2356 pass = Get_Pwnam(user,True);
2360 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
2364 pcon->read_only = lp_readonly(snum);
2368 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
2369 string_sub(list,"%S",service);
2371 if (user_in_list(user,list))
2372 pcon->read_only = True;
2374 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
2375 string_sub(list,"%S",service);
2377 if (user_in_list(user,list))
2378 pcon->read_only = False;
2381 /* admin user check */
2382 if (user_in_list(user,lp_admin_users(snum)) &&
2385 pcon->admin_user = True;
2386 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
2389 pcon->admin_user = False;
2391 pcon->force_user = force;
2393 pcon->uid = pass->pw_uid;
2394 pcon->gid = pass->pw_gid;
2395 pcon->num_files_open = 0;
2396 pcon->lastused = time(NULL);
2397 pcon->service = snum;
2399 pcon->printer = (strncmp(dev,"LPT",3) == 0);
2400 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
2401 pcon->dirptr = NULL;
2402 string_set(&pcon->dirpath,"");
2403 string_set(&pcon->user,user);
2406 if (*lp_force_group(snum))
2411 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
2412 /* default service may be a group name */
2413 string_sub(gname,"%S",service);
2414 gptr = (struct group *)getgrnam(gname);
2418 pcon->gid = gptr->gr_gid;
2419 DEBUG(3,("Forced group %s\n",gname));
2422 DEBUG(1,("Couldn't find group %s\n",gname));
2426 if (*lp_force_user(snum))
2428 struct passwd *pass2;
2430 strcpy(fuser,lp_force_user(snum));
2431 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
2434 pcon->uid = pass2->pw_uid;
2435 string_set(&pcon->user,fuser);
2437 pcon->force_user = True;
2438 DEBUG(3,("Forced user %s\n",fuser));
2441 DEBUG(1,("Couldn't find user %s\n",fuser));
2446 strcpy(s,lp_pathname(snum));
2447 standard_sub(cnum,s);
2448 string_set(&pcon->connectpath,s);
2449 DEBUG(3,("Connect path is %s\n",s));
2452 /* groups stuff added by ih */
2454 pcon->groups = NULL;
2458 /* Find all the groups this uid is in and store them. Used by become_user() */
2459 setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
2461 /* check number of connections */
2462 if (!claim_connection(cnum,
2463 lp_servicename(SNUM(cnum)),
2464 lp_max_connections(SNUM(cnum)),False))
2466 DEBUG(1,("too many connections - rejected\n"));
2470 if (lp_status(SNUM(cnum)))
2471 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
2473 first_connection = False;
2478 /* execute any "root preexec = " line */
2479 if (*lp_rootpreexec(SNUM(cnum)))
2482 strcpy(cmd,lp_rootpreexec(SNUM(cnum)));
2483 standard_sub(cnum,cmd);
2484 DEBUG(5,("cmd=%s\n",cmd));
2485 smbrun(cmd,NULL,False);
2488 if (!become_user(cnum,pcon->vuid))
2490 DEBUG(0,("Can't become connected user!\n"));
2492 if (!IS_IPC(cnum)) {
2493 yield_connection(cnum,
2494 lp_servicename(SNUM(cnum)),
2495 lp_max_connections(SNUM(cnum)));
2496 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2501 if (ChDir(pcon->connectpath) != 0)
2503 DEBUG(0,("Can't change directory to %s (%s)\n",
2504 pcon->connectpath,strerror(errno)));
2507 if (!IS_IPC(cnum)) {
2508 yield_connection(cnum,
2509 lp_servicename(SNUM(cnum)),
2510 lp_max_connections(SNUM(cnum)));
2511 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
2516 string_set(&pcon->origpath,pcon->connectpath);
2518 #if SOFTLINK_OPTIMISATION
2519 /* resolve any soft links early */
2522 strcpy(s,pcon->connectpath);
2524 string_set(&pcon->connectpath,s);
2525 ChDir(pcon->connectpath);
2529 num_connections_open++;
2530 add_session_user(user);
2532 /* execute any "preexec = " line */
2533 if (*lp_preexec(SNUM(cnum)))
2536 strcpy(cmd,lp_preexec(SNUM(cnum)));
2537 standard_sub(cnum,cmd);
2538 smbrun(cmd,NULL,False);
2541 /* we've finished with the sensitive stuff */
2545 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2549 lp_servicename(SNUM(cnum)),user,
2559 /****************************************************************************
2560 find first available file slot
2561 ****************************************************************************/
2562 int find_free_file(void )
2565 /* we start at 1 here for an obscure reason I can't now remember,
2566 but I think is important :-) */
2567 for (i=1;i<MAX_OPEN_FILES;i++)
2570 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2574 /****************************************************************************
2575 find first available connection slot, starting from a random position.
2576 The randomisation stops problems with the server dieing and clients
2577 thinking the server is still available.
2578 ****************************************************************************/
2579 static int find_free_connection(int hash )
2583 hash = (hash % (MAX_CONNECTIONS-2))+1;
2587 for (i=hash+1;i!=hash;)
2589 if (!Connections[i].open && Connections[i].used == used)
2591 DEBUG(3,("found free connection number %d\n",i));
2595 if (i == MAX_CONNECTIONS)
2605 DEBUG(1,("ERROR! Out of connection structures\n"));
2610 /****************************************************************************
2611 reply for the core protocol
2612 ****************************************************************************/
2613 int reply_corep(char *outbuf)
2615 int outsize = set_message(outbuf,1,0,True);
2617 Protocol = PROTOCOL_CORE;
2623 /****************************************************************************
2624 reply for the coreplus protocol
2625 ****************************************************************************/
2626 int reply_coreplus(char *outbuf)
2628 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2629 int outsize = set_message(outbuf,13,0,True);
2630 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2631 readbraw and writebraw (possibly) */
2632 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2633 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
2635 Protocol = PROTOCOL_COREPLUS;
2641 /****************************************************************************
2642 reply for the lanman 1.0 protocol
2643 ****************************************************************************/
2644 int reply_lanman1(char *outbuf)
2646 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2648 BOOL doencrypt = SMBENCRYPT();
2649 time_t t = time(NULL);
2650 /* We need to save and restore this as it can be destroyed
2651 if we call another server if security=server
2652 Thanks to Paul Nelson @ Thursby for pointing this out.
2654 uint16 mid = SVAL(outbuf, smb_mid);
2656 if (lp_security()>=SEC_USER) secword |= 1;
2657 if (doencrypt) secword |= 2;
2659 set_message(outbuf,13,doencrypt?8:0,True);
2660 SSVAL(outbuf,smb_vwv1,secword);
2662 /* Create a token value and add it to the outgoing packet. */
2664 generate_next_challenge(smb_buf(outbuf));
2667 Protocol = PROTOCOL_LANMAN1;
2669 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2670 DEBUG(3,("using password server validation\n"));
2672 if (doencrypt) set_challenge(smb_buf(outbuf));
2676 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2677 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2678 SSVAL(outbuf,smb_vwv2,max_recv);
2679 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
2680 SSVAL(outbuf,smb_vwv4,1);
2681 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
2682 readbraw writebraw (possibly) */
2683 SIVAL(outbuf,smb_vwv6,getpid());
2684 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2686 put_dos_date(outbuf,smb_vwv8,t);
2688 return (smb_len(outbuf)+4);
2692 /****************************************************************************
2693 reply for the lanman 2.0 protocol
2694 ****************************************************************************/
2695 int reply_lanman2(char *outbuf)
2697 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2699 BOOL doencrypt = SMBENCRYPT();
2700 time_t t = time(NULL);
2701 /* We need to save and restore this as it can be destroyed
2702 if we call another server if security=server
2703 Thanks to Paul Nelson @ Thursby for pointing this out.
2705 uint16 mid = SVAL(outbuf, smb_mid);
2707 if (lp_security()>=SEC_USER) secword |= 1;
2708 if (doencrypt) secword |= 2;
2710 set_message(outbuf,13,doencrypt?8:0,True);
2711 SSVAL(outbuf,smb_vwv1,secword);
2713 /* Create a token value and add it to the outgoing packet. */
2715 generate_next_challenge(smb_buf(outbuf));
2718 SIVAL(outbuf,smb_vwv6,getpid());
2720 Protocol = PROTOCOL_LANMAN2;
2722 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2723 DEBUG(3,("using password server validation\n"));
2725 if (doencrypt) set_challenge(smb_buf(outbuf));
2729 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2730 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2731 SSVAL(outbuf,smb_vwv2,max_recv);
2732 SSVAL(outbuf,smb_vwv3,lp_maxmux());
2733 SSVAL(outbuf,smb_vwv4,1);
2734 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
2735 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
2736 put_dos_date(outbuf,smb_vwv8,t);
2738 return (smb_len(outbuf)+4);
2742 /****************************************************************************
2743 reply for the nt protocol
2744 ****************************************************************************/
2745 int reply_nt1(char *outbuf)
2747 /* dual names + lock_and_read + nt SMBs + remote API calls */
2748 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
2750 other valid capabilities which we may support at some time...
2751 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2752 CAP_LARGE_FILES|CAP_LARGE_READX|
2753 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2757 BOOL doencrypt = SMBENCRYPT();
2758 time_t t = time(NULL);
2761 char challenge_len = 8;
2762 /* We need to save and restore this as it can be destroyed
2763 if we call another server if security=server
2764 Thanks to Paul Nelson @ Thursby for pointing this out.
2766 uint16 mid = SVAL(outbuf, smb_mid);
2768 if (lp_readraw() && lp_writeraw())
2770 capabilities |= CAP_RAW_MODE;
2773 if (lp_security()>=SEC_USER) secword |= 1;
2774 if (doencrypt) secword |= 2;
2776 /* decide where (if) to put the encryption challenge, and
2777 follow it with the OEM'd domain name
2779 encrypt_len = doencrypt?challenge_len:0;
2781 data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
2783 data_len = encrypt_len + strlen(myworkgroup) + 1;
2786 set_message(outbuf,17,data_len,True);
2789 /* put the OEM'd domain name */
2790 PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
2792 strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
2795 CVAL(outbuf,smb_vwv1) = secword;
2797 /* Create a token value and add it to the outgoing packet. */
2800 generate_next_challenge(smb_buf(outbuf));
2802 /* Tell the nt machine how long the challenge is. */
2803 SSVALS(outbuf,smb_vwv16+1,challenge_len);
2807 Protocol = PROTOCOL_NT1;
2809 if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
2810 DEBUG(3,("using password server validation\n"));
2812 if (doencrypt) set_challenge(smb_buf(outbuf));
2816 SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
2817 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
2818 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
2819 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
2820 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
2821 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
2822 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
2823 put_long_date(outbuf+smb_vwv11+1,t);
2824 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
2825 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
2827 return (smb_len(outbuf)+4);
2830 /* these are the protocol lists used for auto architecture detection:
2833 protocol [PC NETWORK PROGRAM 1.0]
2834 protocol [XENIX CORE]
2835 protocol [MICROSOFT NETWORKS 1.03]
2836 protocol [LANMAN1.0]
2837 protocol [Windows for Workgroups 3.1a]
2838 protocol [LM1.2X002]
2839 protocol [LANMAN2.1]
2840 protocol [NT LM 0.12]
2843 protocol [PC NETWORK PROGRAM 1.0]
2844 protocol [XENIX CORE]
2845 protocol [MICROSOFT NETWORKS 1.03]
2846 protocol [LANMAN1.0]
2847 protocol [Windows for Workgroups 3.1a]
2848 protocol [LM1.2X002]
2849 protocol [LANMAN2.1]
2850 protocol [NT LM 0.12]
2853 protocol [PC NETWORK PROGRAM 1.0]
2854 protocol [XENIX CORE]
2855 protocol [LANMAN1.0]
2856 protocol [LM1.2X002]
2857 protocol [LANMAN2.1]
2861 * Modified to recognize the architecture of the remote machine better.
2863 * This appears to be the matrix of which protocol is used by which
2865 Protocol WfWg Win95 WinNT OS/2
2866 PC NETWORK PROGRAM 1.0 1 1 1 1
2868 MICROSOFT NETWORKS 3.0 2 2
2870 MICROSOFT NETWORKS 1.03 3
2873 Windows for Workgroups 3.1a 5 5 5
2878 * tim@fsg.com 09/29/95
2881 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2882 #define ARCH_WIN95 0x2
2883 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2884 #define ARCH_WINNT 0x8
2885 #define ARCH_SAMBA 0x10
2887 #define ARCH_ALL 0x1F
2889 /* List of supported protocols, most desired first */
2893 int (*proto_reply_fn)(char *);
2895 } supported_protocols[] = {
2896 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
2897 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
2898 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2899 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2900 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
2901 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2902 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
2903 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
2904 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
2909 /****************************************************************************
2911 ****************************************************************************/
2912 static int reply_negprot(char *inbuf,char *outbuf)
2914 extern fstring remote_arch;
2915 int outsize = set_message(outbuf,1,0,True);
2920 int bcc = SVAL(smb_buf(inbuf),-2);
2921 int arch = ARCH_ALL;
2923 p = smb_buf(inbuf)+1;
2924 while (p < (smb_buf(inbuf) + bcc))
2927 DEBUG(3,("Requested protocol [%s]\n",p));
2928 if (strcsequal(p,"Windows for Workgroups 3.1a"))
2929 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
2930 else if (strcsequal(p,"DOS LM1.2X002"))
2931 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2932 else if (strcsequal(p,"DOS LANMAN2.1"))
2933 arch &= ( ARCH_WFWG | ARCH_WIN95 );
2934 else if (strcsequal(p,"NT LM 0.12"))
2935 arch &= ( ARCH_WIN95 | ARCH_WINNT );
2936 else if (strcsequal(p,"LANMAN2.1"))
2937 arch &= ( ARCH_WINNT | ARCH_OS2 );
2938 else if (strcsequal(p,"LM1.2X002"))
2939 arch &= ( ARCH_WINNT | ARCH_OS2 );
2940 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
2942 else if (strcsequal(p,"XENIX CORE"))
2943 arch &= ( ARCH_WINNT | ARCH_OS2 );
2944 else if (strcsequal(p,"Samba")) {
2954 strcpy(remote_arch,"Samba");
2957 strcpy(remote_arch,"WfWg");
2960 strcpy(remote_arch,"Win95");
2963 strcpy(remote_arch,"WinNT");
2966 strcpy(remote_arch,"OS2");
2969 strcpy(remote_arch,"UNKNOWN");
2973 /* possibly reload - change of architecture */
2974 reload_services(True);
2976 /* a special case to stop password server loops */
2977 if (Index == 1 && strequal(remote_machine,myhostname) &&
2978 lp_security()==SEC_SERVER)
2979 exit_server("Password server loop!");
2981 /* Check for protocols, most desirable first */
2982 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
2984 p = smb_buf(inbuf)+1;
2986 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
2987 while (p < (smb_buf(inbuf) + bcc))
2989 if (strequal(p,supported_protocols[protocol].proto_name))
2998 SSVAL(outbuf,smb_vwv0,choice);
3000 extern fstring remote_proto;
3001 strcpy(remote_proto,supported_protocols[protocol].short_name);
3002 reload_services(True);
3003 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3004 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3007 DEBUG(0,("No protocol supported !\n"));
3009 SSVAL(outbuf,smb_vwv0,choice);
3011 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3017 /****************************************************************************
3018 close all open files for a connection
3019 ****************************************************************************/
3020 static void close_open_files(int cnum)
3023 for (i=0;i<MAX_OPEN_FILES;i++)
3024 if( Files[i].cnum == cnum && Files[i].open) {
3031 /****************************************************************************
3033 ****************************************************************************/
3034 void close_cnum(int cnum, uint16 vuid)
3036 DirCacheFlush(SNUM(cnum));
3040 if (!OPEN_CNUM(cnum))
3042 DEBUG(0,("Can't close cnum %d\n",cnum));
3046 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3048 remote_machine,client_addr(),
3049 lp_servicename(SNUM(cnum))));
3051 yield_connection(cnum,
3052 lp_servicename(SNUM(cnum)),
3053 lp_max_connections(SNUM(cnum)));
3055 if (lp_status(SNUM(cnum)))
3056 yield_connection(cnum,"STATUS.",MAXSTATUS);
3058 close_open_files(cnum);
3059 dptr_closecnum(cnum);
3061 /* execute any "postexec = " line */
3062 if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3065 strcpy(cmd,lp_postexec(SNUM(cnum)));
3066 standard_sub(cnum,cmd);
3067 smbrun(cmd,NULL,False);
3072 /* execute any "root postexec = " line */
3073 if (*lp_rootpostexec(SNUM(cnum)))
3076 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3077 standard_sub(cnum,cmd);
3078 smbrun(cmd,NULL,False);
3081 Connections[cnum].open = False;
3082 num_connections_open--;
3083 if (Connections[cnum].ngroups && Connections[cnum].groups)
3085 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3086 free(Connections[cnum].groups);
3087 free(Connections[cnum].igroups);
3088 Connections[cnum].groups = NULL;
3089 Connections[cnum].igroups = NULL;
3090 Connections[cnum].ngroups = 0;
3093 string_set(&Connections[cnum].user,"");
3094 string_set(&Connections[cnum].dirpath,"");
3095 string_set(&Connections[cnum].connectpath,"");
3099 /****************************************************************************
3100 simple routines to do connection counting
3101 ****************************************************************************/
3102 BOOL yield_connection(int cnum,char *name,int max_connections)
3104 struct connect_record crec;
3107 int mypid = getpid();
3110 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3112 if (max_connections <= 0)
3115 bzero(&crec,sizeof(crec));
3117 strcpy(fname,lp_lockdir());
3118 standard_sub(cnum,fname);
3119 trim_string(fname,"","/");
3123 strcat(fname,".LCK");
3125 f = fopen(fname,"r+");
3128 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3132 fseek(f,0,SEEK_SET);
3134 /* find a free spot */
3135 for (i=0;i<max_connections;i++)
3137 if (fread(&crec,sizeof(crec),1,f) != 1)
3139 DEBUG(2,("Entry not found in lock file %s\n",fname));
3143 if (crec.pid == mypid && crec.cnum == cnum)
3147 if (crec.pid != mypid || crec.cnum != cnum)
3150 DEBUG(2,("Entry not found in lock file %s\n",fname));
3154 bzero((void *)&crec,sizeof(crec));
3156 /* remove our mark */
3157 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3158 fwrite(&crec,sizeof(crec),1,f) != 1)
3160 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3165 DEBUG(3,("Yield successful\n"));
3172 /****************************************************************************
3173 simple routines to do connection counting
3174 ****************************************************************************/
3175 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
3177 struct connect_record crec;
3180 int snum = SNUM(cnum);
3184 if (max_connections <= 0)
3187 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
3189 strcpy(fname,lp_lockdir());
3190 standard_sub(cnum,fname);
3191 trim_string(fname,"","/");
3193 if (!directory_exist(fname,NULL))
3198 strcat(fname,".LCK");
3200 if (!file_exist(fname,NULL))
3202 int oldmask = umask(022);
3203 f = fopen(fname,"w");
3208 total_recs = file_size(fname) / sizeof(crec);
3210 f = fopen(fname,"r+");
3214 DEBUG(1,("couldn't open lock file %s\n",fname));
3218 /* find a free spot */
3219 for (i=0;i<max_connections;i++)
3222 if (i>=total_recs ||
3223 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3224 fread(&crec,sizeof(crec),1,f) != 1)
3226 if (foundi < 0) foundi = i;
3230 if (Clear && crec.pid && !process_exists(crec.pid))
3232 fseek(f,i*sizeof(crec),SEEK_SET);
3233 bzero((void *)&crec,sizeof(crec));
3234 fwrite(&crec,sizeof(crec),1,f);
3235 if (foundi < 0) foundi = i;
3238 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
3247 DEBUG(3,("no free locks in %s\n",fname));
3252 /* fill in the crec */
3253 bzero((void *)&crec,sizeof(crec));
3254 crec.magic = 0x280267;
3255 crec.pid = getpid();
3257 crec.uid = Connections[cnum].uid;
3258 crec.gid = Connections[cnum].gid;
3259 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
3260 crec.start = time(NULL);
3262 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
3263 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
3266 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
3267 fwrite(&crec,sizeof(crec),1,f) != 1)
3278 /*******************************************************************
3279 prepare to dump a core file - carefully!
3280 ********************************************************************/
3281 static BOOL dump_core(void)
3285 strcpy(dname,debugf);
3286 if ((p=strrchr(dname,'/'))) *p=0;
3287 strcat(dname,"/corefiles");
3289 sys_chown(dname,getuid(),getgid());
3291 if (chdir(dname)) return(False);
3294 #ifndef NO_GETRLIMIT
3298 getrlimit(RLIMIT_CORE, &rlp);
3299 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
3300 setrlimit(RLIMIT_CORE, &rlp);
3301 getrlimit(RLIMIT_CORE, &rlp);
3302 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
3308 DEBUG(0,("Dumping core in %s\n",dname));
3313 /****************************************************************************
3315 ****************************************************************************/
3316 void exit_server(char *reason)
3318 static int firsttime=1;
3321 if (!firsttime) exit(0);
3325 DEBUG(2,("Closing connections\n"));
3326 for (i=0;i<MAX_CONNECTIONS;i++)
3327 if (Connections[i].open)
3330 if (dcelogin_atmost_once)
3334 int oldlevel = DEBUGLEVEL;
3336 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
3338 show_msg(last_inbuf);
3339 DEBUGLEVEL = oldlevel;
3340 DEBUG(0,("===============================================================\n"));
3342 if (dump_core()) return;
3346 #ifdef FAST_SHARE_MODES
3347 stop_share_mode_mgmt();
3348 #endif /* FAST_SHARE_MODES */
3350 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
3354 /****************************************************************************
3355 do some standard substitutions in a string
3356 ****************************************************************************/
3357 void standard_sub(int cnum,char *s)
3359 if (!strchr(s,'%')) return;
3361 if (VALID_CNUM(cnum))
3363 string_sub(s,"%S",lp_servicename(Connections[cnum].service));
3364 string_sub(s,"%P",Connections[cnum].connectpath);
3365 string_sub(s,"%u",Connections[cnum].user);
3366 if (strstr(s,"%H")) {
3367 char *home = get_home_dir(Connections[cnum].user);
3368 if (home) string_sub(s,"%H",home);
3370 string_sub(s,"%g",gidtoname(Connections[cnum].gid));
3372 standard_sub_basic(s);
3376 These flags determine some of the permissions required to do an operation
3378 Note that I don't set NEED_WRITE on some write operations because they
3379 are used by some brain-dead clients when printing, and I don't want to
3380 force write permissions on print services.
3382 #define AS_USER (1<<0)
3383 #define NEED_WRITE (1<<1)
3384 #define TIME_INIT (1<<2)
3385 #define CAN_IPC (1<<3)
3386 #define AS_GUEST (1<<5)
3390 define a list of possible SMB messages and their corresponding
3391 functions. Any message that has a NULL function is unimplemented -
3392 please feel free to contribute implementations!
3394 struct smb_message_struct
3408 {SMBnegprot,"SMBnegprot",reply_negprot,0},
3409 {SMBtcon,"SMBtcon",reply_tcon,0},
3410 {SMBtdis,"SMBtdis",reply_tdis,0},
3411 {SMBexit,"SMBexit",reply_exit,0},
3412 {SMBioctl,"SMBioctl",reply_ioctl,0},
3413 {SMBecho,"SMBecho",reply_echo,0},
3414 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
3415 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
3416 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
3417 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
3418 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
3419 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
3420 {SMBsearch,"SMBsearch",reply_search,AS_USER},
3421 {SMBopen,"SMBopen",reply_open,AS_USER},
3423 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3424 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
3425 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
3427 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
3428 {SMBread,"SMBread",reply_read,AS_USER},
3429 {SMBwrite,"SMBwrite",reply_write,AS_USER},
3430 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
3431 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
3432 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
3433 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
3434 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
3436 /* this is a Pathworks specific call, allowing the
3437 changing of the root path */
3438 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
3440 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
3441 {SMBflush,"SMBflush",reply_flush,AS_USER},
3442 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
3443 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
3444 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
3445 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
3446 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
3447 {SMBlock,"SMBlock",reply_lock,AS_USER},
3448 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
3450 /* CORE+ PROTOCOL FOLLOWS */
3452 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
3453 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
3454 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
3455 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
3456 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
3458 /* LANMAN1.0 PROTOCOL FOLLOWS */
3460 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
3461 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
3462 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
3463 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
3464 {SMBwritec,"SMBwritec",NULL,AS_USER},
3465 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
3466 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
3467 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
3468 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
3469 {SMBioctls,"SMBioctls",NULL,AS_USER},
3470 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
3471 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
3473 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
3474 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
3475 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
3476 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
3478 {SMBffirst,"SMBffirst",reply_search,AS_USER},
3479 {SMBfunique,"SMBfunique",reply_search,AS_USER},
3480 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
3482 /* LANMAN2.0 PROTOCOL FOLLOWS */
3483 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
3484 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
3485 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
3486 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
3488 /* messaging routines */
3489 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
3490 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
3491 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
3492 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
3494 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3496 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
3497 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
3498 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
3499 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
3502 /****************************************************************************
3503 return a string containing the function name of a SMB command
3504 ****************************************************************************/
3505 char *smb_fn_name(int type)
3507 static char *unknown_name = "SMBunknown";
3508 static int num_smb_messages =
3509 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3512 for (match=0;match<num_smb_messages;match++)
3513 if (smb_messages[match].code == type)
3516 if (match == num_smb_messages)
3517 return(unknown_name);
3519 return(smb_messages[match].name);
3523 /****************************************************************************
3524 do a switch on the message type, and return the response size
3525 ****************************************************************************/
3526 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
3530 static int num_smb_messages =
3531 sizeof(smb_messages) / sizeof(struct smb_message_struct);
3535 struct timeval msg_start_time;
3536 struct timeval msg_end_time;
3537 static unsigned long total_time = 0;
3539 GetTimeOfDay(&msg_start_time);
3546 last_message = type;
3548 /* make sure this is an SMB packet */
3549 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
3551 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
3555 for (match=0;match<num_smb_messages;match++)
3556 if (smb_messages[match].code == type)
3559 if (match == num_smb_messages)
3561 DEBUG(0,("Unknown message type %d!\n",type));
3562 outsize = reply_unknown(inbuf,outbuf);
3566 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
3567 if (smb_messages[match].fn)
3569 int cnum = SVAL(inbuf,smb_tid);
3570 int flags = smb_messages[match].flags;
3571 uint16 session_tag = SVAL(inbuf,smb_uid);
3573 /* does this protocol need to be run as root? */
3574 if (!(flags & AS_USER))
3577 /* does this protocol need to be run as the connected user? */
3578 if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
3579 if (flags & AS_GUEST)
3582 return(ERROR(ERRSRV,ERRinvnid));
3584 /* this code is to work around a bug is MS client 3 without
3585 introducing a security hole - it needs to be able to do
3586 print queue checks as guest if it isn't logged in properly */
3587 if (flags & AS_USER)
3590 /* does it need write permission? */
3591 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
3592 return(ERROR(ERRSRV,ERRaccess));
3594 /* ipc services are limited */
3595 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
3596 return(ERROR(ERRSRV,ERRaccess));
3598 /* load service specific parameters */
3599 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
3600 return(ERROR(ERRSRV,ERRaccess));
3602 /* does this protocol need to be run as guest? */
3603 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
3604 return(ERROR(ERRSRV,ERRaccess));
3608 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
3612 outsize = reply_unknown(inbuf,outbuf);
3617 GetTimeOfDay(&msg_end_time);
3618 if (!(smb_messages[match].flags & TIME_INIT))
3620 smb_messages[match].time = 0;
3621 smb_messages[match].flags |= TIME_INIT;
3624 unsigned long this_time =
3625 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
3626 (msg_end_time.tv_usec - msg_start_time.tv_usec);
3627 smb_messages[match].time += this_time;
3628 total_time += this_time;
3630 DEBUG(2,("TIME %s %d usecs %g pct\n",
3631 smb_fn_name(type),smb_messages[match].time,
3632 (100.0*smb_messages[match].time) / total_time));
3639 /****************************************************************************
3640 construct a chained reply and add it to the already made reply
3641 **************************************************************************/
3642 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
3644 static char *orig_inbuf;
3645 static char *orig_outbuf;
3646 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
3647 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
3648 char *inbuf2, *outbuf2;
3650 char inbuf_saved[smb_wct];
3651 char outbuf_saved[smb_wct];
3652 extern int chain_size;
3653 int wct = CVAL(outbuf,smb_wct);
3654 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
3656 /* maybe its not chained */
3657 if (smb_com2 == 0xFF) {
3658 CVAL(outbuf,smb_vwv0) = 0xFF;
3662 if (chain_size == 0) {
3663 /* this is the first part of the chain */
3665 orig_outbuf = outbuf;
3668 /* we need to tell the client where the next part of the reply will be */
3669 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
3670 CVAL(outbuf,smb_vwv0) = smb_com2;
3672 /* remember how much the caller added to the chain, only counting stuff
3673 after the parameter words */
3674 chain_size += outsize - smb_wct;
3676 /* work out pointers into the original packets. The
3677 headers on these need to be filled in */
3678 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
3679 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
3681 /* remember the original command type */
3682 smb_com1 = CVAL(orig_inbuf,smb_com);
3684 /* save the data which will be overwritten by the new headers */
3685 memcpy(inbuf_saved,inbuf2,smb_wct);
3686 memcpy(outbuf_saved,outbuf2,smb_wct);
3688 /* give the new packet the same header as the last part of the SMB */
3689 memmove(inbuf2,inbuf,smb_wct);
3691 /* create the in buffer */
3692 CVAL(inbuf2,smb_com) = smb_com2;
3694 /* create the out buffer */
3695 bzero(outbuf2,smb_size);
3696 set_message(outbuf2,0,0,True);
3697 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
3699 memcpy(outbuf2+4,inbuf2+4,4);
3700 CVAL(outbuf2,smb_rcls) = SUCCESS;
3701 CVAL(outbuf2,smb_reh) = 0;
3702 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
3704 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
3705 SSVAL(outbuf2,smb_err,SUCCESS);
3706 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
3707 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
3708 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
3709 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
3711 DEBUG(3,("Chained message\n"));
3714 /* process the request */
3715 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
3716 bufsize-chain_size);
3718 /* copy the new reply and request headers over the old ones, but
3719 preserve the smb_com field */
3720 memmove(orig_outbuf,outbuf2,smb_wct);
3721 CVAL(orig_outbuf,smb_com) = smb_com1;
3723 /* restore the saved data, being careful not to overwrite any
3724 data from the reply header */
3725 memcpy(inbuf2,inbuf_saved,smb_wct);
3727 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
3728 if (ofs < 0) ofs = 0;
3729 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
3737 /****************************************************************************
3738 construct a reply to the incoming packet
3739 ****************************************************************************/
3740 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
3742 int type = CVAL(inbuf,smb_com);
3744 int msg_type = CVAL(inbuf,0);
3745 extern int chain_size;
3747 smb_last_time = time(NULL);
3752 bzero(outbuf,smb_size);
3755 return(reply_special(inbuf,outbuf));
3757 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
3758 set_message(outbuf,0,0,True);
3760 memcpy(outbuf+4,inbuf+4,4);
3761 CVAL(outbuf,smb_rcls) = SUCCESS;
3762 CVAL(outbuf,smb_reh) = 0;
3763 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
3765 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
3766 SSVAL(outbuf,smb_err,SUCCESS);
3767 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
3768 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
3769 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
3770 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
3772 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
3774 outsize += chain_size;
3777 smb_setlen(outbuf,outsize - 4);
3782 /****************************************************************************
3783 process commands from the client
3784 ****************************************************************************/
3785 static void process(void)
3787 static int trans_num = 0;
3791 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3792 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3793 if ((InBuffer == NULL) || (OutBuffer == NULL))
3796 InBuffer += SMB_ALIGNMENT;
3797 OutBuffer += SMB_ALIGNMENT;
3800 DEBUG(3,("priming nmbd\n"));
3803 ip = *interpret_addr2("localhost");
3804 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
3806 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
3816 int deadtime = lp_deadtime()*60;
3818 int last_keepalive=0;
3821 deadtime = DEFAULT_SMBD_TIMEOUT;
3823 if (lp_readprediction())
3824 do_read_prediction();
3828 for (counter=SMBD_SELECT_LOOP;
3829 !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
3830 counter += SMBD_SELECT_LOOP)
3834 BOOL allidle = True;
3835 extern int keepalive;
3837 if (smb_read_error == READ_EOF) {
3838 DEBUG(3,("end of file from client\n"));
3842 if (smb_read_error == READ_ERROR) {
3843 DEBUG(3,("receive_smb error (%s) exiting\n",
3850 /* become root again if waiting */
3853 /* check for smb.conf reload */
3854 if (!(counter%SMBD_RELOAD_CHECK))
3855 reload_services(True);
3858 /* check the share modes every 10 secs */
3859 if (!(counter%SHARE_MODES_CHECK))
3860 check_share_modes();
3862 /* clean the share modes every 5 minutes */
3863 if (!(counter%SHARE_MODES_CLEAN))
3864 clean_share_modes();
3867 /* automatic timeout if all connections are closed */
3868 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
3869 DEBUG(2,("%s Closing idle connection\n",timestring()));
3873 if (keepalive && (counter-last_keepalive)>keepalive) {
3874 extern int password_client;
3875 if (!send_keepalive(Client)) {
3876 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3879 /* also send a keepalive to the password server if its still
3881 if (password_client != -1)
3882 send_keepalive(password_client);
3883 last_keepalive = counter;
3886 /* check for connection timeouts */
3887 for (i=0;i<MAX_CONNECTIONS;i++)
3888 if (Connections[i].open)
3890 /* close dirptrs on connections that are idle */
3891 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
3894 if (Connections[i].num_files_open > 0 ||
3895 (t-Connections[i].lastused)<deadtime)
3899 if (allidle && num_connections_open>0) {
3900 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3905 msg_type = CVAL(InBuffer,0);
3906 msg_flags = CVAL(InBuffer,1);
3907 type = CVAL(InBuffer,smb_com);
3909 len = smb_len(InBuffer);
3911 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
3915 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
3918 if(trans_num == 1 && VT_Check(InBuffer)) {
3928 nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
3931 if (CVAL(OutBuffer,0) == 0)
3932 show_msg(OutBuffer);
3934 if (nread != smb_len(OutBuffer) + 4)
3936 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3938 smb_len(OutBuffer)));
3941 send_smb(Client,OutBuffer);
3948 /****************************************************************************
3949 initialise connect, service and file structs
3950 ****************************************************************************/
3951 static void init_structs(void )
3954 get_myname(myhostname,NULL);
3956 for (i=0;i<MAX_CONNECTIONS;i++)
3958 Connections[i].open = False;
3959 Connections[i].num_files_open=0;
3960 Connections[i].lastused=0;
3961 Connections[i].used=False;
3962 string_init(&Connections[i].user,"");
3963 string_init(&Connections[i].dirpath,"");
3964 string_init(&Connections[i].connectpath,"");
3965 string_init(&Connections[i].origpath,"");
3968 for (i=0;i<MAX_OPEN_FILES;i++)
3970 Files[i].open = False;
3971 string_init(&Files[i].name,"");
3975 for (i=0;i<MAX_OPEN_FILES;i++)
3977 file_fd_struct *fd_ptr = &FileFd[i];
3978 fd_ptr->ref_count = 0;
3979 fd_ptr->dev = (int32)-1;
3980 fd_ptr->inode = (int32)-1;
3982 fd_ptr->fd_readonly = -1;
3983 fd_ptr->fd_writeonly = -1;
3984 fd_ptr->real_open_flags = -1;
3990 /****************************************************************************
3991 usage on the program
3992 ****************************************************************************/
3993 static void usage(char *pname)
3995 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
3997 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
3998 printf("Version %s\n",VERSION);
3999 printf("\t-D become a daemon\n");
4000 printf("\t-p port listen on the specified port\n");
4001 printf("\t-d debuglevel set the debuglevel\n");
4002 printf("\t-l log basename. Basename for log/debug files\n");
4003 printf("\t-s services file. Filename of services file\n");
4004 printf("\t-P passive only\n");
4005 printf("\t-a overwrite log file, don't append\n");
4010 /****************************************************************************
4012 ****************************************************************************/
4013 int main(int argc,char *argv[])
4015 extern BOOL append_log;
4016 /* shall I run as a daemon */
4017 BOOL is_daemon = False;
4018 int port = SMB_PORT;
4020 extern char *optarg;
4021 char pidFile[100] = { 0 };
4023 #ifdef NEED_AUTH_PARAMETERS
4024 set_auth_parameters(argc,argv);
4035 strcpy(debugf,SMBLOGFILE);
4037 setup_logging(argv[0],False);
4039 charset_initialise(-1);
4041 /* make absolutely sure we run as root - to handle cases whre people
4042 are crazy enough to have it setuid */
4052 fault_setup(exit_server);
4053 signal(SIGTERM , SIGNAL_CAST dflt_sig);
4055 /* we want total control over the permissions on created files,
4056 so set our umask to 0 */
4063 /* this is for people who can't start the program correctly */
4064 while (argc > 1 && (*argv[1] != '-'))
4070 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4074 strncpy(pidFile, optarg, sizeof(pidFile));
4077 strcpy(user_socket_options,optarg);
4080 strcpy(scope,optarg);
4084 extern BOOL passive;
4089 strcpy(servicesf,optarg);
4092 strcpy(debugf,optarg);
4096 extern BOOL append_log;
4097 append_log = !append_log;
4107 DEBUGLEVEL = atoi(optarg);
4110 port = atoi(optarg);
4123 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4124 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
4126 #ifndef NO_GETRLIMIT
4127 #ifdef RLIMIT_NOFILE
4130 getrlimit(RLIMIT_NOFILE, &rlp);
4131 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4132 setrlimit(RLIMIT_NOFILE, &rlp);
4133 getrlimit(RLIMIT_NOFILE, &rlp);
4134 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4140 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4141 getuid(),getgid(),geteuid(),getegid()));
4143 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4145 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4151 if (!reload_services(False))
4154 charset_initialise(lp_client_code_page());
4156 strcpy(myworkgroup, lp_workgroup());
4158 #ifndef NO_SIGNAL_TEST
4159 signal(SIGHUP,SIGNAL_CAST sig_hup);
4162 DEBUG(3,("%s loaded services\n",timestring()));
4164 if (!is_daemon && !is_a_socket(0))
4166 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4172 DEBUG(3,("%s becoming a daemon\n",timestring()));
4181 if ((fd = open(pidFile,
4182 O_NONBLOCK | O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4184 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4187 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4189 DEBUG(0,("ERROR: smbd is already running\n"));
4192 sprintf(buf, "%u\n", (unsigned int) getpid());
4193 if (write(fd, buf, strlen(buf)) < 0)
4195 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
4198 /* Leave pid file open & locked for the duration... */
4201 if (!open_sockets(is_daemon,port))
4204 #ifdef FAST_SHARE_MODES
4205 if (!start_share_mode_mgmt())
4207 #endif /* FAST_SHARE_MODES */
4209 /* possibly reload the services file. */
4210 reload_services(True);
4212 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
4216 if (sys_chroot(lp_rootdir()) == 0)
4217 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4223 exit_server("normal exit");