2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1998
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 global_myworkgroup;
29 extern pstring global_myname;
31 char *InBuffer = NULL;
32 char *OutBuffer = NULL;
33 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 time_t smb_last_time=(time_t)0;
52 extern BOOL global_machine_pasword_needs_changing;
54 extern int smb_read_error;
56 extern pstring user_socket_options;
59 extern int dcelogin_atmost_once;
63 * This is set on startup - it defines the SID for this
66 extern DOM_SID global_machine_sid;
68 connection_struct Connections[MAX_CONNECTIONS];
69 files_struct Files[MAX_FNUMS];
72 * Indirection for file fd's. Needed as POSIX locking
73 * is based on file/process, not fd/process.
75 file_fd_struct FileFd[MAX_OPEN_FILES];
76 int max_file_fd_used = 0;
81 * Size of data we can send to client. Set
82 * by the client for all protocols above CORE.
83 * Set by us for CORE protocol.
85 int max_send = BUFFER_SIZE;
87 * Size of the data we can receive. Set by us.
88 * Can be modified by the max xmit parameter.
90 int max_recv = BUFFER_SIZE;
92 /* a fnum to use when chaining */
95 /* number of open connections */
96 static int num_connections_open = 0;
98 /* Oplock ipc UDP socket. */
100 uint16 oplock_port = 0;
101 /* Current number of oplocks we have outstanding. */
102 int32 global_oplocks_open = 0;
104 BOOL global_oplock_break = False;
106 extern fstring remote_machine;
108 extern pstring OriginalDir;
110 /* these can be set by some functions to override the error codes */
111 int unix_ERR_class=SMB_SUCCESS;
115 extern int extra_time_offset;
117 extern pstring myhostname;
119 static int find_free_connection(int hash);
121 /* for readability... */
122 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
123 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
124 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
125 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
126 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
128 /****************************************************************************
129 when exiting, take the whole family
130 ****************************************************************************/
133 exit_server("caught signal");
134 return 0; /* Keep -Wall happy :-) */
136 /****************************************************************************
137 Send a SIGTERM to our process group.
138 *****************************************************************************/
141 if(am_parent) kill(0,SIGTERM);
144 /****************************************************************************
145 change a dos mode to a unix mode
146 base permission for files:
147 everybody gets read bit set
148 dos readonly is represented in unix by removing everyone's write bit
149 dos archive is represented in unix by the user's execute bit
150 dos system is represented in unix by the group's execute bit
151 dos hidden is represented in unix by the other's execute bit
152 Then apply create mask,
154 base permission for directories:
155 dos directory is represented in unix by unix's dir bit and the exec bit
156 Then apply create mask,
158 ****************************************************************************/
159 mode_t unix_mode(int cnum,int dosmode)
161 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
163 if ( !IS_DOS_READONLY(dosmode) )
164 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
166 if (IS_DOS_DIR(dosmode)) {
167 /* We never make directories read only for the owner as under DOS a user
168 can always create a file in a read-only directory. */
169 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
170 /* Apply directory mask */
171 result &= lp_dir_mode(SNUM(cnum));
172 /* Add in force bits */
173 result |= lp_force_dir_mode(SNUM(cnum));
175 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
178 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
181 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
184 /* Apply mode mask */
185 result &= lp_create_mode(SNUM(cnum));
186 /* Add in force bits */
187 result |= lp_force_create_mode(SNUM(cnum));
193 /****************************************************************************
194 change a unix mode to a dos mode
195 ****************************************************************************/
196 int dos_mode(int cnum,char *path,struct stat *sbuf)
199 extern struct current_user current_user;
201 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
203 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
204 if (!((sbuf->st_mode & S_IWOTH) ||
205 Connections[cnum].admin_user ||
206 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
207 ((sbuf->st_mode & S_IWGRP) &&
208 in_group(sbuf->st_gid,current_user.gid,
209 current_user.ngroups,current_user.igroups))))
212 if ((sbuf->st_mode & S_IWUSR) == 0)
216 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
219 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
222 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
225 if (S_ISDIR(sbuf->st_mode))
226 result = aDIR | (result & aRONLY);
230 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
235 /* hide files with a name starting with a . */
236 if (lp_hide_dot_files(SNUM(cnum)))
238 char *p = strrchr(path,'/');
244 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
248 /* Optimization : Only call is_hidden_path if it's not already
250 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
255 DEBUG(8,("dos_mode returning "));
257 if (result & aHIDDEN) DEBUG(8, ("h"));
258 if (result & aRONLY ) DEBUG(8, ("r"));
259 if (result & aSYSTEM) DEBUG(8, ("s"));
260 if (result & aDIR ) DEBUG(8, ("d"));
261 if (result & aARCH ) DEBUG(8, ("a"));
268 /*******************************************************************
269 chmod a file - but preserve some bits
270 ********************************************************************/
271 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
280 if (sys_stat(fname,st)) return(-1);
283 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
285 if (dos_mode(cnum,fname,st) == dosmode) return(0);
287 unixmode = unix_mode(cnum,dosmode);
289 /* preserve the s bits */
290 mask |= (S_ISUID | S_ISGID);
292 /* preserve the t bit */
297 /* possibly preserve the x bits */
298 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
299 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
300 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
302 unixmode |= (st->st_mode & mask);
304 /* if we previously had any r bits set then leave them alone */
305 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
306 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
310 /* if we previously had any w bits set then leave them alone
311 if the new mode is not rdonly */
312 if (!IS_DOS_READONLY(dosmode) &&
313 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
314 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
318 return(sys_chmod(fname,unixmode));
321 /*******************************************************************
322 Wrapper around sys_utime that possibly allows DOS semantics rather
324 *******************************************************************/
326 int file_utime(int cnum, char *fname, struct utimbuf *times)
328 extern struct current_user current_user;
334 if(sys_utime(fname, times) == 0)
337 if((errno != EPERM) && (errno != EACCES))
340 if(!lp_dos_filetimes(SNUM(cnum)))
343 /* We have permission (given by the Samba admin) to
344 break POSIX semantics and allow a user to change
345 the time on a file they don't own but can write to
349 if(sys_stat(fname,&sb) != 0)
352 /* Check if we have write access. */
353 if (CAN_WRITE(cnum)) {
354 if (((sb.st_mode & S_IWOTH) ||
355 Connections[cnum].admin_user ||
356 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
357 ((sb.st_mode & S_IWGRP) &&
358 in_group(sb.st_gid,current_user.gid,
359 current_user.ngroups,current_user.igroups)))) {
360 /* We are allowed to become root and change the filetime. */
362 ret = sys_utime(fname, times);
363 unbecome_root(False);
370 /*******************************************************************
371 Change a filetime - possibly allowing DOS semantics.
372 *******************************************************************/
374 BOOL set_filetime(int cnum, char *fname, time_t mtime)
376 struct utimbuf times;
378 if (null_mtime(mtime)) return(True);
380 times.modtime = times.actime = mtime;
382 if (file_utime(cnum, fname, ×)) {
383 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
389 /****************************************************************************
390 check if two filenames are equal
392 this needs to be careful about whether we are case sensitive
393 ****************************************************************************/
394 static BOOL fname_equal(char *name1, char *name2)
396 int l1 = strlen(name1);
397 int l2 = strlen(name2);
399 /* handle filenames ending in a single dot */
400 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
404 ret = fname_equal(name1,name2);
409 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
413 ret = fname_equal(name1,name2);
418 /* now normal filename handling */
420 return(strcmp(name1,name2) == 0);
422 return(strequal(name1,name2));
426 /****************************************************************************
427 mangle the 2nd name and check if it is then equal to the first name
428 ****************************************************************************/
429 static BOOL mangled_equal(char *name1, char *name2)
433 if (is_8_3(name2, True))
436 pstrcpy(tmpname,name2);
437 mangle_name_83(tmpname,sizeof(tmpname));
439 return(strequal(name1,tmpname));
443 /****************************************************************************
444 scan a directory to find a filename, matching without case sensitivity
446 If the name looks like a mangled name then try via the mangling functions
447 ****************************************************************************/
448 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
455 mangled = is_mangled(name);
457 /* handle null paths */
461 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
462 pstrcpy(name, dname);
467 * The incoming name can be mangled, and if we de-mangle it
468 * here it will not compare correctly against the filename (name2)
469 * read from the directory and then mangled by the name_map_mangle()
470 * call. We need to mangle both names or neither.
474 mangled = !check_mangled_cache( name );
476 /* open the directory */
477 if (!(cur_dir = OpenDir(cnum, path, True)))
479 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
483 /* now scan for matching names */
484 while ((dname = ReadDirName(cur_dir)))
487 (strequal(dname,".") || strequal(dname,"..")))
490 pstrcpy(name2,dname);
491 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
493 if ((mangled && mangled_equal(name,name2))
494 || fname_equal(name, name2))
496 /* we've found the file, change it's name and return */
497 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
498 pstrcpy(name, dname);
508 /****************************************************************************
509 This routine is called to convert names from the dos namespace to unix
510 namespace. It needs to handle any case conversions, mangling, format
513 We assume that we have already done a chdir() to the right "root" directory
516 The function will return False if some part of the name except for the last
517 part cannot be resolved
519 If the saved_last_component != 0, then the unmodified last component
520 of the pathname is returned there. This is used in an exceptional
521 case in reply_mv (so far). If saved_last_component == 0 then nothing
524 The bad_path arg is set to True if the filename walk failed. This is
525 used to pick the correct error code to return between ENOENT and ENOTDIR
526 as Windows applications depend on ERRbadpath being returned if a component
527 of a pathname does not exist.
528 ****************************************************************************/
529 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
539 if(saved_last_component)
540 *saved_last_component = 0;
542 /* convert to basic unix format - removing \ chars and cleaning it up */
544 unix_clean_name(name);
546 /* names must be relative to the root of the service - trim any leading /.
547 also trim trailing /'s */
548 trim_string(name,"/","/");
551 * Ensure saved_last_component is valid even if file exists.
553 if(saved_last_component) {
554 end = strrchr(name, '/');
556 pstrcpy(saved_last_component, end + 1);
558 pstrcpy(saved_last_component, name);
561 if (!case_sensitive &&
562 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
565 /* check if it's a printer file */
566 if (Connections[cnum].printer)
568 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
572 slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
573 /* sanitise the name */
574 for (s=name2 ; *s ; s++)
575 if (!issafe(*s)) *s = '_';
576 pstrcpy(name,(char *)mktemp(name2));
581 /* stat the name - if it exists then we are all done! */
582 if (sys_stat(name,&st) == 0)
587 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
589 /* a special case - if we don't have any mangling chars and are case
590 sensitive then searching won't help */
591 if (case_sensitive && !is_mangled(name) &&
592 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
595 /* now we need to recursively match the name against the real
596 directory structure */
599 while (strncmp(start,"./",2) == 0)
602 /* now match each part of the path name separately, trying the names
603 as is first, then trying to scan the directory for matching names */
604 for (;start;start = (end?end+1:(char *)NULL))
606 /* pinpoint the end of this section of the filename */
607 end = strchr(start, '/');
609 /* chop the name at this point */
612 if(saved_last_component != 0)
613 pstrcpy(saved_last_component, end ? end + 1 : start);
615 /* check if the name exists up to this point */
616 if (sys_stat(name, &st) == 0)
618 /* it exists. it must either be a directory or this must be
619 the last part of the path for it to be OK */
620 if (end && !(st.st_mode & S_IFDIR))
622 /* an intermediate part of the name isn't a directory */
623 DEBUG(5,("Not a dir %s\n",start));
634 /* remember the rest of the pathname so it can be restored
636 if (end) pstrcpy(rest,end+1);
638 /* try to find this part of the path in the directory */
639 if (strchr(start,'?') || strchr(start,'*') ||
640 !scan_directory(dirpath, start, cnum, end?True:False))
644 /* an intermediate part of the name can't be found */
645 DEBUG(5,("Intermediate not found %s\n",start));
647 /* We need to return the fact that the intermediate
648 name resolution failed. This is used to return an
649 error of ERRbadpath rather than ERRbadfile. Some
650 Windows applications depend on the difference between
657 /* just the last part of the name doesn't exist */
658 /* we may need to strupper() or strlower() it in case
659 this conversion is being used for file creation
661 /* if the filename is of mixed case then don't normalise it */
662 if (!case_preserve &&
663 (!strhasupper(start) || !strhaslower(start)))
666 /* check on the mangled stack to see if we can recover the
667 base of the filename */
668 if (is_mangled(start))
669 check_mangled_cache( start );
671 DEBUG(5,("New file %s\n",start));
675 /* restore the rest of the string */
678 pstrcpy(start+strlen(start)+1,rest);
679 end = start + strlen(start);
683 /* add to the dirpath that we have resolved so far */
684 if (*dirpath) pstrcat(dirpath,"/");
685 pstrcat(dirpath,start);
687 /* restore the / that we wiped out earlier */
691 /* the name has been resolved */
692 DEBUG(5,("conversion finished %s\n",name));
697 /****************************************************************************
698 check a filename - possibly caling reducename
700 This is called by every routine before it allows an operation on a filename.
701 It does any final confirmation necessary to ensure that the filename is
702 a valid one for the user to access.
703 ****************************************************************************/
704 BOOL check_name(char *name,int cnum)
710 if( IS_VETO_PATH(cnum, name))
712 DEBUG(5,("file path name %s vetoed\n",name));
716 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
718 /* Check if we are allowing users to follow symlinks */
719 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
720 University of Geneva */
723 if (!lp_symlinks(SNUM(cnum)))
726 if ( (sys_lstat(name,&statbuf) != -1) &&
727 (S_ISLNK(statbuf.st_mode)) )
729 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
736 DEBUG(5,("check_name on %s failed\n",name));
741 /****************************************************************************
742 check a filename - possibly caling reducename
743 ****************************************************************************/
744 static void check_for_pipe(char *fname)
746 /* special case of pipe opens */
750 if (strstr(s,"pipe/"))
752 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
753 unix_ERR_class = ERRSRV;
754 unix_ERR_code = ERRaccess;
758 /****************************************************************************
759 fd support routines - attempt to do a sys_open
760 ****************************************************************************/
761 static int fd_attempt_open(char *fname, int flags, int mode)
763 int fd = sys_open(fname,flags,mode);
765 /* Fix for files ending in '.' */
766 if((fd == -1) && (errno == ENOENT) &&
767 (strchr(fname,'.')==NULL))
770 fd = sys_open(fname,flags,mode);
773 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
774 if ((fd == -1) && (errno == ENAMETOOLONG))
777 char *p = strrchr(fname, '/');
779 if (p == fname) /* name is "/xxx" */
781 max_len = pathconf("/", _PC_NAME_MAX);
784 else if ((p == NULL) || (p == fname))
787 max_len = pathconf(".", _PC_NAME_MAX);
792 max_len = pathconf(fname, _PC_NAME_MAX);
796 if (strlen(p) > max_len)
798 char tmp = p[max_len];
801 if ((fd = sys_open(fname,flags,mode)) == -1)
809 /****************************************************************************
810 Cache a uid_t currently with this file open. This is an optimization only
811 used when multiple sessionsetup's have been done to one smbd.
812 ****************************************************************************/
813 static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
815 if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
817 fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
820 /****************************************************************************
821 Remove a uid_t that currently has this file open. This is an optimization only
822 used when multiple sessionsetup's have been done to one smbd.
823 ****************************************************************************/
824 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
827 for(i = 0; i < fd_ptr->uid_cache_count; i++)
828 if(fd_ptr->uid_users_cache[i] == u) {
829 if(i < (fd_ptr->uid_cache_count-1))
830 memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
831 sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
832 fd_ptr->uid_cache_count--;
837 /****************************************************************************
838 Check if a uid_t that currently has this file open is present. This is an
839 optimization only used when multiple sessionsetup's have been done to one smbd.
840 ****************************************************************************/
841 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
844 for(i = 0; i < fd_ptr->uid_cache_count; i++)
845 if(fd_ptr->uid_users_cache[i] == u)
850 /****************************************************************************
851 fd support routines - attempt to find an already open file by dev
852 and inode - increments the ref_count of the returned file_fd_struct *.
853 ****************************************************************************/
854 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
857 file_fd_struct *fd_ptr;
862 for(i = 0; i <= max_file_fd_used; i++) {
864 if((fd_ptr->ref_count > 0) &&
865 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
866 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
869 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
870 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
877 /****************************************************************************
878 fd support routines - attempt to find a empty slot in the FileFd array.
879 Increments the ref_count of the returned entry.
880 ****************************************************************************/
881 static file_fd_struct *fd_get_new(void)
883 extern struct current_user current_user;
885 file_fd_struct *fd_ptr;
887 for(i = 0; i < MAX_OPEN_FILES; i++) {
889 if(fd_ptr->ref_count == 0) {
890 fd_ptr->dev = (uint32)-1;
891 fd_ptr->inode = (uint32)-1;
893 fd_ptr->fd_readonly = -1;
894 fd_ptr->fd_writeonly = -1;
895 fd_ptr->real_open_flags = -1;
896 fd_ptr->uid_cache_count = 0;
897 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
899 /* Increment max used counter if neccessary, cuts down
900 on search time when re-using */
901 if(i > max_file_fd_used)
902 max_file_fd_used = i;
903 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
904 i, fd_ptr->dev, fd_ptr->inode));
908 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
912 /****************************************************************************
913 fd support routines - attempt to re-open an already open fd as O_RDWR.
914 Save the already open fd (we cannot close due to POSIX file locking braindamage.
915 ****************************************************************************/
916 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
918 int fd = sys_open( fname, O_RDWR, mode);
923 if(fd_ptr->real_open_flags == O_RDONLY)
924 fd_ptr->fd_readonly = fd_ptr->fd;
925 if(fd_ptr->real_open_flags == O_WRONLY)
926 fd_ptr->fd_writeonly = fd_ptr->fd;
929 fd_ptr->real_open_flags = O_RDWR;
932 /****************************************************************************
933 fd support routines - attempt to close the file referenced by this fd.
934 Decrements the ref_count and returns it.
935 ****************************************************************************/
936 static int fd_attempt_close(file_fd_struct *fd_ptr)
938 extern struct current_user current_user;
940 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
942 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
943 fd_ptr->real_open_flags,
945 if(fd_ptr->ref_count > 0) {
947 if(fd_ptr->ref_count == 0) {
950 if(fd_ptr->fd_readonly != -1)
951 close(fd_ptr->fd_readonly);
952 if(fd_ptr->fd_writeonly != -1)
953 close(fd_ptr->fd_writeonly);
955 fd_ptr->fd_readonly = -1;
956 fd_ptr->fd_writeonly = -1;
957 fd_ptr->real_open_flags = -1;
958 fd_ptr->dev = (uint32)-1;
959 fd_ptr->inode = (uint32)-1;
960 fd_ptr->uid_cache_count = 0;
962 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
964 return fd_ptr->ref_count;
967 /****************************************************************************
968 fd support routines - check that current user has permissions
969 to open this file. Used when uid not found in optimization cache.
970 This is really ugly code, as due to POSIX locking braindamage we must
971 fork and then attempt to open the file, and return success or failure
973 ****************************************************************************/
974 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
978 if((child_pid = fork()) < 0) {
979 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
989 if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
990 DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
994 if (child_pid != wpid) {
995 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
998 #if defined(WIFEXITED) && defined(WEXITSTATUS)
999 if (WIFEXITED(status_code) == 0) {
1000 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
1003 if (WEXITSTATUS(status_code) != 0) {
1004 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1007 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1008 if(status_code != 0) {
1009 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1012 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1015 * Success - the child could open the file.
1017 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
1024 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
1025 if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
1026 /* Access denied. */
1030 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
1037 /****************************************************************************
1039 ****************************************************************************/
1040 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1042 extern struct current_user current_user;
1044 struct stat statbuf;
1045 file_fd_struct *fd_ptr;
1046 files_struct *fsp = &Files[fnum];
1047 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1051 fsp->granted_oplock = False;
1054 pstrcpy(fname,fname1);
1056 /* check permissions */
1059 * This code was changed after seeing a client open request
1060 * containing the open mode of (DENY_WRITE/read-only) with
1061 * the 'create if not exist' bit set. The previous code
1062 * would fail to open the file read only on a read-only share
1063 * as it was checking the flags parameter directly against O_RDONLY,
1064 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1068 if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1069 /* It's a read-only share - fail if we wanted to write. */
1070 if(accmode != O_RDONLY) {
1071 DEBUG(3,("Permission denied opening %s\n",fname));
1072 check_for_pipe(fname);
1075 else if(flags & O_CREAT) {
1076 /* We don't want to write - but we must make sure that O_CREAT
1077 doesn't create the file if we have write access into the
1084 /* this handles a bug in Win95 - it doesn't say to create the file when it
1086 if (Connections[cnum].printer)
1090 if (flags == O_WRONLY)
1091 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1095 * Ensure we have a valid struct stat so we can search the
1099 if(sys_stat(fname, &statbuf) < 0) {
1100 if(errno != ENOENT) {
1101 DEBUG(3,("Error doing stat on file %s (%s)\n",
1102 fname,strerror(errno)));
1104 check_for_pipe(fname);
1114 * Check to see if we have this file already
1115 * open. If we do, just use the already open fd and increment the
1116 * reference count (fd_get_already_open increments the ref_count).
1118 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1120 * File was already open.
1124 * Check it wasn't open for exclusive use.
1126 if((flags & O_CREAT) && (flags & O_EXCL)) {
1127 fd_ptr->ref_count--;
1133 * Ensure that the user attempting to open
1134 * this file has permissions to do so, if
1135 * the user who originally opened the file wasn't
1136 * the same as the current user.
1139 if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
1140 if(!check_access_allowed_for_current_user( fname, accmode )) {
1141 /* Error - permission denied. */
1142 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
1143 fname, flags, accmode));
1144 /* Ensure the ref_count is decremented. */
1145 fd_ptr->ref_count--;
1146 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1152 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
1155 * If not opened O_RDWR try
1156 * and do that here - a chmod may have been done
1157 * between the last open and now.
1159 if(fd_ptr->real_open_flags != O_RDWR)
1160 fd_attempt_reopen(fname, mode, fd_ptr);
1163 * Ensure that if we wanted write access
1164 * it has been opened for write, and if we wanted read it
1165 * was open for read.
1167 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1168 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1169 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1170 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1171 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1172 check_for_pipe(fname);
1173 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1174 fd_ptr->ref_count--;
1180 /* We need to allocate a new file_fd_struct (this increments the
1182 if((fd_ptr = fd_get_new()) == 0)
1185 * Whatever the requested flags, attempt read/write access,
1186 * as we don't know what flags future file opens may require.
1187 * If this fails, try again with the required flags.
1188 * Even if we open read/write when only read access was
1189 * requested the setting of the can_write flag in
1190 * the file_struct will protect us from errant
1191 * write requests. We never need to worry about O_APPEND
1192 * as this is not set anywhere in Samba.
1194 fd_ptr->real_open_flags = O_RDWR;
1195 /* Set the flags as needed without the read/write modes. */
1196 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1197 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1199 * On some systems opening a file for R/W access on a read only
1200 * filesystems sets errno to EROFS.
1203 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1204 #else /* No EROFS */
1205 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1207 if(accmode != O_RDWR) {
1208 fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
1209 fd_ptr->real_open_flags = accmode;
1214 if ((fd_ptr->fd >=0) &&
1215 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1219 pstrcpy(dname,fname);
1220 p = strrchr(dname,'/');
1222 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1223 lp_minprintspace(SNUM(cnum))) {
1224 fd_attempt_close(fd_ptr);
1226 if(fd_ptr->ref_count == 0)
1235 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1236 fname,strerror(errno),flags));
1237 /* Ensure the ref_count is decremented. */
1238 fd_attempt_close(fd_ptr);
1239 check_for_pipe(fname);
1243 if (fd_ptr->fd >= 0)
1247 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1248 /* Error - backout !! */
1249 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1250 fd_ptr->fd, fname,strerror(errno)));
1251 /* Ensure the ref_count is decremented. */
1252 fd_attempt_close(fd_ptr);
1258 /* Set the correct entries in fd_ptr. */
1259 fd_ptr->dev = (uint32)sbuf->st_dev;
1260 fd_ptr->inode = (uint32)sbuf->st_ino;
1262 fsp->fd_ptr = fd_ptr;
1263 Connections[cnum].num_files_open++;
1264 fsp->mode = sbuf->st_mode;
1265 GetTimeOfDay(&fsp->open_time);
1266 fsp->vuid = current_user.vuid;
1270 fsp->mmap_ptr = NULL;
1272 fsp->can_lock = True;
1273 fsp->can_read = ((flags & O_WRONLY)==0);
1274 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1275 fsp->share_mode = 0;
1276 fsp->print_file = Connections[cnum].printer;
1277 fsp->modified = False;
1278 fsp->granted_oplock = False;
1279 fsp->sent_oplock_break = False;
1280 fsp->is_directory = False;
1283 * Note that the file name here is the *untranslated* name
1284 * ie. it is still in the DOS codepage sent from the client.
1285 * All use of this filename will pass though the sys_xxxx
1286 * functions which will do the dos_to_unix translation before
1287 * mapping into a UNIX filename. JRA.
1289 string_set(&fsp->name,fname);
1290 fsp->wbmpx_ptr = NULL;
1293 * If the printer is marked as postscript output a leading
1294 * file identifier to ensure the file is treated as a raw
1296 * This has a similar effect as CtrlD=0 in WIN.INI file.
1297 * tim@fsg.com 09/06/94
1299 if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write)
1301 DEBUG(3,("Writing postscript line\n"));
1302 write_file(fnum,"%!\n",3);
1305 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1307 *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname,
1308 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1309 Connections[cnum].num_files_open,fnum));
1314 /* mmap it if read-only */
1315 if (!fsp->can_write)
1317 fsp->mmap_size = file_size(fname);
1318 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1319 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1321 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1323 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1324 fsp->mmap_ptr = NULL;
1330 /*******************************************************************
1332 ********************************************************************/
1333 void sync_file(int cnum, int fnum)
1336 if(lp_strict_sync(SNUM(cnum)))
1337 fsync(Files[fnum].fd_ptr->fd);
1341 /****************************************************************************
1342 run a file if it is a magic script
1343 ****************************************************************************/
1344 static void check_magic(int fnum,int cnum)
1346 if (!*lp_magicscript(SNUM(cnum)))
1349 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1353 if (!(p = strrchr(Files[fnum].name,'/')))
1354 p = Files[fnum].name;
1358 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1364 pstring magic_output;
1366 pstrcpy(fname,Files[fnum].name);
1368 if (*lp_magicoutput(SNUM(cnum)))
1369 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1371 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
1374 ret = smbrun(fname,magic_output,False);
1375 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1380 /****************************************************************************
1381 Common code to close a file or a directory.
1382 ****************************************************************************/
1384 static void close_filestruct(files_struct *fs_p)
1386 int cnum = fs_p->cnum;
1388 fs_p->reserved = False;
1390 fs_p->is_directory = False;
1392 Connections[cnum].num_files_open--;
1395 free((char *)fs_p->wbmpx_ptr);
1396 fs_p->wbmpx_ptr = NULL;
1402 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1403 fs_p->mmap_ptr = NULL;
1408 /****************************************************************************
1409 Close a file - possibly invalidating the read prediction.
1411 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1412 operation otherwise it came as the result of some other operation such as
1413 the closing of the connection. In the latter case printing and
1414 magic scripts are not run.
1415 ****************************************************************************/
1417 void close_file(int fnum, BOOL normal_close)
1419 files_struct *fs_p = &Files[fnum];
1420 int cnum = fs_p->cnum;
1421 uint32 dev = fs_p->fd_ptr->dev;
1422 uint32 inode = fs_p->fd_ptr->inode;
1425 close_filestruct(fs_p);
1427 #if USE_READ_PREDICTION
1428 invalidate_read_prediction(fs_p->fd_ptr->fd);
1431 if (lp_share_modes(SNUM(cnum)))
1433 lock_share_entry( cnum, dev, inode, &token);
1434 del_share_mode(token, fnum);
1437 fd_attempt_close(fs_p->fd_ptr);
1439 if (lp_share_modes(SNUM(cnum)))
1440 unlock_share_entry( cnum, dev, inode, token);
1442 /* NT uses smbclose to start a print - weird */
1443 if (normal_close && fs_p->print_file)
1446 /* check for magic scripts */
1448 check_magic(fnum,cnum);
1450 if(fs_p->granted_oplock == True)
1451 global_oplocks_open--;
1453 fs_p->sent_oplock_break = False;
1455 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1456 timestring(),Connections[cnum].user,fs_p->name,
1457 Connections[cnum].num_files_open));
1460 string_free(&fs_p->name);
1463 /* we will catch bugs faster by zeroing this structure */
1464 memset(fs_p, 0, sizeof(*fs_p));
1467 /****************************************************************************
1468 Close a directory opened by an NT SMB call.
1469 ****************************************************************************/
1471 void close_directory(int fnum)
1473 files_struct *fs_p = &Files[fnum];
1476 * Do the code common to files and directories.
1478 close_filestruct(fs_p);
1481 string_free(&fs_p->name);
1484 /* we will catch bugs faster by zeroing this structure */
1485 memset(fs_p, 0, sizeof(*fs_p));
1488 /****************************************************************************
1489 Open a directory from an NT SMB call.
1490 ****************************************************************************/
1492 void open_directory(int fnum,int cnum,char *fname, int *action)
1494 extern struct current_user current_user;
1495 files_struct *fsp = &Files[fnum];
1498 Connections[cnum].num_files_open++;
1500 GetTimeOfDay(&fsp->open_time);
1501 fsp->vuid = current_user.vuid;
1505 fsp->mmap_ptr = NULL;
1507 fsp->can_lock = True;
1508 fsp->can_read = False;
1509 fsp->can_write = False;
1510 fsp->share_mode = 0;
1511 fsp->print_file = False;
1512 fsp->modified = False;
1513 fsp->granted_oplock = False;
1514 fsp->sent_oplock_break = False;
1515 fsp->is_directory = True;
1518 * Note that the file name here is the *untranslated* name
1519 * ie. it is still in the DOS codepage sent from the client.
1520 * All use of this filename will pass though the sys_xxxx
1521 * functions which will do the dos_to_unix translation before
1522 * mapping into a UNIX filename. JRA.
1524 string_set(&fsp->name,fname);
1525 fsp->wbmpx_ptr = NULL;
1527 *action = FILE_WAS_OPENED;
1530 enum {AFAIL,AREAD,AWRITE,AALL};
1532 /*******************************************************************
1533 reproduce the share mode access table
1534 ********************************************************************/
1535 static int access_table(int new_deny,int old_deny,int old_mode,
1536 int share_pid,char *fname)
1538 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1540 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1542 if (old_deny == new_deny && share_pid == pid)
1545 if (old_mode == 0) return(AREAD);
1547 /* the new smbpub.zip spec says that if the file extension is
1548 .com, .dll, .exe or .sym then allow the open. I will force
1549 it to read-only as this seems sensible although the spec is
1550 a little unclear on this. */
1551 if ((fname = strrchr(fname,'.'))) {
1552 if (strequal(fname,".com") ||
1553 strequal(fname,".dll") ||
1554 strequal(fname,".exe") ||
1555 strequal(fname,".sym"))
1565 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1566 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1567 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1570 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1571 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1572 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1575 if (old_deny==DENY_WRITE) return(AREAD);
1576 if (old_deny==DENY_READ) return(AWRITE);
1577 if (old_deny==DENY_NONE) return(AALL);
1583 /*******************************************************************
1584 check if the share mode on a file allows it to be deleted or unlinked
1585 return True if sharing doesn't prevent the operation
1586 ********************************************************************/
1587 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1591 share_mode_entry *old_shares = 0;
1592 int num_share_modes;
1598 if(!lp_share_modes(SNUM(cnum)))
1601 if (sys_stat(fname,&sbuf) == -1) return(True);
1603 dev = (uint32)sbuf.st_dev;
1604 inode = (uint32)sbuf.st_ino;
1606 lock_share_entry(cnum, dev, inode, &token);
1607 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1610 * Check if the share modes will give us access.
1613 if(num_share_modes != 0)
1620 broke_oplock = False;
1621 for(i = 0; i < num_share_modes; i++)
1623 share_mode_entry *share_entry = &old_shares[i];
1626 * Break oplocks before checking share modes. See comment in
1627 * open_file_shared for details.
1628 * Check if someone has an oplock on this file. If so we must
1629 * break it before continuing.
1631 if(share_entry->op_type & BATCH_OPLOCK)
1635 * It appears that the NT redirector may have a bug, in that
1636 * it tries to do an SMBmv on a file that it has open with a
1637 * batch oplock, and then fails to respond to the oplock break
1638 * request. This only seems to occur when the client is doing an
1639 * SMBmv to the smbd it is using - thus we try and detect this
1640 * condition by checking if the file being moved is open and oplocked by
1641 * this smbd process, and then not sending the oplock break in this
1642 * special case. If the file was open with a deny mode that
1643 * prevents the move the SMBmv will fail anyway with a share
1644 * violation error. JRA.
1646 if(rename_op && (share_entry->pid == pid))
1648 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1649 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1651 * This next line is a test that allows the deny-mode
1652 * processing to be skipped. This seems to be needed as
1653 * NT insists on the rename succeeding (in Office 9x no less !).
1654 * This should be removed as soon as (a) MS fix the redirector
1655 * bug or (b) NT SMB support in Samba makes NT not issue the
1656 * call (as is my fervent hope). JRA.
1662 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1663 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1665 /* Oplock break.... */
1666 unlock_share_entry(cnum, dev, inode, token);
1667 if(request_oplock_break(share_entry, dev, inode) == False)
1669 free((char *)old_shares);
1670 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1671 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1674 lock_share_entry(cnum, dev, inode, &token);
1675 broke_oplock = True;
1680 /* someone else has a share lock on it, check to see
1682 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1689 free((char *)old_shares);
1690 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1692 } while(broke_oplock);
1695 /* XXXX exactly what share mode combinations should be allowed for
1696 deleting/renaming? */
1697 /* If we got here then either there were no share modes or
1698 all share modes were DENY_DOS and the pid == getpid() */
1703 unlock_share_entry(cnum, dev, inode, token);
1704 if(old_shares != NULL)
1705 free((char *)old_shares);
1709 /****************************************************************************
1711 Helper for open_file_shared.
1712 Truncate a file after checking locking; close file if locked.
1713 **************************************************************************/
1714 static void truncate_unless_locked(int fnum, int cnum, int token,
1717 if (Files[fnum].can_write){
1718 if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){
1719 /* If share modes are in force for this connection we
1720 have the share entry locked. Unlock it before closing. */
1721 if (*share_locked && lp_share_modes(SNUM(cnum)))
1722 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1723 Files[fnum].fd_ptr->inode, token);
1724 close_file(fnum,False);
1725 /* Share mode no longer locked. */
1726 *share_locked = False;
1728 unix_ERR_class = ERRDOS;
1729 unix_ERR_code = ERRlock;
1732 ftruncate(Files[fnum].fd_ptr->fd,0);
1736 /****************************************************************************
1737 check if we can open a file with a share mode
1738 ****************************************************************************/
1739 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1740 BOOL fcbopen, int *flags)
1742 int old_open_mode = share->share_mode &0xF;
1743 int old_deny_mode = (share->share_mode >>4)&7;
1745 if (old_deny_mode > 4 || old_open_mode > 2)
1747 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1748 deny_mode,old_deny_mode,old_open_mode,fname));
1753 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1756 if ((access_allowed == AFAIL) ||
1757 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1758 (access_allowed == AREAD && *flags == O_WRONLY) ||
1759 (access_allowed == AWRITE && *flags == O_RDONLY))
1761 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1762 deny_mode,old_deny_mode,old_open_mode,
1763 share->pid,fname, fcbopen, *flags, access_allowed));
1767 if (access_allowed == AREAD)
1770 if (access_allowed == AWRITE)
1777 /****************************************************************************
1778 open a file with a share mode
1779 ****************************************************************************/
1780 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1781 int mode,int oplock_request, int *Access,int *action)
1783 files_struct *fs_p = &Files[fnum];
1786 int deny_mode = (share_mode>>4)&7;
1788 BOOL file_existed = file_exist(fname,&sbuf);
1789 BOOL share_locked = False;
1790 BOOL fcbopen = False;
1794 int num_share_modes = 0;
1799 /* this is for OS/2 EAs - try and say we don't support them */
1800 if (strstr(fname,".+,;=[]."))
1802 unix_ERR_class = ERRDOS;
1803 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1804 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1805 unix_ERR_code = ERRcannotopen;
1806 #else /* OS2_WPS_FIX */
1807 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1808 #endif /* OS2_WPS_FIX */
1813 if ((ofun & 0x3) == 0 && file_existed)
1821 if ((ofun & 0x3) == 2)
1824 /* note that we ignore the append flag as
1825 append does not mean the same thing under dos and unix */
1827 switch (share_mode&0xF)
1845 if (share_mode&(1<<14)) {
1850 if (flags != O_RDONLY && file_existed &&
1851 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1861 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1863 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1868 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1870 if (lp_share_modes(SNUM(cnum)))
1873 share_mode_entry *old_shares = 0;
1877 dev = (uint32)sbuf.st_dev;
1878 inode = (uint32)sbuf.st_ino;
1879 lock_share_entry(cnum, dev, inode, &token);
1880 share_locked = True;
1881 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1885 * Check if the share modes will give us access.
1888 if(share_locked && (num_share_modes != 0))
1895 broke_oplock = False;
1896 for(i = 0; i < num_share_modes; i++)
1898 share_mode_entry *share_entry = &old_shares[i];
1901 * By observation of NetBench, oplocks are broken *before* share
1902 * modes are checked. This allows a file to be closed by the client
1903 * if the share mode would deny access and the client has an oplock.
1904 * Check if someone has an oplock on this file. If so we must break
1905 * it before continuing.
1907 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1910 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1911 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1913 /* Oplock break.... */
1914 unlock_share_entry(cnum, dev, inode, token);
1915 if(request_oplock_break(share_entry, dev, inode) == False)
1917 free((char *)old_shares);
1918 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1919 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1921 unix_ERR_class = ERRDOS;
1922 unix_ERR_code = ERRbadshare;
1925 lock_share_entry(cnum, dev, inode, &token);
1926 broke_oplock = True;
1930 /* someone else has a share lock on it, check to see
1932 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1934 free((char *)old_shares);
1935 unlock_share_entry(cnum, dev, inode, token);
1937 unix_ERR_class = ERRDOS;
1938 unix_ERR_code = ERRbadshare;
1946 free((char *)old_shares);
1947 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1949 } while(broke_oplock);
1953 free((char *)old_shares);
1956 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1957 flags,flags2,mode));
1959 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1960 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1963 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1970 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1972 /* We created the file - thus we must now lock the share entry before creating it. */
1973 dev = fs_p->fd_ptr->dev;
1974 inode = fs_p->fd_ptr->inode;
1975 lock_share_entry(cnum, dev, inode, &token);
1976 share_locked = True;
1992 fs_p->share_mode = (deny_mode<<4) | open_mode;
1995 (*Access) = open_mode;
1999 if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
2000 if (!file_existed) *action = FILE_WAS_CREATED;
2001 if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
2003 /* We must create the share mode entry before truncate as
2004 truncate can fail due to locking and have to close the
2005 file (which expects the share_mode_entry to be there).
2007 if (lp_share_modes(SNUM(cnum)))
2010 /* JRA. Currently this only services Exlcusive and batch
2011 oplocks (no other opens on this file). This needs to
2012 be extended to level II oplocks (multiple reader
2015 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
2016 !IS_VETO_OPLOCK_PATH(cnum,fname))
2018 fs_p->granted_oplock = True;
2019 fs_p->sent_oplock_break = False;
2020 global_oplocks_open++;
2023 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2024 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2032 set_share_mode(token, fnum, port, oplock_request);
2035 if ((flags2&O_TRUNC) && file_existed)
2036 truncate_unless_locked(fnum,cnum,token,&share_locked);
2039 if (share_locked && lp_share_modes(SNUM(cnum)))
2040 unlock_share_entry( cnum, dev, inode, token);
2043 /****************************************************************************
2044 seek a file. Try to avoid the seek if possible
2045 ****************************************************************************/
2046 int seek_file(int fnum,uint32 pos)
2049 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2052 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2054 return(Files[fnum].pos);
2057 /****************************************************************************
2059 ****************************************************************************/
2060 int read_file(int fnum,char *data,uint32 pos,int n)
2064 #if USE_READ_PREDICTION
2065 if (!Files[fnum].can_write)
2067 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2076 if (Files[fnum].mmap_ptr)
2078 int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2082 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2094 if (seek_file(fnum,pos) != pos)
2096 DEBUG(3,("Failed to seek to %d\n",pos));
2101 readret = read(Files[fnum].fd_ptr->fd,data,n);
2102 if (readret > 0) ret += readret;
2109 /****************************************************************************
2111 ****************************************************************************/
2112 int write_file(int fnum,char *data,int n)
2114 if (!Files[fnum].can_write) {
2119 if (!Files[fnum].modified) {
2121 Files[fnum].modified = True;
2122 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2123 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2124 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2125 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2130 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2134 /****************************************************************************
2135 load parameters specific to a connection/service
2136 ****************************************************************************/
2137 BOOL become_service(int cnum,BOOL do_chdir)
2139 extern char magic_char;
2140 static int last_cnum = -1;
2143 if (!OPEN_CNUM(cnum))
2149 Connections[cnum].lastused = smb_last_time;
2154 ChDir(Connections[cnum].connectpath) != 0 &&
2155 ChDir(Connections[cnum].origpath) != 0)
2157 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2158 Connections[cnum].connectpath,cnum));
2162 if (cnum == last_cnum)
2167 case_default = lp_defaultcase(snum);
2168 case_preserve = lp_preservecase(snum);
2169 short_case_preserve = lp_shortpreservecase(snum);
2170 case_mangle = lp_casemangle(snum);
2171 case_sensitive = lp_casesensitive(snum);
2172 magic_char = lp_magicchar(snum);
2173 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2178 /****************************************************************************
2179 find a service entry
2180 ****************************************************************************/
2181 int find_service(char *service)
2185 string_sub(service,"\\","/");
2187 iService = lp_servicenumber(service);
2189 /* now handle the special case of a home directory */
2192 char *phome_dir = get_home_dir(service);
2197 * Try mapping the servicename, it may
2198 * be a Windows to unix mapped user name.
2200 if(map_username(service))
2201 phome_dir = get_home_dir(service);
2204 DEBUG(3,("checking for home directory %s gave %s\n",service,
2205 phome_dir?phome_dir:"(NULL)"));
2210 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2212 lp_add_home(service,iHomeService,phome_dir);
2213 iService = lp_servicenumber(service);
2218 /* If we still don't have a service, attempt to add it as a printer. */
2221 int iPrinterService;
2223 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2227 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2229 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2231 DEBUG(3,("%s is a valid printer name\n", service));
2232 DEBUG(3,("adding %s as a printer service\n", service));
2233 lp_add_printer(service,iPrinterService);
2234 iService = lp_servicenumber(service);
2236 DEBUG(0,("failed to add %s as a printer service!\n", service));
2239 DEBUG(3,("%s is not a valid printer name\n", service));
2243 /* just possibly it's a default service? */
2246 char *pdefservice = lp_defaultservice();
2247 if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2250 * We need to do a local copy here as lp_defaultservice()
2251 * returns one of the rotating lp_string buffers that
2252 * could get overwritten by the recursive find_service() call
2253 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2256 pstrcpy(defservice, pdefservice);
2257 iService = find_service(defservice);
2260 string_sub(service,"_","/");
2261 iService = lp_add_service(service,iService);
2267 if (!VALID_SNUM(iService))
2269 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2274 DEBUG(3,("find_service() failed to find service %s\n", service));
2280 /****************************************************************************
2281 create an error packet from a cached error.
2282 ****************************************************************************/
2283 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2285 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2287 int32 eclass = wbmpx->wr_errclass;
2288 int32 err = wbmpx->wr_error;
2290 /* We can now delete the auxiliary struct */
2291 free((char *)wbmpx);
2292 Files[fnum].wbmpx_ptr = NULL;
2293 return error_packet(inbuf,outbuf,eclass,err,line);
2302 } unix_smb_errmap[] =
2304 {EPERM,ERRDOS,ERRnoaccess},
2305 {EACCES,ERRDOS,ERRnoaccess},
2306 {ENOENT,ERRDOS,ERRbadfile},
2307 {ENOTDIR,ERRDOS,ERRbadpath},
2308 {EIO,ERRHRD,ERRgeneral},
2309 {EBADF,ERRSRV,ERRsrverror},
2310 {EINVAL,ERRSRV,ERRsrverror},
2311 {EEXIST,ERRDOS,ERRfilexists},
2312 {ENFILE,ERRDOS,ERRnofids},
2313 {EMFILE,ERRDOS,ERRnofids},
2314 {ENOSPC,ERRHRD,ERRdiskfull},
2316 {EDQUOT,ERRHRD,ERRdiskfull},
2319 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2322 {EXDEV,ERRDOS,ERRdiffdevice},
2324 {EROFS,ERRHRD,ERRnowrite},
2328 /****************************************************************************
2329 create an error packet from errno
2330 ****************************************************************************/
2331 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2333 int eclass=def_class;
2337 if (unix_ERR_class != SMB_SUCCESS)
2339 eclass = unix_ERR_class;
2340 ecode = unix_ERR_code;
2341 unix_ERR_class = SMB_SUCCESS;
2346 while (unix_smb_errmap[i].smbclass != 0)
2348 if (unix_smb_errmap[i].unixerror == errno)
2350 eclass = unix_smb_errmap[i].smbclass;
2351 ecode = unix_smb_errmap[i].smbcode;
2358 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2362 /****************************************************************************
2363 create an error packet. Normally called using the ERROR() macro
2364 ****************************************************************************/
2365 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2367 int outsize = set_message(outbuf,0,0,True);
2368 int cmd = CVAL(inbuf,smb_com);
2369 int flgs2 = SVAL(outbuf,smb_flg2);
2371 if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2373 SIVAL(outbuf,smb_rcls,error_code);
2375 DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2376 timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2380 CVAL(outbuf,smb_rcls) = error_class;
2381 SSVAL(outbuf,smb_err,error_code);
2382 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2385 (int)CVAL(inbuf,smb_com),
2386 smb_fn_name(CVAL(inbuf,smb_com)),
2393 DEBUG(3,("error string = %s\n",strerror(errno)));
2399 /****************************************************************************
2400 this is called when the client exits abruptly
2401 **************************************************************************/
2402 static int sig_pipe(void)
2404 struct cli_state *cli;
2405 BlockSignals(True,SIGPIPE);
2407 if ((cli = server_client()) && cli->initialised) {
2408 DEBUG(3,("lost connection to password server\n"));
2410 BlockSignals(False,SIGPIPE);
2414 exit_server("Got sigpipe\n");
2418 /****************************************************************************
2419 open the socket communication
2420 ****************************************************************************/
2421 static BOOL open_sockets(BOOL is_daemon,int port)
2427 int num_interfaces = iface_count();
2428 int fd_listenset[FD_SETSIZE];
2434 static int atexit_set;
2435 if(atexit_set == 0) {
2445 FD_ZERO(&listen_set);
2447 if(lp_interfaces() && lp_bind_interfaces_only())
2449 /* We have been given an interfaces line, and been
2450 told to only bind to those interfaces. Create a
2451 socket per interface and bind to only these.
2454 if(num_interfaces > FD_SETSIZE)
2456 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2457 max can be %d\n", num_interfaces, FD_SETSIZE));
2461 /* Now open a listen socket for each of the interfaces. */
2462 for(i = 0; i < num_interfaces; i++)
2464 struct in_addr *ifip = iface_n_ip(i);
2468 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2471 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2474 /* ready to listen */
2475 if (listen(s, 5) == -1)
2477 DEBUG(0,("listen: %s\n",strerror(errno)));
2481 FD_SET(s,&listen_set);
2486 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2489 /* open an incoming socket */
2490 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2494 /* ready to listen */
2495 if (listen(s, 5) == -1)
2497 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2502 fd_listenset[0] = s;
2503 FD_SET(s,&listen_set);
2506 /* now accept incoming connections - forking a new process
2507 for each incoming connection */
2508 DEBUG(2,("waiting for a connection\n"));
2514 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2516 num = sys_select(&lfds,NULL);
2518 if (num == -1 && errno == EINTR)
2521 /* Find the sockets that are read-ready - accept on these. */
2522 for( ; num > 0; num--)
2524 struct sockaddr addr;
2525 int in_addrlen = sizeof(addr);
2528 for(i = 0; i < num_interfaces; i++)
2530 if(FD_ISSET(fd_listenset[i],&lfds))
2532 s = fd_listenset[i];
2533 /* Clear this so we don't look at it again. */
2534 FD_CLR(fd_listenset[i],&lfds);
2539 Client = accept(s,&addr,&in_addrlen);
2541 if (Client == -1 && errno == EINTR)
2546 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2550 if (Client != -1 && fork()==0)
2552 /* Child code ... */
2554 CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2556 /* close the listening socket(s) */
2557 for(i = 0; i < num_interfaces; i++)
2558 close(fd_listenset[i]);
2560 /* close our standard file descriptors */
2564 set_socket_options(Client,"SO_KEEPALIVE");
2565 set_socket_options(Client,user_socket_options);
2567 /* Reset global variables in util.c so that
2568 client substitutions will be done correctly
2571 reset_globals_after_fork();
2574 close(Client); /* The parent doesn't need this socket */
2577 * Force parent to check log size after spawning child.
2578 * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
2579 * The parent smbd will log to logserver.smb.
2580 * It writes only two messages for each child
2581 * started/finished. But each child writes, say, 50 messages also in
2582 * logserver.smb, begining with the debug_count of the parent, before the
2583 * child opens its own log file logserver.client. In a worst case
2584 * scenario the size of logserver.smb would be checked after about
2585 * 50*50=2500 messages (ca. 100kb).
2587 force_check_log_size();
2591 } /* end if is_daemon */
2594 /* Started from inetd. fd 0 is the socket. */
2595 /* We will abort gracefully when the client or remote system
2597 CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2600 /* close our standard file descriptors */
2603 set_socket_options(Client,"SO_KEEPALIVE");
2604 set_socket_options(Client,user_socket_options);
2610 /****************************************************************************
2611 process an smb from the client - split out from the process() code so
2612 it can be used by the oplock break code.
2613 ****************************************************************************/
2615 static void process_smb(char *inbuf, char *outbuf)
2619 extern BOOL sslEnabled; /* don't use function for performance reasons */
2620 static int sslConnected = 0;
2621 #endif /* WITH_SSL */
2622 static int trans_num;
2623 int msg_type = CVAL(inbuf,0);
2624 int32 len = smb_len(inbuf);
2625 int nread = len + 4;
2627 if (trans_num == 0) {
2628 /* on the first packet, check the global hosts allow/ hosts
2629 deny parameters before doing any parsing of the packet
2630 passed to us by the client. This prevents attacks on our
2631 parsing code from hosts not in the hosts allow list */
2632 if (!check_access(-1)) {
2633 /* send a negative session response "not listining on calling
2635 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2636 DEBUG(1,("%s Connection denied from %s\n",
2637 timestring(),client_addr(Client)));
2638 send_smb(Client,(char *)buf);
2639 exit_server("connection denied");
2643 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2644 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2647 if(sslEnabled && !sslConnected){
2648 sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2649 if(sslConnected < 0){ /* an error occured */
2650 exit_server("SSL negotiation failed");
2651 }else if(sslConnected){
2656 #endif /* WITH_SSL */
2659 if(trans_num == 1 && VT_Check(inbuf))
2668 else if(msg_type == 0x85)
2669 return; /* Keepalive packet. */
2671 nread = construct_reply(inbuf,outbuf,nread,max_send);
2675 if (CVAL(outbuf,0) == 0)
2678 if (nread != smb_len(outbuf) + 4)
2680 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2681 nread, smb_len(outbuf)));
2684 send_smb(Client,outbuf);
2689 /****************************************************************************
2690 open the oplock IPC socket communication
2691 ****************************************************************************/
2692 static BOOL open_oplock_ipc(void)
2694 struct sockaddr_in sock_name;
2695 int len = sizeof(sock_name);
2697 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2699 /* Open a lookback UDP socket on a random port. */
2700 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2701 if (oplock_sock == -1)
2703 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2704 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2709 /* Find out the transient UDP port we have been allocated. */
2710 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2712 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2719 oplock_port = ntohs(sock_name.sin_port);
2721 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2722 getpid(), oplock_port));
2727 /****************************************************************************
2728 process an oplock break message.
2729 ****************************************************************************/
2730 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2736 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2737 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2739 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2741 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2742 msg_len, from_port));
2744 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2745 only valid request. */
2747 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2749 case OPLOCK_BREAK_CMD:
2750 /* Ensure that the msg length is correct. */
2751 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2753 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2754 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2758 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2759 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2760 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2761 struct timeval tval;
2762 struct sockaddr_in toaddr;
2764 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2765 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2767 DEBUG(5,("process_local_message: oplock break request from \
2768 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2771 * If we have no record of any currently open oplocks,
2772 * it's not an error, as a close command may have
2773 * just been issued on the file that was oplocked.
2774 * Just return success in this case.
2777 if(global_oplocks_open != 0)
2779 if(oplock_break(dev, inode, &tval) == False)
2781 DEBUG(0,("process_local_message: oplock break failed - \
2782 not returning udp message.\n"));
2788 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2789 oplocks. Returning success.\n"));
2792 /* Send the message back after OR'ing in the 'REPLY' bit. */
2793 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2795 bzero((char *)&toaddr,sizeof(toaddr));
2796 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2797 toaddr.sin_port = htons(from_port);
2798 toaddr.sin_family = AF_INET;
2800 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2801 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2803 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2804 remotepid, strerror(errno)));
2808 DEBUG(5,("process_local_message: oplock break reply sent to \
2809 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2810 from_port, dev, inode));
2815 * Keep this as a debug case - eventually we can remove it.
2818 DEBUG(0,("process_local_message: Received unsolicited break \
2819 reply - dumping info.\n"));
2821 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2823 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2824 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2829 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2830 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2831 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2833 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2834 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2840 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2841 (unsigned int)SVAL(msg_start,0)));
2847 /****************************************************************************
2848 Process an oplock break directly.
2849 ****************************************************************************/
2850 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2852 extern struct current_user current_user;
2855 char *outbuf = NULL;
2856 files_struct *fsp = NULL;
2859 BOOL shutdown_server = False;
2864 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2865 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2867 /* We need to search the file open table for the
2868 entry containing this dev and inode, and ensure
2869 we have an oplock on it. */
2870 for( fnum = 0; fnum < MAX_FNUMS; fnum++)
2874 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2875 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2876 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2885 /* The file could have been closed in the meantime - return success. */
2886 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2887 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2891 /* Ensure we have an oplock on the file */
2893 /* There is a potential race condition in that an oplock could
2894 have been broken due to another udp request, and yet there are
2895 still oplock break messages being sent in the udp message
2896 queue for this file. So return true if we don't have an oplock,
2897 as we may have just freed it.
2900 if(!fsp->granted_oplock)
2902 DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2906 /* mark the oplock break as sent - we don't want to send twice! */
2907 if (fsp->sent_oplock_break)
2909 DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
2911 /* We have to fail the open here as we cannot send another oplock break on this
2912 file whilst we are awaiting a response from the client - neither can we
2913 allow another open to succeed while we are waiting for the client. */
2917 /* Now comes the horrid part. We must send an oplock break to the client,
2918 and then process incoming messages until we get a close or oplock release.
2919 At this point we know we need a new inbuf/outbuf buffer pair.
2920 We cannot use these staticaly as we may recurse into here due to
2921 messages crossing on the wire.
2924 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2926 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2930 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2932 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2938 /* Prepare the SMBlockingX message. */
2939 bzero(outbuf,smb_size);
2940 set_message(outbuf,8,0,True);
2942 SCVAL(outbuf,smb_com,SMBlockingX);
2943 SSVAL(outbuf,smb_tid,fsp->cnum);
2944 SSVAL(outbuf,smb_pid,0xFFFF);
2945 SSVAL(outbuf,smb_uid,0);
2946 SSVAL(outbuf,smb_mid,0xFFFF);
2947 SCVAL(outbuf,smb_vwv0,0xFF);
2948 SSVAL(outbuf,smb_vwv2,fnum);
2949 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2950 /* Change this when we have level II oplocks. */
2951 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2953 send_smb(Client, outbuf);
2955 /* Remember we just sent an oplock break on this file. */
2956 fsp->sent_oplock_break = True;
2958 /* We need this in case a readraw crosses on the wire. */
2959 global_oplock_break = True;
2961 /* Process incoming messages. */
2963 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2964 seconds we should just die.... */
2966 start_time = time(NULL);
2969 * Save the information we need to re-become the
2970 * user, then unbecome the user whilst we're doing this.
2972 saved_cnum = fsp->cnum;
2973 saved_vuid = current_user.vuid;
2977 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2979 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2982 * Die if we got an error.
2985 if (smb_read_error == READ_EOF)
2986 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2988 if (smb_read_error == READ_ERROR)
2989 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2990 timestring(), strerror(errno)));
2992 if (smb_read_error == READ_TIMEOUT)
2993 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2994 timestring(), OPLOCK_BREAK_TIMEOUT));
2996 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2997 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2998 shutdown_server = True;
3003 * There are certain SMB requests that we shouldn't allow
3004 * to recurse. opens, renames and deletes are the obvious
3005 * ones. This is handled in the switch_message() function.
3006 * If global_oplock_break is set they will push the packet onto
3007 * the pending smb queue and return -1 (no reply).
3011 process_smb(inbuf, outbuf);
3014 * Die if we go over the time limit.
3017 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3019 DEBUG(0,("%s oplock_break: no break received from client within \
3020 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3021 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3022 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3023 shutdown_server = True;
3029 * Go back to being the user who requested the oplock
3032 if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3034 DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3038 exit_server("unable to re-become user");
3040 /* Including the directory. */
3043 /* Free the buffers we've been using to recurse. */
3047 /* We need this in case a readraw crossed on the wire. */
3048 if(global_oplock_break)
3049 global_oplock_break = False;
3052 * If the client did not respond we must die.
3057 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3061 exit_server("oplock break failure");
3066 /* The lockingX reply will have removed the oplock flag
3067 from the sharemode. */
3069 fsp->granted_oplock = False;
3070 fsp->sent_oplock_break = False;
3071 global_oplocks_open--;
3074 /* Santity check - remove this later. JRA */
3075 if(global_oplocks_open < 0)
3077 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3078 global_oplocks_open));
3079 exit_server("oplock_break: global_oplocks_open < 0");
3082 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3083 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3088 /****************************************************************************
3089 Send an oplock break message to another smbd process. If the oplock is held
3090 by the local smbd then call the oplock break function directly.
3091 ****************************************************************************/
3093 BOOL request_oplock_break(share_mode_entry *share_entry,
3094 uint32 dev, uint32 inode)
3096 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3097 struct sockaddr_in addr_out;
3102 if(pid == share_entry->pid)
3104 /* We are breaking our own oplock, make sure it's us. */
3105 if(share_entry->op_port != oplock_port)
3107 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3108 should be %d\n", pid, share_entry->op_port, oplock_port));
3112 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3114 /* Call oplock break direct. */
3115 return oplock_break(dev, inode, &share_entry->time);
3118 /* We need to send a OPLOCK_BREAK_CMD message to the
3119 port in the share mode entry. */
3121 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3122 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3123 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3124 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3125 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3126 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3128 /* set the address and port */
3129 bzero((char *)&addr_out,sizeof(addr_out));
3130 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3131 addr_out.sin_port = htons( share_entry->op_port );
3132 addr_out.sin_family = AF_INET;
3134 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3135 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3137 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3138 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3140 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3141 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3142 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3148 * Now we must await the oplock broken message coming back
3149 * from the target smbd process. Timeout if it fails to
3150 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3151 * While we get messages that aren't ours, loop.
3154 start_time = time(NULL);
3155 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3157 while(time_left >= 0)
3159 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3160 int32 reply_msg_len;
3161 uint16 reply_from_port;
3162 char *reply_msg_start;
3164 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3165 time_left ? time_left * 1000 : 1) == False)
3167 if(smb_read_error == READ_TIMEOUT)
3169 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3170 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3171 share_entry->op_port, dev, inode));
3173 * This is a hack to make handling of failing clients more robust.
3174 * If a oplock break response message is not received in the timeout
3175 * period we may assume that the smbd servicing that client holding
3176 * the oplock has died and the client changes were lost anyway, so
3177 * we should continue to try and open the file.
3182 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3183 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3184 share_entry->op_port, dev, inode, strerror(errno)));
3188 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3189 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3191 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3193 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3196 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3202 * Test to see if this is the reply we are awaiting.
3205 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3206 (reply_from_port == share_entry->op_port) &&
3207 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3208 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3209 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3212 * This is the reply we've been waiting for.
3219 * This is another message - probably a break request.
3220 * Process it to prevent potential deadlock.
3221 * Note that the code in switch_message() prevents
3222 * us from recursing into here as any SMB requests
3223 * we might process that would cause another oplock
3224 * break request to be made will be queued.
3228 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3231 time_left -= (time(NULL) - start_time);
3234 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3239 /****************************************************************************
3240 Get the next SMB packet, doing the local message processing automatically.
3241 ****************************************************************************/
3243 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3245 BOOL got_smb = False;
3250 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3255 /* Deal with oplock break requests from other smbd's. */
3256 process_local_message(oplock_sock, inbuf, bufsize);
3260 if(ret && (CVAL(inbuf,0) == 0x85))
3262 /* Keepalive packet. */
3267 while(ret && !got_smb);
3272 /****************************************************************************
3273 check if a snum is in use
3274 ****************************************************************************/
3275 BOOL snum_used(int snum)
3278 for (i=0;i<MAX_CONNECTIONS;i++)
3279 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3284 /****************************************************************************
3285 reload the services file
3286 **************************************************************************/
3287 BOOL reload_services(BOOL test)
3294 pstrcpy(fname,lp_configfile());
3295 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3297 pstrcpy(servicesf,fname);
3304 if (test && !lp_file_list_changed())
3307 lp_killunused(snum_used);
3309 ret = lp_load(servicesf,False,False,True);
3311 /* perhaps the config filename is now set */
3313 reload_services(True);
3322 set_socket_options(Client,"SO_KEEPALIVE");
3323 set_socket_options(Client,user_socket_options);
3327 reset_mangled_cache();
3329 /* this forces service parameters to be flushed */
3330 become_service(-1,True);
3337 /****************************************************************************
3338 this prevents zombie child processes
3339 ****************************************************************************/
3340 static BOOL reload_after_sighup = False;
3342 static int sig_hup(void)
3344 BlockSignals(True,SIGHUP);
3345 DEBUG(0,("Got SIGHUP\n"));
3348 * Fix from <branko.cibej@hermes.si> here.
3349 * We used to reload in the signal handler - this
3353 reload_after_sighup = True;
3354 BlockSignals(False,SIGHUP);
3359 /****************************************************************************
3360 make a connection to a service
3361 ****************************************************************************/
3362 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3366 struct passwd *pass = NULL;
3367 connection_struct *pcon;
3373 snum = find_service(service);
3377 if (strequal(service,"IPC$"))
3379 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3383 DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));
3387 if (strequal(service,HOMES_NAME))
3389 if (*user && Get_Pwnam(user,True))
3390 return(make_connection(user,user,password,pwlen,dev,vuid));
3392 if(lp_security() != SEC_SHARE)
3394 if (validated_username(vuid))
3396 pstrcpy(user,validated_username(vuid));
3397 return(make_connection(user,user,password,pwlen,dev,vuid));
3403 * Security = share. Try with sesssetup_user as the username.
3407 pstrcpy(user,sesssetup_user);
3408 return(make_connection(user,user,password,pwlen,dev,vuid));
3413 if (!lp_snum_ok(snum) || !check_access(snum)) {
3417 /* you can only connect to the IPC$ service as an ipc device */
3418 if (strequal(service,"IPC$"))
3421 if (*dev == '?' || !*dev)
3423 if (lp_print_ok(snum))
3424 pstrcpy(dev,"LPT1:");
3429 /* if the request is as a printer and you can't print then refuse */
3431 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3432 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3436 /* lowercase the user name */
3439 /* add it as a possible user name */
3440 add_session_user(service);
3442 /* shall we let them in? */
3443 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3445 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3449 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3452 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3456 pcon = &Connections[cnum];
3457 bzero((char *)pcon,sizeof(*pcon));
3459 /* find out some info about the user */
3460 pass = Get_Pwnam(user,True);
3464 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3468 pcon->read_only = lp_readonly(snum);
3472 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3473 string_sub(list,"%S",service);
3475 if (user_in_list(user,list))
3476 pcon->read_only = True;
3478 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3479 string_sub(list,"%S",service);
3481 if (user_in_list(user,list))
3482 pcon->read_only = False;
3485 /* admin user check */
3487 /* JRA - original code denied admin user if the share was
3488 marked read_only. Changed as I don't think this is needed,
3489 but old code left in case there is a problem here.
3491 if (user_in_list(user,lp_admin_users(snum))
3493 && !pcon->read_only)
3498 pcon->admin_user = True;
3499 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3502 pcon->admin_user = False;
3504 pcon->force_user = force;
3506 pcon->uid = pass->pw_uid;
3507 pcon->gid = pass->pw_gid;
3508 pcon->num_files_open = 0;
3509 pcon->lastused = time(NULL);
3510 pcon->service = snum;
3512 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3513 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3514 pcon->dirptr = NULL;
3515 pcon->veto_list = NULL;
3516 pcon->hide_list = NULL;
3517 pcon->veto_oplock_list = NULL;
3518 string_set(&pcon->dirpath,"");
3519 string_set(&pcon->user,user);
3521 #ifdef HAVE_GETGRNAM
3522 if (*lp_force_group(snum))
3527 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3528 /* default service may be a group name */
3529 string_sub(gname,"%S",service);
3530 gptr = (struct group *)getgrnam(gname);
3534 pcon->gid = gptr->gr_gid;
3535 DEBUG(3,("Forced group %s\n",gname));
3538 DEBUG(1,("Couldn't find group %s\n",gname));
3542 if (*lp_force_user(snum))
3544 struct passwd *pass2;
3546 fstrcpy(fuser,lp_force_user(snum));
3547 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3550 pcon->uid = pass2->pw_uid;
3551 string_set(&pcon->user,fuser);
3552 fstrcpy(user,fuser);
3553 pcon->force_user = True;
3554 DEBUG(3,("Forced user %s\n",fuser));
3557 DEBUG(1,("Couldn't find user %s\n",fuser));
3562 pstrcpy(s,lp_pathname(snum));
3563 standard_sub(cnum,s);
3564 string_set(&pcon->connectpath,s);
3565 DEBUG(3,("Connect path is %s\n",s));
3568 /* groups stuff added by ih */
3570 pcon->igroups = NULL;
3571 pcon->groups = NULL;
3575 /* Find all the groups this uid is in and store them. Used by become_user() */
3576 setup_groups(pcon->user,pcon->uid,pcon->gid,
3577 &pcon->ngroups,&pcon->igroups,&pcon->groups);
3579 /* check number of connections */
3580 if (!claim_connection(cnum,
3581 lp_servicename(SNUM(cnum)),
3582 lp_max_connections(SNUM(cnum)),False))
3584 DEBUG(1,("too many connections - rejected\n"));
3588 if (lp_status(SNUM(cnum)))
3589 claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3594 /* execute any "root preexec = " line */
3595 if (*lp_rootpreexec(SNUM(cnum)))
3598 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3599 standard_sub(cnum,cmd);
3600 DEBUG(5,("cmd=%s\n",cmd));
3601 smbrun(cmd,NULL,False);
3604 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3606 DEBUG(0,("Can't become connected user!\n"));
3608 if (!IS_IPC(cnum)) {
3609 yield_connection(cnum,
3610 lp_servicename(SNUM(cnum)),
3611 lp_max_connections(SNUM(cnum)));
3612 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3617 if (ChDir(pcon->connectpath) != 0)
3619 DEBUG(0,("Can't change directory to %s (%s)\n",
3620 pcon->connectpath,strerror(errno)));
3623 if (!IS_IPC(cnum)) {
3624 yield_connection(cnum,
3625 lp_servicename(SNUM(cnum)),
3626 lp_max_connections(SNUM(cnum)));
3627 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3632 string_set(&pcon->origpath,pcon->connectpath);
3634 #if SOFTLINK_OPTIMISATION
3635 /* resolve any soft links early */
3638 pstrcpy(s,pcon->connectpath);
3640 string_set(&pcon->connectpath,s);
3641 ChDir(pcon->connectpath);
3645 num_connections_open++;
3646 add_session_user(user);
3648 /* execute any "preexec = " line */
3649 if (*lp_preexec(SNUM(cnum)))
3652 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3653 standard_sub(cnum,cmd);
3654 smbrun(cmd,NULL,False);
3657 /* we've finished with the sensitive stuff */
3660 /* Add veto/hide lists */
3661 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3663 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3664 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3665 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3670 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3673 client_addr(Client),
3674 lp_servicename(SNUM(cnum)),user,
3683 /****************************************************************************
3684 Attempt to break an oplock on a file (if oplocked).
3685 Returns True if the file was closed as a result of
3686 the oplock break, False otherwise.
3687 Used as a last ditch attempt to free a space in the
3688 file table when we have run out.
3689 ****************************************************************************/
3691 static BOOL attempt_close_oplocked_file(files_struct *fp)
3694 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3696 if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3698 /* Try and break the oplock. */
3699 file_fd_struct *fsp = fp->fd_ptr;
3700 if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3701 if(!fp->open) /* Did the oplock break close the file ? */
3709 /****************************************************************************
3710 find first available file slot
3711 ****************************************************************************/
3712 int find_free_file(void )
3715 static int first_file;
3717 /* we want to give out file handles differently on each new
3718 connection because of a common bug in MS clients where they try to
3719 reuse a file descriptor from an earlier smb connection. This code
3720 increases the chance that the errant client will get an error rather
3721 than causing corruption */
3722 if (first_file == 0) {
3723 first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
3724 if (first_file == 0) first_file = 1;
3727 if (first_file >= MAX_FNUMS)
3730 for (i=first_file;i<MAX_FNUMS;i++)
3731 if (!Files[i].open && !Files[i].reserved) {
3732 memset(&Files[i], 0, sizeof(Files[i]));
3734 Files[i].reserved = True;
3738 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3739 for (i=1;i<first_file;i++)
3740 if (!Files[i].open && !Files[i].reserved) {
3741 memset(&Files[i], 0, sizeof(Files[i]));
3743 Files[i].reserved = True;
3748 * Before we give up, go through the open files
3749 * and see if there are any files opened with a
3750 * batch oplock. If so break the oplock and then
3751 * re-use that entry (if it becomes closed).
3752 * This may help as NT/95 clients tend to keep
3753 * files batch oplocked for quite a long time
3754 * after they have finished with them.
3756 for (i=first_file;i<MAX_FNUMS;i++) {
3757 if(attempt_close_oplocked_file( &Files[i])) {
3758 memset(&Files[i], 0, sizeof(Files[i]));
3760 Files[i].reserved = True;
3765 for (i=1;i<MAX_FNUMS;i++) {
3766 if(attempt_close_oplocked_file( &Files[i])) {
3767 memset(&Files[i], 0, sizeof(Files[i]));
3769 Files[i].reserved = True;
3774 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3778 /****************************************************************************
3779 find first available connection slot, starting from a random position.
3780 The randomisation stops problems with the server dieing and clients
3781 thinking the server is still available.
3782 ****************************************************************************/
3783 static int find_free_connection(int hash )
3787 hash = (hash % (MAX_CONNECTIONS-2))+1;
3791 for (i=hash+1;i!=hash;)
3793 if (!Connections[i].open && Connections[i].used == used)
3795 DEBUG(3,("found free connection number %d\n",i));
3799 if (i == MAX_CONNECTIONS)
3809 DEBUG(1,("ERROR! Out of connection structures\n"));
3814 /****************************************************************************
3815 reply for the core protocol
3816 ****************************************************************************/
3817 int reply_corep(char *outbuf)
3819 int outsize = set_message(outbuf,1,0,True);
3821 Protocol = PROTOCOL_CORE;
3827 /****************************************************************************
3828 reply for the coreplus protocol
3829 ****************************************************************************/
3830 int reply_coreplus(char *outbuf)
3832 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3833 int outsize = set_message(outbuf,13,0,True);
3834 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3835 readbraw and writebraw (possibly) */
3836 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3837 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3839 Protocol = PROTOCOL_COREPLUS;
3845 /****************************************************************************
3846 reply for the lanman 1.0 protocol
3847 ****************************************************************************/
3848 int reply_lanman1(char *outbuf)
3850 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3852 BOOL doencrypt = SMBENCRYPT();
3853 time_t t = time(NULL);
3855 if (lp_security()>=SEC_USER) secword |= 1;
3856 if (doencrypt) secword |= 2;
3858 set_message(outbuf,13,doencrypt?8:0,True);
3859 SSVAL(outbuf,smb_vwv1,secword);
3860 /* Create a token value and add it to the outgoing packet. */
3862 generate_next_challenge(smb_buf(outbuf));
3864 Protocol = PROTOCOL_LANMAN1;
3866 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3867 SSVAL(outbuf,smb_vwv2,max_recv);
3868 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3869 SSVAL(outbuf,smb_vwv4,1);
3870 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3871 readbraw writebraw (possibly) */
3872 SIVAL(outbuf,smb_vwv6,getpid());
3873 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3875 put_dos_date(outbuf,smb_vwv8,t);
3877 return (smb_len(outbuf)+4);
3881 /****************************************************************************
3882 reply for the lanman 2.0 protocol
3883 ****************************************************************************/
3884 int reply_lanman2(char *outbuf)
3886 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3888 BOOL doencrypt = SMBENCRYPT();
3889 time_t t = time(NULL);
3890 struct cli_state *cli = NULL;
3894 if (lp_security() == SEC_SERVER) {
3895 cli = server_cryptkey();
3899 DEBUG(3,("using password server validation\n"));
3900 doencrypt = ((cli->sec_mode & 2) != 0);
3903 if (lp_security()>=SEC_USER) secword |= 1;
3904 if (doencrypt) secword |= 2;
3909 generate_next_challenge(cryptkey);
3911 memcpy(cryptkey, cli->cryptkey, 8);
3912 set_challenge(cli->cryptkey);
3916 set_message(outbuf,13,crypt_len,True);
3917 SSVAL(outbuf,smb_vwv1,secword);
3918 SIVAL(outbuf,smb_vwv6,getpid());
3920 memcpy(smb_buf(outbuf), cryptkey, 8);
3922 Protocol = PROTOCOL_LANMAN2;
3924 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3925 SSVAL(outbuf,smb_vwv2,max_recv);
3926 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3927 SSVAL(outbuf,smb_vwv4,1);
3928 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3929 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3930 put_dos_date(outbuf,smb_vwv8,t);
3932 return (smb_len(outbuf)+4);
3936 /****************************************************************************
3937 reply for the nt protocol
3938 ****************************************************************************/
3939 int reply_nt1(char *outbuf)
3941 /* dual names + lock_and_read + nt SMBs + remote API calls */
3942 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
3945 other valid capabilities which we may support at some time...
3946 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3947 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3951 BOOL doencrypt = SMBENCRYPT();
3952 time_t t = time(NULL);
3954 struct cli_state *cli = NULL;
3958 if (lp_security() == SEC_SERVER) {
3959 cli = server_cryptkey();
3963 DEBUG(3,("using password server validation\n"));
3964 doencrypt = ((cli->sec_mode & 2) != 0);
3970 generate_next_challenge(cryptkey);
3972 memcpy(cryptkey, cli->cryptkey, 8);
3973 set_challenge(cli->cryptkey);
3977 if (lp_readraw() && lp_writeraw()) {
3978 capabilities |= CAP_RAW_MODE;
3981 if (lp_security() >= SEC_USER) secword |= 1;
3982 if (doencrypt) secword |= 2;
3984 /* decide where (if) to put the encryption challenge, and
3985 follow it with the OEM'd domain name
3987 data_len = crypt_len + strlen(global_myworkgroup) + 1;
3989 set_message(outbuf,17,data_len,True);
3990 pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
3992 CVAL(outbuf,smb_vwv1) = secword;
3993 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3995 memcpy(smb_buf(outbuf), cryptkey, 8);
3997 Protocol = PROTOCOL_NT1;
3999 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4000 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4001 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4002 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4003 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4004 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4005 put_long_date(outbuf+smb_vwv11+1,t);
4006 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4007 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4009 return (smb_len(outbuf)+4);
4012 /* these are the protocol lists used for auto architecture detection:
4015 protocol [PC NETWORK PROGRAM 1.0]
4016 protocol [XENIX CORE]
4017 protocol [MICROSOFT NETWORKS 1.03]
4018 protocol [LANMAN1.0]
4019 protocol [Windows for Workgroups 3.1a]
4020 protocol [LM1.2X002]
4021 protocol [LANMAN2.1]
4022 protocol [NT LM 0.12]
4025 protocol [PC NETWORK PROGRAM 1.0]
4026 protocol [XENIX CORE]
4027 protocol [MICROSOFT NETWORKS 1.03]
4028 protocol [LANMAN1.0]
4029 protocol [Windows for Workgroups 3.1a]
4030 protocol [LM1.2X002]
4031 protocol [LANMAN2.1]
4032 protocol [NT LM 0.12]
4035 protocol [PC NETWORK PROGRAM 1.0]
4036 protocol [XENIX CORE]
4037 protocol [LANMAN1.0]
4038 protocol [LM1.2X002]
4039 protocol [LANMAN2.1]
4043 * Modified to recognize the architecture of the remote machine better.
4045 * This appears to be the matrix of which protocol is used by which
4047 Protocol WfWg Win95 WinNT OS/2
4048 PC NETWORK PROGRAM 1.0 1 1 1 1
4050 MICROSOFT NETWORKS 3.0 2 2
4052 MICROSOFT NETWORKS 1.03 3
4055 Windows for Workgroups 3.1a 5 5 5
4060 * tim@fsg.com 09/29/95
4063 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4064 #define ARCH_WIN95 0x2
4065 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4066 #define ARCH_WINNT 0x8
4067 #define ARCH_SAMBA 0x10
4069 #define ARCH_ALL 0x1F
4071 /* List of supported protocols, most desired first */
4075 int (*proto_reply_fn)(char *);
4077 } supported_protocols[] = {
4078 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4079 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4080 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4081 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4082 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4083 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4084 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4085 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4086 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4091 /****************************************************************************
4093 ****************************************************************************/
4094 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4096 int outsize = set_message(outbuf,1,0,True);
4101 int bcc = SVAL(smb_buf(inbuf),-2);
4102 int arch = ARCH_ALL;
4104 p = smb_buf(inbuf)+1;
4105 while (p < (smb_buf(inbuf) + bcc))
4108 DEBUG(3,("Requested protocol [%s]\n",p));
4109 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4110 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4111 else if (strcsequal(p,"DOS LM1.2X002"))
4112 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4113 else if (strcsequal(p,"DOS LANMAN2.1"))
4114 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4115 else if (strcsequal(p,"NT LM 0.12"))
4116 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4117 else if (strcsequal(p,"LANMAN2.1"))
4118 arch &= ( ARCH_WINNT | ARCH_OS2 );
4119 else if (strcsequal(p,"LM1.2X002"))
4120 arch &= ( ARCH_WINNT | ARCH_OS2 );
4121 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4123 else if (strcsequal(p,"XENIX CORE"))
4124 arch &= ( ARCH_WINNT | ARCH_OS2 );
4125 else if (strcsequal(p,"Samba")) {
4135 set_remote_arch(RA_SAMBA);
4138 set_remote_arch(RA_WFWG);
4141 set_remote_arch(RA_WIN95);
4144 set_remote_arch(RA_WINNT);
4147 set_remote_arch(RA_OS2);
4150 set_remote_arch(RA_UNKNOWN);
4154 /* possibly reload - change of architecture */
4155 reload_services(True);
4157 /* a special case to stop password server loops */
4158 if (Index == 1 && strequal(remote_machine,myhostname) &&
4159 (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4160 exit_server("Password server loop!");
4162 /* Check for protocols, most desirable first */
4163 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4165 p = smb_buf(inbuf)+1;
4167 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4168 while (p < (smb_buf(inbuf) + bcc))
4170 if (strequal(p,supported_protocols[protocol].proto_name))
4179 SSVAL(outbuf,smb_vwv0,choice);
4181 extern fstring remote_proto;
4182 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4183 reload_services(True);
4184 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4185 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4188 DEBUG(0,("No protocol supported !\n"));
4190 SSVAL(outbuf,smb_vwv0,choice);
4192 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4198 /****************************************************************************
4199 close all open files for a connection
4200 ****************************************************************************/
4201 static void close_open_files(int cnum)
4204 for (i=0;i<MAX_FNUMS;i++)
4205 if( Files[i].cnum == cnum && Files[i].open) {
4206 if(Files[i].is_directory)
4209 close_file(i,False);
4215 /****************************************************************************
4217 ****************************************************************************/
4218 void close_cnum(int cnum, uint16 vuid)
4221 DirCacheFlush(SNUM(cnum));
4225 if (!OPEN_CNUM(cnum))
4227 DEBUG(0,("Can't close cnum %d\n",cnum));
4231 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4233 remote_machine,client_addr(Client),
4234 lp_servicename(SNUM(cnum))));
4236 yield_connection(cnum,
4237 lp_servicename(SNUM(cnum)),
4238 lp_max_connections(SNUM(cnum)));
4240 if (lp_status(SNUM(cnum)))
4241 yield_connection(cnum,"STATUS.",MAXSTATUS);
4243 close_open_files(cnum);
4244 dptr_closecnum(cnum);
4246 /* execute any "postexec = " line */
4247 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4250 pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4251 standard_sub(cnum,cmd);
4252 smbrun(cmd,NULL,False);
4257 /* execute any "root postexec = " line */
4258 if (*lp_rootpostexec(SNUM(cnum)))
4261 pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4262 standard_sub(cnum,cmd);
4263 smbrun(cmd,NULL,False);
4266 Connections[cnum].open = False;
4267 num_connections_open--;
4268 if (Connections[cnum].ngroups && Connections[cnum].groups)
4270 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4271 free(Connections[cnum].groups);
4272 free(Connections[cnum].igroups);
4273 Connections[cnum].groups = NULL;
4274 Connections[cnum].igroups = NULL;
4275 Connections[cnum].ngroups = 0;
4278 free_namearray(Connections[cnum].veto_list);
4279 free_namearray(Connections[cnum].hide_list);
4280 free_namearray(Connections[cnum].veto_oplock_list);
4282 string_set(&Connections[cnum].user,"");
4283 string_set(&Connections[cnum].dirpath,"");
4284 string_set(&Connections[cnum].connectpath,"");
4290 /*******************************************************************
4291 prepare to dump a core file - carefully!
4292 ********************************************************************/
4293 static BOOL dump_core(void)
4297 pstrcpy(dname,debugf);
4298 if ((p=strrchr(dname,'/'))) *p=0;
4299 pstrcat(dname,"/corefiles");
4301 sys_chown(dname,getuid(),getgid());
4303 if (chdir(dname)) return(False);
4306 #ifdef HAVE_GETRLIMIT
4310 getrlimit(RLIMIT_CORE, &rlp);
4311 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4312 setrlimit(RLIMIT_CORE, &rlp);
4313 getrlimit(RLIMIT_CORE, &rlp);
4314 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4320 DEBUG(0,("Dumping core in %s\n",dname));
4325 /****************************************************************************
4327 ****************************************************************************/
4328 void exit_server(char *reason)
4330 static int firsttime=1;
4333 if (!firsttime) exit(0);
4337 DEBUG(2,("Closing connections\n"));
4338 for (i=0;i<MAX_CONNECTIONS;i++)
4339 if (Connections[i].open)
4340 close_cnum(i,(uint16)-1);
4342 if (dcelogin_atmost_once)
4346 int oldlevel = DEBUGLEVEL;
4348 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4350 show_msg(last_inbuf);
4351 DEBUGLEVEL = oldlevel;
4352 DEBUG(0,("===============================================================\n"));
4354 if (dump_core()) return;
4360 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4364 /****************************************************************************
4365 do some standard substitutions in a string
4366 ****************************************************************************/
4367 void standard_sub(int cnum,char *str)
4369 if (VALID_CNUM(cnum)) {
4372 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4374 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4375 string_sub(p,"%H",home);
4379 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4380 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4381 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4382 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4384 * Patch from jkf@soton.ac.uk
4385 * Left the %N (NIS server name) in standard_sub_basic as it
4386 * is a feature for logon servers, hence uses the username.
4387 * The %p (NIS server path) code is here as it is used
4388 * instead of the default "path =" string in [homes] and so
4389 * needs the service name, not the username.
4391 case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4392 case '\0' : p++; break; /* don't run off the end of the string */
4393 default : p+=2; break;
4397 standard_sub_basic(str);
4401 These flags determine some of the permissions required to do an operation
4403 Note that I don't set NEED_WRITE on some write operations because they
4404 are used by some brain-dead clients when printing, and I don't want to
4405 force write permissions on print services.
4407 #define AS_USER (1<<0)
4408 #define NEED_WRITE (1<<1)
4409 #define TIME_INIT (1<<2)
4410 #define CAN_IPC (1<<3)
4411 #define AS_GUEST (1<<5)
4412 #define QUEUE_IN_OPLOCK (1<<6)
4415 define a list of possible SMB messages and their corresponding
4416 functions. Any message that has a NULL function is unimplemented -
4417 please feel free to contribute implementations!
4419 struct smb_message_struct
4423 int (*fn)(char *, char *, int, int);
4433 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4434 {SMBtcon,"SMBtcon",reply_tcon,0},
4435 {SMBtdis,"SMBtdis",reply_tdis,0},
4436 {SMBexit,"SMBexit",reply_exit,0},
4437 {SMBioctl,"SMBioctl",reply_ioctl,0},
4438 {SMBecho,"SMBecho",reply_echo,0},
4439 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4440 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4441 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4442 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4443 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4444 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4445 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4446 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4448 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4449 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4450 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4452 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4453 {SMBread,"SMBread",reply_read,AS_USER},
4454 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4455 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4456 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4457 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4458 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4459 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4461 /* this is a Pathworks specific call, allowing the
4462 changing of the root path */
4463 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4465 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4466 {SMBflush,"SMBflush",reply_flush,AS_USER},
4467 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4468 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4469 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4470 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4471 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4472 {SMBlock,"SMBlock",reply_lock,AS_USER},
4473 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4475 /* CORE+ PROTOCOL FOLLOWS */
4477 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4478 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4479 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4480 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4481 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4483 /* LANMAN1.0 PROTOCOL FOLLOWS */
4485 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4486 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4487 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4488 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4489 {SMBwritec,"SMBwritec",NULL,AS_USER},
4490 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4491 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4492 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4493 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4494 {SMBioctls,"SMBioctls",NULL,AS_USER},
4495 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4496 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4498 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4499 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4500 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4501 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4503 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4504 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4505 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4507 /* LANMAN2.0 PROTOCOL FOLLOWS */
4508 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4509 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4510 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4511 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4513 /* NT PROTOCOL FOLLOWS */
4514 {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4515 {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
4516 {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
4517 {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
4519 /* messaging routines */
4520 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4521 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4522 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4523 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4525 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4527 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4528 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4529 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4530 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4533 /****************************************************************************
4534 return a string containing the function name of a SMB command
4535 ****************************************************************************/
4536 char *smb_fn_name(int type)
4538 static char *unknown_name = "SMBunknown";
4539 static int num_smb_messages =
4540 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4543 for (match=0;match<num_smb_messages;match++)
4544 if (smb_messages[match].code == type)
4547 if (match == num_smb_messages)
4548 return(unknown_name);
4550 return(smb_messages[match].name);
4554 /****************************************************************************
4555 do a switch on the message type, and return the response size
4556 ****************************************************************************/
4557 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4561 static int num_smb_messages =
4562 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4566 struct timeval msg_start_time;
4567 struct timeval msg_end_time;
4568 static unsigned long total_time = 0;
4570 GetTimeOfDay(&msg_start_time);
4577 last_message = type;
4579 /* make sure this is an SMB packet */
4580 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4582 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4586 for (match=0;match<num_smb_messages;match++)
4587 if (smb_messages[match].code == type)
4590 if (match == num_smb_messages)
4592 DEBUG(0,("Unknown message type %d!\n",type));
4593 outsize = reply_unknown(inbuf,outbuf);
4597 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4599 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4602 * Queue this message as we are the process of an oplock break.
4605 DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4608 push_smb_message( inbuf, size);
4612 if (smb_messages[match].fn)
4614 int cnum = SVAL(inbuf,smb_tid);
4615 int flags = smb_messages[match].flags;
4616 static uint16 last_session_tag = UID_FIELD_INVALID;
4617 /* In share mode security we must ignore the vuid. */
4618 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4619 /* Ensure this value is replaced in the incoming packet. */
4620 SSVAL(inbuf,smb_uid,session_tag);
4623 * Ensure the correct username is in sesssetup_user.
4624 * This is a really ugly bugfix for problems with
4625 * multiple session_setup_and_X's being done and
4626 * allowing %U and %G substitutions to work correctly.
4627 * There is a reason this code is done here, don't
4628 * move it unless you know what you're doing... :-).
4631 if(session_tag != last_session_tag ) {
4632 user_struct *vuser = NULL;
4634 last_session_tag = session_tag;
4635 if(session_tag != UID_FIELD_INVALID)
4636 vuser = get_valid_user_struct(session_tag);
4638 pstrcpy( sesssetup_user, vuser->requested_name);
4641 /* does this protocol need to be run as root? */
4642 if (!(flags & AS_USER))
4645 /* does this protocol need to be run as the connected user? */
4646 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4647 if (flags & AS_GUEST)
4650 return(ERROR(ERRSRV,ERRinvnid));
4652 /* this code is to work around a bug is MS client 3 without
4653 introducing a security hole - it needs to be able to do
4654 print queue checks as guest if it isn't logged in properly */
4655 if (flags & AS_USER)
4658 /* does it need write permission? */
4659 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4660 return(ERROR(ERRSRV,ERRaccess));
4662 /* ipc services are limited */
4663 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4664 return(ERROR(ERRSRV,ERRaccess));
4666 /* load service specific parameters */
4667 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4668 return(ERROR(ERRSRV,ERRaccess));
4670 /* does this protocol need to be run as guest? */
4671 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4672 return(ERROR(ERRSRV,ERRaccess));
4676 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4680 outsize = reply_unknown(inbuf,outbuf);
4685 GetTimeOfDay(&msg_end_time);
4686 if (!(smb_messages[match].flags & TIME_INIT))
4688 smb_messages[match].time = 0;
4689 smb_messages[match].flags |= TIME_INIT;
4692 unsigned long this_time =
4693 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4694 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4695 smb_messages[match].time += this_time;
4696 total_time += this_time;
4698 DEBUG(2,("TIME %s %d usecs %g pct\n",
4699 smb_fn_name(type),smb_messages[match].time,
4700 (100.0*smb_messages[match].time) / total_time));
4707 /****************************************************************************
4708 construct a chained reply and add it to the already made reply
4709 **************************************************************************/
4710 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4712 static char *orig_inbuf;
4713 static char *orig_outbuf;
4714 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4715 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4716 char *inbuf2, *outbuf2;
4718 char inbuf_saved[smb_wct];
4719 char outbuf_saved[smb_wct];
4720 extern int chain_size;
4721 int wct = CVAL(outbuf,smb_wct);
4722 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4724 /* maybe its not chained */
4725 if (smb_com2 == 0xFF) {
4726 CVAL(outbuf,smb_vwv0) = 0xFF;
4730 if (chain_size == 0) {
4731 /* this is the first part of the chain */
4733 orig_outbuf = outbuf;
4736 /* we need to tell the client where the next part of the reply will be */
4737 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4738 CVAL(outbuf,smb_vwv0) = smb_com2;
4740 /* remember how much the caller added to the chain, only counting stuff
4741 after the parameter words */
4742 chain_size += outsize - smb_wct;
4744 /* work out pointers into the original packets. The
4745 headers on these need to be filled in */
4746 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4747 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4749 /* remember the original command type */
4750 smb_com1 = CVAL(orig_inbuf,smb_com);
4752 /* save the data which will be overwritten by the new headers */
4753 memcpy(inbuf_saved,inbuf2,smb_wct);
4754 memcpy(outbuf_saved,outbuf2,smb_wct);
4756 /* give the new packet the same header as the last part of the SMB */
4757 memmove(inbuf2,inbuf,smb_wct);
4759 /* create the in buffer */
4760 CVAL(inbuf2,smb_com) = smb_com2;
4762 /* create the out buffer */
4763 bzero(outbuf2,smb_size);
4764 set_message(outbuf2,0,0,True);
4765 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4767 memcpy(outbuf2+4,inbuf2+4,4);
4768 CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4769 CVAL(outbuf2,smb_reh) = 0;
4770 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4772 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4773 SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4774 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4775 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4776 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4777 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4779 DEBUG(3,("Chained message\n"));
4782 /* process the request */
4783 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4784 bufsize-chain_size);
4786 /* copy the new reply and request headers over the old ones, but
4787 preserve the smb_com field */
4788 memmove(orig_outbuf,outbuf2,smb_wct);
4789 CVAL(orig_outbuf,smb_com) = smb_com1;
4791 /* restore the saved data, being careful not to overwrite any
4792 data from the reply header */
4793 memcpy(inbuf2,inbuf_saved,smb_wct);
4795 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4796 if (ofs < 0) ofs = 0;
4797 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4805 /****************************************************************************
4806 construct a reply to the incoming packet
4807 ****************************************************************************/
4808 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4810 int type = CVAL(inbuf,smb_com);
4812 int msg_type = CVAL(inbuf,0);
4813 extern int chain_size;
4815 smb_last_time = time(NULL);
4821 bzero(outbuf,smb_size);
4824 return(reply_special(inbuf,outbuf));
4826 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4827 set_message(outbuf,0,0,True);
4829 memcpy(outbuf+4,inbuf+4,4);
4830 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4831 CVAL(outbuf,smb_reh) = 0;
4832 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4834 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4835 SSVAL(outbuf,smb_err,SMB_SUCCESS);
4836 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4837 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4838 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4839 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4841 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4843 outsize += chain_size;
4846 smb_setlen(outbuf,outsize - 4);
4850 /****************************************************************************
4851 process commands from the client
4852 ****************************************************************************/
4853 static void process(void)
4857 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4858 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4859 if ((InBuffer == NULL) || (OutBuffer == NULL))
4862 InBuffer += SMB_ALIGNMENT;
4863 OutBuffer += SMB_ALIGNMENT;
4866 DEBUG(3,("priming nmbd\n"));
4869 ip = *interpret_addr2("localhost");
4870 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4872 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4876 /* re-initialise the timezone */
4881 int deadtime = lp_deadtime()*60;
4883 int last_keepalive=0;
4884 int service_load_counter = 0;
4885 BOOL got_smb = False;
4888 deadtime = DEFAULT_SMBD_TIMEOUT;
4890 #if USE_READ_PREDICTION
4891 if (lp_readprediction())
4892 do_read_prediction();
4897 for (counter=SMBD_SELECT_LOOP;
4898 !receive_message_or_smb(Client,oplock_sock,
4899 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4900 counter += SMBD_SELECT_LOOP)
4904 BOOL allidle = True;
4905 extern int keepalive;
4907 if (counter > 365 * 3600) /* big number of seconds. */
4910 service_load_counter = 0;
4913 if (smb_read_error == READ_EOF)
4915 DEBUG(3,("end of file from client\n"));
4919 if (smb_read_error == READ_ERROR)
4921 DEBUG(3,("receive_smb error (%s) exiting\n",
4928 /* become root again if waiting */
4931 /* check for smb.conf reload */
4932 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4934 service_load_counter = counter;
4936 /* reload services, if files have changed. */
4937 reload_services(True);
4941 * If reload_after_sighup == True then we got a SIGHUP
4942 * and are being asked to reload. Fix from <branko.cibej@hermes.si>
4945 if (reload_after_sighup)
4947 DEBUG(0,("Reloading services after SIGHUP\n"));
4948 reload_services(False);
4949 reload_after_sighup = False;
4952 /* automatic timeout if all connections are closed */
4953 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4955 DEBUG(2,("%s Closing idle connection\n",timestring()));
4959 if (keepalive && (counter-last_keepalive)>keepalive)
4961 struct cli_state *cli = server_client();
4962 if (!send_keepalive(Client)) {
4963 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4966 /* also send a keepalive to the password server if its still
4968 if (cli && cli->initialised)
4969 send_keepalive(cli->fd);
4970 last_keepalive = counter;
4973 /* check for connection timeouts */
4974 for (i=0;i<MAX_CONNECTIONS;i++)
4975 if (Connections[i].open)
4977 /* close dirptrs on connections that are idle */
4978 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4981 if (Connections[i].num_files_open > 0 ||
4982 (t-Connections[i].lastused)<deadtime)
4986 if (allidle && num_connections_open>0)
4988 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4992 if(global_machine_pasword_needs_changing)
4994 unsigned char trust_passwd_hash[16];
4996 pstring remote_machine_list;
4999 * We're in domain level security, and the code that
5000 * read the machine password flagged that the machine
5001 * password needs changing.
5005 * First, open the machine password file with an exclusive lock.
5008 if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5009 DEBUG(0,("process: unable to open the machine account password file for \
5010 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5014 if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5015 DEBUG(0,("process: unable to read the machine account password for \
5016 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5017 trust_password_unlock();
5022 * Make sure someone else hasn't already done this.
5025 if(t < lct + lp_machine_password_timeout()) {
5026 trust_password_unlock();
5027 global_machine_pasword_needs_changing = False;
5031 pstrcpy(remote_machine_list, lp_passwordserver());
5033 change_trust_account_password( global_myworkgroup, remote_machine_list);
5034 trust_password_unlock();
5035 global_machine_pasword_needs_changing = False;
5040 process_smb(InBuffer, OutBuffer);
5042 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5047 /****************************************************************************
5048 initialise connect, service and file structs
5049 ****************************************************************************/
5050 static void init_structs(void )
5053 get_myname(myhostname,NULL);
5056 * Set the machine NETBIOS name if not already
5057 * set from the config file.
5060 if (!*global_myname)
5063 fstrcpy( global_myname, myhostname );
5064 p = strchr( global_myname, '.' );
5068 strupper( global_myname );
5070 for (i=0;i<MAX_CONNECTIONS;i++)
5072 Connections[i].open = False;
5073 Connections[i].num_files_open=0;
5074 Connections[i].lastused=0;
5075 Connections[i].used=False;
5076 string_init(&Connections[i].user,"");
5077 string_init(&Connections[i].dirpath,"");
5078 string_init(&Connections[i].connectpath,"");
5079 string_init(&Connections[i].origpath,"");
5082 for (i=0;i<MAX_FNUMS;i++)
5084 Files[i].open = False;
5085 string_init(&Files[i].name,"");
5088 for (i=0;i<MAX_OPEN_FILES;i++)
5090 file_fd_struct *fd_ptr = &FileFd[i];
5091 fd_ptr->ref_count = 0;
5092 fd_ptr->dev = (int32)-1;
5093 fd_ptr->inode = (int32)-1;
5095 fd_ptr->fd_readonly = -1;
5096 fd_ptr->fd_writeonly = -1;
5097 fd_ptr->real_open_flags = -1;
5101 init_rpc_pipe_hnd();
5103 /* for LSA handles */
5104 init_lsa_policy_hnd();
5109 /****************************************************************************
5110 usage on the program
5111 ****************************************************************************/
5112 static void usage(char *pname)
5114 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5116 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5117 printf("Version %s\n",VERSION);
5118 printf("\t-D become a daemon\n");
5119 printf("\t-p port listen on the specified port\n");
5120 printf("\t-d debuglevel set the debuglevel\n");
5121 printf("\t-l log basename. Basename for log/debug files\n");
5122 printf("\t-s services file. Filename of services file\n");
5123 printf("\t-P passive only\n");
5124 printf("\t-a overwrite log file, don't append\n");
5129 /****************************************************************************
5131 ****************************************************************************/
5132 int main(int argc,char *argv[])
5134 extern BOOL append_log;
5135 /* shall I run as a daemon */
5136 BOOL is_daemon = False;
5137 int port = SMB_PORT;
5139 extern char *optarg;
5141 #ifdef HAVE_SET_AUTH_PARAMETERS
5142 set_auth_parameters(argc,argv);
5146 /* needed for SecureWare on SCO */
5154 pstrcpy(debugf,SMBLOGFILE);
5156 pstrcpy(remote_machine, "smb");
5158 setup_logging(argv[0],False);
5160 charset_initialise();
5162 /* make absolutely sure we run as root - to handle cases where people
5163 are crazy enough to have it setuid */
5164 #ifdef HAVE_SETRESUID
5173 fault_setup((void (*)(void *))exit_server);
5174 CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
5176 /* we want total control over the permissions on created files,
5177 so set our umask to 0 */
5184 /* this is for people who can't start the program correctly */
5185 while (argc > 1 && (*argv[1] != '-'))
5191 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5195 pstrcpy(user_socket_options,optarg);
5198 pstrcpy(scope,optarg);
5202 extern BOOL passive;
5207 pstrcpy(servicesf,optarg);
5210 pstrcpy(debugf,optarg);
5214 extern BOOL append_log;
5215 append_log = !append_log;
5225 DEBUGLEVEL = atoi(optarg);
5228 port = atoi(optarg);
5241 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5242 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5244 #ifdef HAVE_GETRLIMIT
5245 #ifdef RLIMIT_NOFILE
5248 getrlimit(RLIMIT_NOFILE, &rlp);
5250 * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5251 * extra fd we need to read directories, as well as the log files
5252 * and standard handles etc.
5254 rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5255 setrlimit(RLIMIT_NOFILE, &rlp);
5256 getrlimit(RLIMIT_NOFILE, &rlp);
5257 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5263 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5264 getuid(),getgid(),geteuid(),getegid()));
5266 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5268 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5274 if (!reload_services(False))
5279 extern BOOL sslEnabled;
5280 sslEnabled = lp_ssl_enabled();
5284 #endif /* WITH_SSL */
5286 codepage_initialise(lp_client_code_page());
5288 pstrcpy(global_myworkgroup, lp_workgroup());
5290 if(!pdb_generate_machine_sid()) {
5291 DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5295 CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
5297 /* Setup the signals that allow the debug log level
5298 to by dynamically changed. */
5300 /* If we are using the malloc debug code we can't use
5301 SIGUSR1 and SIGUSR2 to do debug level changes. */
5304 #if defined(SIGUSR1)
5305 CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5306 #endif /* SIGUSR1 */
5308 #if defined(SIGUSR2)
5309 CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5310 #endif /* SIGUSR2 */
5311 #endif /* MEM_MAN */
5313 DEBUG(3,("%s loaded services\n",timestring()));
5315 if (!is_daemon && !is_a_socket(0))
5317 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5323 DEBUG(3,("%s becoming a daemon\n",timestring()));
5327 if (!directory_exist(lp_lockdir(), NULL)) {
5328 mkdir(lp_lockdir(), 0755);
5332 pidfile_create("smbd");
5335 if (!open_sockets(is_daemon,port))
5338 if (!locking_init(0))
5341 if(!initialize_password_db())
5344 /* possibly reload the services file. */
5345 reload_services(True);
5347 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5351 if (sys_chroot(lp_rootdir()) == 0)
5352 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5355 /* Setup the oplock IPC socket. */
5356 if(!open_oplock_ipc())
5362 exit_server("normal exit");