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 static 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 /* for readability... */
120 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
121 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
122 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
123 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
124 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
126 /****************************************************************************
127 when exiting, take the whole family
128 ****************************************************************************/
131 exit_server("caught signal");
132 return 0; /* Keep -Wall happy :-) */
134 /****************************************************************************
135 Send a SIGTERM to our process group.
136 *****************************************************************************/
139 if(am_parent) kill(0,SIGTERM);
142 /****************************************************************************
143 change a dos mode to a unix mode
144 base permission for files:
145 everybody gets read bit set
146 dos readonly is represented in unix by removing everyone's write bit
147 dos archive is represented in unix by the user's execute bit
148 dos system is represented in unix by the group's execute bit
149 dos hidden is represented in unix by the other's execute bit
150 Then apply create mask,
152 base permission for directories:
153 dos directory is represented in unix by unix's dir bit and the exec bit
154 Then apply create mask,
156 ****************************************************************************/
157 mode_t unix_mode(connection_struct *conn,int dosmode)
159 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
161 if ( !IS_DOS_READONLY(dosmode) )
162 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
164 if (IS_DOS_DIR(dosmode)) {
165 /* We never make directories read only for the owner as under DOS a user
166 can always create a file in a read-only directory. */
167 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
168 /* Apply directory mask */
169 result &= lp_dir_mode(SNUM(conn));
170 /* Add in force bits */
171 result |= lp_force_dir_mode(SNUM(conn));
173 if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
176 if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
179 if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
182 /* Apply mode mask */
183 result &= lp_create_mode(SNUM(conn));
184 /* Add in force bits */
185 result |= lp_force_create_mode(SNUM(conn));
191 /****************************************************************************
192 change a unix mode to a dos mode
193 ****************************************************************************/
194 int dos_mode(connection_struct *conn,char *path,struct stat *sbuf)
197 extern struct current_user current_user;
199 DEBUG(8,("dos_mode: %s\n", path));
201 if (CAN_WRITE(conn) && !lp_alternate_permissions(SNUM(conn))) {
202 if (!((sbuf->st_mode & S_IWOTH) ||
204 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
205 ((sbuf->st_mode & S_IWGRP) &&
206 in_group(sbuf->st_gid,current_user.gid,
207 current_user.ngroups,current_user.groups))))
210 if ((sbuf->st_mode & S_IWUSR) == 0)
214 if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
217 if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
220 if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
223 if (S_ISDIR(sbuf->st_mode))
224 result = aDIR | (result & aRONLY);
228 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
233 /* hide files with a name starting with a . */
234 if (lp_hide_dot_files(SNUM(conn)))
236 char *p = strrchr(path,'/');
242 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
246 /* Optimization : Only call is_hidden_path if it's not already
248 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path))
253 DEBUG(8,("dos_mode returning "));
255 if (result & aHIDDEN) DEBUG(8, ("h"));
256 if (result & aRONLY ) DEBUG(8, ("r"));
257 if (result & aSYSTEM) DEBUG(8, ("s"));
258 if (result & aDIR ) DEBUG(8, ("d"));
259 if (result & aARCH ) DEBUG(8, ("a"));
266 /*******************************************************************
267 chmod a file - but preserve some bits
268 ********************************************************************/
269 int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st)
278 if (sys_stat(fname,st)) return(-1);
281 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
283 if (dos_mode(conn,fname,st) == dosmode) return(0);
285 unixmode = unix_mode(conn,dosmode);
287 /* preserve the s bits */
288 mask |= (S_ISUID | S_ISGID);
290 /* preserve the t bit */
295 /* possibly preserve the x bits */
296 if (!MAP_ARCHIVE(conn)) mask |= S_IXUSR;
297 if (!MAP_SYSTEM(conn)) mask |= S_IXGRP;
298 if (!MAP_HIDDEN(conn)) mask |= S_IXOTH;
300 unixmode |= (st->st_mode & mask);
302 /* if we previously had any r bits set then leave them alone */
303 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
304 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
308 /* if we previously had any w bits set then leave them alone
309 if the new mode is not rdonly */
310 if (!IS_DOS_READONLY(dosmode) &&
311 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
312 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
316 return(sys_chmod(fname,unixmode));
319 /*******************************************************************
320 Wrapper around sys_utime that possibly allows DOS semantics rather
322 *******************************************************************/
324 int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
326 extern struct current_user current_user;
332 if(sys_utime(fname, times) == 0)
335 if((errno != EPERM) && (errno != EACCES))
338 if(!lp_dos_filetimes(SNUM(conn)))
341 /* We have permission (given by the Samba admin) to
342 break POSIX semantics and allow a user to change
343 the time on a file they don't own but can write to
347 if(sys_stat(fname,&sb) != 0)
350 /* Check if we have write access. */
351 if (CAN_WRITE(conn)) {
352 if (((sb.st_mode & S_IWOTH) ||
354 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
355 ((sb.st_mode & S_IWGRP) &&
356 in_group(sb.st_gid,current_user.gid,
357 current_user.ngroups,current_user.groups)))) {
358 /* We are allowed to become root and change the filetime. */
360 ret = sys_utime(fname, times);
361 unbecome_root(False);
368 /*******************************************************************
369 Change a filetime - possibly allowing DOS semantics.
370 *******************************************************************/
372 BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
374 struct utimbuf times;
376 if (null_mtime(mtime)) return(True);
378 times.modtime = times.actime = mtime;
380 if (file_utime(conn, fname, ×)) {
381 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
387 /****************************************************************************
388 check if two filenames are equal
390 this needs to be careful about whether we are case sensitive
391 ****************************************************************************/
392 static BOOL fname_equal(char *name1, char *name2)
394 int l1 = strlen(name1);
395 int l2 = strlen(name2);
397 /* handle filenames ending in a single dot */
398 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
402 ret = fname_equal(name1,name2);
407 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
411 ret = fname_equal(name1,name2);
416 /* now normal filename handling */
418 return(strcmp(name1,name2) == 0);
420 return(strequal(name1,name2));
424 /****************************************************************************
425 mangle the 2nd name and check if it is then equal to the first name
426 ****************************************************************************/
427 static BOOL mangled_equal(char *name1, char *name2)
431 if (is_8_3(name2, True))
434 pstrcpy(tmpname,name2);
435 mangle_name_83(tmpname,sizeof(tmpname));
437 return(strequal(name1,tmpname));
441 /****************************************************************************
442 scan a directory to find a filename, matching without case sensitivity
444 If the name looks like a mangled name then try via the mangling functions
445 ****************************************************************************/
446 static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache)
453 mangled = is_mangled(name);
455 /* handle null paths */
459 if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) {
460 pstrcpy(name, dname);
465 * The incoming name can be mangled, and if we de-mangle it
466 * here it will not compare correctly against the filename (name2)
467 * read from the directory and then mangled by the name_map_mangle()
468 * call. We need to mangle both names or neither.
472 mangled = !check_mangled_cache( name );
474 /* open the directory */
475 if (!(cur_dir = OpenDir(conn, path, True)))
477 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
481 /* now scan for matching names */
482 while ((dname = ReadDirName(cur_dir)))
485 (strequal(dname,".") || strequal(dname,"..")))
488 pstrcpy(name2,dname);
489 if (!name_map_mangle(name2,False,SNUM(conn))) continue;
491 if ((mangled && mangled_equal(name,name2))
492 || fname_equal(name, name2))
494 /* we've found the file, change it's name and return */
495 if (docache) DirCacheAdd(path,name,dname,SNUM(conn));
496 pstrcpy(name, dname);
506 /****************************************************************************
507 This routine is called to convert names from the dos namespace to unix
508 namespace. It needs to handle any case conversions, mangling, format
511 We assume that we have already done a chdir() to the right "root" directory
514 The function will return False if some part of the name except for the last
515 part cannot be resolved
517 If the saved_last_component != 0, then the unmodified last component
518 of the pathname is returned there. This is used in an exceptional
519 case in reply_mv (so far). If saved_last_component == 0 then nothing
522 The bad_path arg is set to True if the filename walk failed. This is
523 used to pick the correct error code to return between ENOENT and ENOTDIR
524 as Windows applications depend on ERRbadpath being returned if a component
525 of a pathname does not exist.
526 ****************************************************************************/
527 BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, BOOL *bad_path)
537 if(saved_last_component)
538 *saved_last_component = 0;
540 /* convert to basic unix format - removing \ chars and cleaning it up */
542 unix_clean_name(name);
544 /* names must be relative to the root of the service - trim any leading /.
545 also trim trailing /'s */
546 trim_string(name,"/","/");
549 * Ensure saved_last_component is valid even if file exists.
551 if(saved_last_component) {
552 end = strrchr(name, '/');
554 pstrcpy(saved_last_component, end + 1);
556 pstrcpy(saved_last_component, name);
559 if (!case_sensitive &&
560 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
563 /* check if it's a printer file */
566 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
570 slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
571 /* sanitise the name */
572 for (s=name2 ; *s ; s++)
573 if (!issafe(*s)) *s = '_';
574 pstrcpy(name,(char *)mktemp(name2));
579 /* stat the name - if it exists then we are all done! */
580 if (sys_stat(name,&st) == 0)
585 DEBUG(5,("unix_convert(%s)\n",name));
587 /* a special case - if we don't have any mangling chars and are case
588 sensitive then searching won't help */
589 if (case_sensitive && !is_mangled(name) &&
590 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
593 /* now we need to recursively match the name against the real
594 directory structure */
597 while (strncmp(start,"./",2) == 0)
600 /* now match each part of the path name separately, trying the names
601 as is first, then trying to scan the directory for matching names */
602 for (;start;start = (end?end+1:(char *)NULL))
604 /* pinpoint the end of this section of the filename */
605 end = strchr(start, '/');
607 /* chop the name at this point */
610 if(saved_last_component != 0)
611 pstrcpy(saved_last_component, end ? end + 1 : start);
613 /* check if the name exists up to this point */
614 if (sys_stat(name, &st) == 0)
616 /* it exists. it must either be a directory or this must be
617 the last part of the path for it to be OK */
618 if (end && !(st.st_mode & S_IFDIR))
620 /* an intermediate part of the name isn't a directory */
621 DEBUG(5,("Not a dir %s\n",start));
632 /* remember the rest of the pathname so it can be restored
634 if (end) pstrcpy(rest,end+1);
636 /* try to find this part of the path in the directory */
637 if (strchr(start,'?') || strchr(start,'*') ||
638 !scan_directory(dirpath, start, conn, end?True:False))
642 /* an intermediate part of the name can't be found */
643 DEBUG(5,("Intermediate not found %s\n",start));
645 /* We need to return the fact that the intermediate
646 name resolution failed. This is used to return an
647 error of ERRbadpath rather than ERRbadfile. Some
648 Windows applications depend on the difference between
655 /* just the last part of the name doesn't exist */
656 /* we may need to strupper() or strlower() it in case
657 this conversion is being used for file creation
659 /* if the filename is of mixed case then don't normalise it */
660 if (!case_preserve &&
661 (!strhasupper(start) || !strhaslower(start)))
664 /* check on the mangled stack to see if we can recover the
665 base of the filename */
666 if (is_mangled(start))
667 check_mangled_cache( start );
669 DEBUG(5,("New file %s\n",start));
673 /* restore the rest of the string */
676 pstrcpy(start+strlen(start)+1,rest);
677 end = start + strlen(start);
681 /* add to the dirpath that we have resolved so far */
682 if (*dirpath) pstrcat(dirpath,"/");
683 pstrcat(dirpath,start);
685 /* restore the / that we wiped out earlier */
689 /* the name has been resolved */
690 DEBUG(5,("conversion finished %s\n",name));
695 /****************************************************************************
696 check a filename - possibly caling reducename
698 This is called by every routine before it allows an operation on a filename.
699 It does any final confirmation necessary to ensure that the filename is
700 a valid one for the user to access.
701 ****************************************************************************/
702 BOOL check_name(char *name,connection_struct *conn)
708 if (IS_VETO_PATH(conn, name)) {
709 DEBUG(5,("file path name %s vetoed\n",name));
713 ret = reduce_name(name,conn->connectpath,lp_widelinks(SNUM(conn)));
715 /* Check if we are allowing users to follow symlinks */
716 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
717 University of Geneva */
720 if (!lp_symlinks(SNUM(conn)))
723 if ( (sys_lstat(name,&statbuf) != -1) &&
724 (S_ISLNK(statbuf.st_mode)) )
726 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
733 DEBUG(5,("check_name on %s failed\n",name));
738 /****************************************************************************
739 check a filename - possibly caling reducename
740 ****************************************************************************/
741 static void check_for_pipe(char *fname)
743 /* special case of pipe opens */
747 if (strstr(s,"pipe/"))
749 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
750 unix_ERR_class = ERRSRV;
751 unix_ERR_code = ERRaccess;
755 /****************************************************************************
756 fd support routines - attempt to do a sys_open
757 ****************************************************************************/
758 static int fd_attempt_open(char *fname, int flags, int mode)
760 int fd = sys_open(fname,flags,mode);
762 /* Fix for files ending in '.' */
763 if((fd == -1) && (errno == ENOENT) &&
764 (strchr(fname,'.')==NULL))
767 fd = sys_open(fname,flags,mode);
770 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
771 if ((fd == -1) && (errno == ENAMETOOLONG))
774 char *p = strrchr(fname, '/');
776 if (p == fname) /* name is "/xxx" */
778 max_len = pathconf("/", _PC_NAME_MAX);
781 else if ((p == NULL) || (p == fname))
784 max_len = pathconf(".", _PC_NAME_MAX);
789 max_len = pathconf(fname, _PC_NAME_MAX);
793 if (strlen(p) > max_len)
795 char tmp = p[max_len];
798 if ((fd = sys_open(fname,flags,mode)) == -1)
806 /****************************************************************************
807 Cache a uid_t currently with this file open. This is an optimization only
808 used when multiple sessionsetup's have been done to one smbd.
809 ****************************************************************************/
810 static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
812 if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
814 fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
817 /****************************************************************************
818 Remove a uid_t that currently has this file open. This is an optimization only
819 used when multiple sessionsetup's have been done to one smbd.
820 ****************************************************************************/
821 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
824 for(i = 0; i < fd_ptr->uid_cache_count; i++)
825 if(fd_ptr->uid_users_cache[i] == u) {
826 if(i < (fd_ptr->uid_cache_count-1))
827 memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
828 sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
829 fd_ptr->uid_cache_count--;
834 /****************************************************************************
835 Check if a uid_t that currently has this file open is present. This is an
836 optimization only used when multiple sessionsetup's have been done to one smbd.
837 ****************************************************************************/
838 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
841 for(i = 0; i < fd_ptr->uid_cache_count; i++)
842 if(fd_ptr->uid_users_cache[i] == u)
847 /****************************************************************************
848 fd support routines - attempt to find an already open file by dev
849 and inode - increments the ref_count of the returned file_fd_struct *.
850 ****************************************************************************/
851 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
854 file_fd_struct *fd_ptr;
859 for(i = 0; i <= max_file_fd_used; i++) {
861 if((fd_ptr->ref_count > 0) &&
862 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
863 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
866 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
867 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
874 /****************************************************************************
875 fd support routines - attempt to find a empty slot in the FileFd array.
876 Increments the ref_count of the returned entry.
877 ****************************************************************************/
878 static file_fd_struct *fd_get_new(void)
880 extern struct current_user current_user;
882 file_fd_struct *fd_ptr;
884 for(i = 0; i < MAX_OPEN_FILES; i++) {
886 if(fd_ptr->ref_count == 0) {
887 fd_ptr->dev = (uint32)-1;
888 fd_ptr->inode = (uint32)-1;
890 fd_ptr->fd_readonly = -1;
891 fd_ptr->fd_writeonly = -1;
892 fd_ptr->real_open_flags = -1;
893 fd_ptr->uid_cache_count = 0;
894 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
896 /* Increment max used counter if neccessary, cuts down
897 on search time when re-using */
898 if(i > max_file_fd_used)
899 max_file_fd_used = i;
900 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
901 i, fd_ptr->dev, fd_ptr->inode));
905 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
909 /****************************************************************************
910 fd support routines - attempt to re-open an already open fd as O_RDWR.
911 Save the already open fd (we cannot close due to POSIX file locking braindamage.
912 ****************************************************************************/
913 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
915 int fd = sys_open( fname, O_RDWR, mode);
920 if(fd_ptr->real_open_flags == O_RDONLY)
921 fd_ptr->fd_readonly = fd_ptr->fd;
922 if(fd_ptr->real_open_flags == O_WRONLY)
923 fd_ptr->fd_writeonly = fd_ptr->fd;
926 fd_ptr->real_open_flags = O_RDWR;
929 /****************************************************************************
930 fd support routines - attempt to close the file referenced by this fd.
931 Decrements the ref_count and returns it.
932 ****************************************************************************/
933 static int fd_attempt_close(file_fd_struct *fd_ptr)
935 extern struct current_user current_user;
937 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
939 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
940 fd_ptr->real_open_flags,
942 if(fd_ptr->ref_count > 0) {
944 if(fd_ptr->ref_count == 0) {
947 if(fd_ptr->fd_readonly != -1)
948 close(fd_ptr->fd_readonly);
949 if(fd_ptr->fd_writeonly != -1)
950 close(fd_ptr->fd_writeonly);
952 fd_ptr->fd_readonly = -1;
953 fd_ptr->fd_writeonly = -1;
954 fd_ptr->real_open_flags = -1;
955 fd_ptr->dev = (uint32)-1;
956 fd_ptr->inode = (uint32)-1;
957 fd_ptr->uid_cache_count = 0;
959 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
961 return fd_ptr->ref_count;
964 /****************************************************************************
965 fd support routines - check that current user has permissions
966 to open this file. Used when uid not found in optimization cache.
967 This is really ugly code, as due to POSIX locking braindamage we must
968 fork and then attempt to open the file, and return success or failure
970 ****************************************************************************/
971 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
975 if((child_pid = fork()) < 0) {
976 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
986 if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
987 DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
991 if (child_pid != wpid) {
992 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
995 #if defined(WIFEXITED) && defined(WEXITSTATUS)
996 if (WIFEXITED(status_code) == 0) {
997 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
1000 if (WEXITSTATUS(status_code) != 0) {
1001 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1004 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1005 if(status_code != 0) {
1006 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1009 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1012 * Success - the child could open the file.
1014 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
1021 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
1022 if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
1023 /* Access denied. */
1027 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
1034 /****************************************************************************
1036 ****************************************************************************/
1037 static void open_file(int fnum,connection_struct *conn,
1038 char *fname1,int flags,int mode, struct stat *sbuf)
1040 extern struct current_user current_user;
1042 struct stat statbuf;
1043 file_fd_struct *fd_ptr;
1044 files_struct *fsp = &Files[fnum];
1045 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1049 fsp->granted_oplock = False;
1052 pstrcpy(fname,fname1);
1054 /* check permissions */
1057 * This code was changed after seeing a client open request
1058 * containing the open mode of (DENY_WRITE/read-only) with
1059 * the 'create if not exist' bit set. The previous code
1060 * would fail to open the file read only on a read-only share
1061 * as it was checking the flags parameter directly against O_RDONLY,
1062 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1066 if (conn->read_only && !conn->printer) {
1067 /* It's a read-only share - fail if we wanted to write. */
1068 if(accmode != O_RDONLY) {
1069 DEBUG(3,("Permission denied opening %s\n",fname));
1070 check_for_pipe(fname);
1072 } else if(flags & O_CREAT) {
1073 /* We don't want to write - but we must make sure that O_CREAT
1074 doesn't create the file if we have write access into the
1081 /* this handles a bug in Win95 - it doesn't say to create the file when it
1083 if (conn->printer) {
1088 if (flags == O_WRONLY)
1089 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1093 * Ensure we have a valid struct stat so we can search the
1097 if(sys_stat(fname, &statbuf) < 0) {
1098 if(errno != ENOENT) {
1099 DEBUG(3,("Error doing stat on file %s (%s)\n",
1100 fname,strerror(errno)));
1102 check_for_pipe(fname);
1112 * Check to see if we have this file already
1113 * open. If we do, just use the already open fd and increment the
1114 * reference count (fd_get_already_open increments the ref_count).
1116 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1118 * File was already open.
1122 * Check it wasn't open for exclusive use.
1124 if((flags & O_CREAT) && (flags & O_EXCL)) {
1125 fd_ptr->ref_count--;
1131 * Ensure that the user attempting to open
1132 * this file has permissions to do so, if
1133 * the user who originally opened the file wasn't
1134 * the same as the current user.
1137 if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
1138 if(!check_access_allowed_for_current_user( fname, accmode )) {
1139 /* Error - permission denied. */
1140 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
1141 fname, flags, accmode));
1142 /* Ensure the ref_count is decremented. */
1143 fd_ptr->ref_count--;
1144 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1150 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
1153 * If not opened O_RDWR try
1154 * and do that here - a chmod may have been done
1155 * between the last open and now.
1157 if(fd_ptr->real_open_flags != O_RDWR)
1158 fd_attempt_reopen(fname, mode, fd_ptr);
1161 * Ensure that if we wanted write access
1162 * it has been opened for write, and if we wanted read it
1163 * was open for read.
1165 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1166 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1167 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1168 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1169 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1170 check_for_pipe(fname);
1171 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1172 fd_ptr->ref_count--;
1178 /* We need to allocate a new file_fd_struct (this increments the
1180 if((fd_ptr = fd_get_new()) == 0)
1183 * Whatever the requested flags, attempt read/write access,
1184 * as we don't know what flags future file opens may require.
1185 * If this fails, try again with the required flags.
1186 * Even if we open read/write when only read access was
1187 * requested the setting of the can_write flag in
1188 * the file_struct will protect us from errant
1189 * write requests. We never need to worry about O_APPEND
1190 * as this is not set anywhere in Samba.
1192 fd_ptr->real_open_flags = O_RDWR;
1193 /* Set the flags as needed without the read/write modes. */
1194 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1195 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1197 * On some systems opening a file for R/W access on a read only
1198 * filesystems sets errno to EROFS.
1201 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1202 #else /* No EROFS */
1203 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1205 if(accmode != O_RDWR) {
1206 fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
1207 fd_ptr->real_open_flags = accmode;
1212 if ((fd_ptr->fd >=0) &&
1213 conn->printer && lp_minprintspace(SNUM(conn))) {
1217 pstrcpy(dname,fname);
1218 p = strrchr(dname,'/');
1220 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1221 lp_minprintspace(SNUM(conn))) {
1222 fd_attempt_close(fd_ptr);
1224 if(fd_ptr->ref_count == 0)
1233 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1234 fname,strerror(errno),flags));
1235 /* Ensure the ref_count is decremented. */
1236 fd_attempt_close(fd_ptr);
1237 check_for_pipe(fname);
1241 if (fd_ptr->fd >= 0)
1245 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1246 /* Error - backout !! */
1247 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1248 fd_ptr->fd, fname,strerror(errno)));
1249 /* Ensure the ref_count is decremented. */
1250 fd_attempt_close(fd_ptr);
1256 /* Set the correct entries in fd_ptr. */
1257 fd_ptr->dev = (uint32)sbuf->st_dev;
1258 fd_ptr->inode = (uint32)sbuf->st_ino;
1260 fsp->fd_ptr = fd_ptr;
1261 conn->num_files_open++;
1262 fsp->mode = sbuf->st_mode;
1263 GetTimeOfDay(&fsp->open_time);
1264 fsp->vuid = current_user.vuid;
1268 fsp->mmap_ptr = NULL;
1270 fsp->can_lock = True;
1271 fsp->can_read = ((flags & O_WRONLY)==0);
1272 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1273 fsp->share_mode = 0;
1274 fsp->print_file = conn->printer;
1275 fsp->modified = False;
1276 fsp->granted_oplock = False;
1277 fsp->sent_oplock_break = False;
1278 fsp->is_directory = False;
1281 * Note that the file name here is the *untranslated* name
1282 * ie. it is still in the DOS codepage sent from the client.
1283 * All use of this filename will pass though the sys_xxxx
1284 * functions which will do the dos_to_unix translation before
1285 * mapping into a UNIX filename. JRA.
1287 string_set(&fsp->fsp_name,fname);
1288 fsp->wbmpx_ptr = NULL;
1291 * If the printer is marked as postscript output a leading
1292 * file identifier to ensure the file is treated as a raw
1294 * This has a similar effect as CtrlD=0 in WIN.INI file.
1295 * tim@fsg.com 09/06/94
1297 if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
1298 DEBUG(3,("Writing postscript line\n"));
1299 write_file(fnum,"%!\n",3);
1302 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1303 *sesssetup_user ? sesssetup_user : conn->user,fname,
1304 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
1305 conn->num_files_open,fnum));
1310 /* mmap it if read-only */
1311 if (!fsp->can_write) {
1312 fsp->mmap_size = file_size(fname);
1313 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1314 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1316 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
1317 DEBUG(3,("Failed to mmap() %s - %s\n",
1318 fname,strerror(errno)));
1319 fsp->mmap_ptr = NULL;
1325 /*******************************************************************
1327 ********************************************************************/
1328 void sync_file(connection_struct *conn, int fnum)
1331 if(lp_strict_sync(SNUM(conn)))
1332 fsync(Files[fnum].fd_ptr->fd);
1336 /****************************************************************************
1337 run a file if it is a magic script
1338 ****************************************************************************/
1339 static void check_magic(int fnum,connection_struct *conn)
1341 if (!*lp_magicscript(SNUM(conn)))
1344 DEBUG(5,("checking magic for %s\n",Files[fnum].fsp_name));
1348 if (!(p = strrchr(Files[fnum].fsp_name,'/')))
1349 p = Files[fnum].fsp_name;
1353 if (!strequal(lp_magicscript(SNUM(conn)),p))
1359 pstring magic_output;
1361 pstrcpy(fname,Files[fnum].fsp_name);
1363 if (*lp_magicoutput(SNUM(conn)))
1364 pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
1366 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
1369 ret = smbrun(fname,magic_output,False);
1370 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1375 /****************************************************************************
1376 Common code to close a file or a directory.
1377 ****************************************************************************/
1378 static void close_filestruct(files_struct *fsp)
1380 connection_struct *conn = fsp->conn;
1382 fsp->reserved = False;
1384 fsp->is_directory = False;
1386 conn->num_files_open--;
1387 if(fsp->wbmpx_ptr) {
1388 free((char *)fsp->wbmpx_ptr);
1389 fsp->wbmpx_ptr = NULL;
1394 munmap(fsp->mmap_ptr,fsp->mmap_size);
1395 fsp->mmap_ptr = NULL;
1400 /****************************************************************************
1401 Close a file - possibly invalidating the read prediction.
1403 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1404 operation otherwise it came as the result of some other operation such as
1405 the closing of the connection. In the latter case printing and
1406 magic scripts are not run.
1407 ****************************************************************************/
1408 void close_file(int fnum, BOOL normal_close)
1410 files_struct *fs_p = &Files[fnum];
1411 uint32 dev = fs_p->fd_ptr->dev;
1412 uint32 inode = fs_p->fd_ptr->inode;
1414 connection_struct *conn = fs_p->conn;
1416 close_filestruct(fs_p);
1418 #if USE_READ_PREDICTION
1419 invalidate_read_prediction(fs_p->fd_ptr->fd);
1422 if (lp_share_modes(SNUM(conn))) {
1423 lock_share_entry(conn, dev, inode, &token);
1424 del_share_mode(token, fnum);
1427 fd_attempt_close(fs_p->fd_ptr);
1429 if (lp_share_modes(SNUM(conn)))
1430 unlock_share_entry(conn, dev, inode, token);
1432 /* NT uses smbclose to start a print - weird */
1433 if (normal_close && fs_p->print_file)
1434 print_file(conn, fs_p);
1436 /* check for magic scripts */
1438 check_magic(fnum,conn);
1441 if(fs_p->granted_oplock == True)
1442 global_oplocks_open--;
1444 fs_p->sent_oplock_break = False;
1446 DEBUG(2,("%s closed file %s (numopen=%d)\n",
1447 conn->user,fs_p->fsp_name,
1448 conn->num_files_open));
1450 if (fs_p->fsp_name) {
1451 string_free(&fs_p->fsp_name);
1454 /* we will catch bugs faster by zeroing this structure */
1455 memset(fs_p, 0, sizeof(*fs_p));
1458 /****************************************************************************
1459 Close a directory opened by an NT SMB call.
1460 ****************************************************************************/
1462 void close_directory(int fnum)
1464 files_struct *fsp = &Files[fnum];
1466 /* TODO - walk the list of pending
1467 change notify requests and free
1468 any pertaining to this fnum. */
1470 remove_pending_change_notify_requests_by_fid(fnum);
1473 * Do the code common to files and directories.
1475 close_filestruct(fsp);
1478 string_free(&fsp->fsp_name);
1480 /* we will catch bugs faster by zeroing this structure */
1481 memset(fsp, 0, sizeof(*fsp));
1484 /****************************************************************************
1485 Open a directory from an NT SMB call.
1486 ****************************************************************************/
1487 int open_directory(int fnum,connection_struct *conn,
1488 char *fname, int smb_ofun, int unixmode, int *action)
1490 extern struct current_user current_user;
1491 files_struct *fsp = &Files[fnum];
1494 if (smb_ofun & 0x10) {
1496 * Create the directory.
1499 if(sys_mkdir(fname, unixmode) < 0) {
1500 DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
1501 fname, strerror(errno) ));
1505 *action = FILE_WAS_CREATED;
1508 * Check that it *was* a directory.
1511 if(sys_stat(fname, &st) < 0) {
1512 DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
1513 fname, strerror(errno) ));
1517 if(!S_ISDIR(st.st_mode)) {
1518 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1521 *action = FILE_WAS_OPENED;
1524 DEBUG(5,("open_directory: opening directory %s, fnum = %d\n",
1528 * Setup the files_struct for it.
1532 conn->num_files_open++;
1534 GetTimeOfDay(&fsp->open_time);
1535 fsp->vuid = current_user.vuid;
1539 fsp->mmap_ptr = NULL;
1541 fsp->can_lock = True;
1542 fsp->can_read = False;
1543 fsp->can_write = False;
1544 fsp->share_mode = 0;
1545 fsp->print_file = False;
1546 fsp->modified = False;
1547 fsp->granted_oplock = False;
1548 fsp->sent_oplock_break = False;
1549 fsp->is_directory = True;
1552 * Note that the file name here is the *untranslated* name
1553 * ie. it is still in the DOS codepage sent from the client.
1554 * All use of this filename will pass though the sys_xxxx
1555 * functions which will do the dos_to_unix translation before
1556 * mapping into a UNIX filename. JRA.
1558 string_set(&fsp->fsp_name,fname);
1559 fsp->wbmpx_ptr = NULL;
1564 enum {AFAIL,AREAD,AWRITE,AALL};
1566 /*******************************************************************
1567 reproduce the share mode access table
1568 ********************************************************************/
1569 static int access_table(int new_deny,int old_deny,int old_mode,
1570 int share_pid,char *fname)
1572 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1574 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1576 if (old_deny == new_deny && share_pid == pid)
1579 if (old_mode == 0) return(AREAD);
1581 /* the new smbpub.zip spec says that if the file extension is
1582 .com, .dll, .exe or .sym then allow the open. I will force
1583 it to read-only as this seems sensible although the spec is
1584 a little unclear on this. */
1585 if ((fname = strrchr(fname,'.'))) {
1586 if (strequal(fname,".com") ||
1587 strequal(fname,".dll") ||
1588 strequal(fname,".exe") ||
1589 strequal(fname,".sym"))
1599 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1600 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1601 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1604 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1605 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1606 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1609 if (old_deny==DENY_WRITE) return(AREAD);
1610 if (old_deny==DENY_READ) return(AWRITE);
1611 if (old_deny==DENY_NONE) return(AALL);
1617 /*******************************************************************
1618 check if the share mode on a file allows it to be deleted or unlinked
1619 return True if sharing doesn't prevent the operation
1620 ********************************************************************/
1621 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
1625 share_mode_entry *old_shares = 0;
1626 int num_share_modes;
1632 if(!lp_share_modes(SNUM(conn)))
1635 if (sys_stat(fname,&sbuf) == -1) return(True);
1637 dev = (uint32)sbuf.st_dev;
1638 inode = (uint32)sbuf.st_ino;
1640 lock_share_entry(conn, dev, inode, &token);
1641 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1644 * Check if the share modes will give us access.
1647 if(num_share_modes != 0)
1654 broke_oplock = False;
1655 for(i = 0; i < num_share_modes; i++)
1657 share_mode_entry *share_entry = &old_shares[i];
1660 * Break oplocks before checking share modes. See comment in
1661 * open_file_shared for details.
1662 * Check if someone has an oplock on this file. If so we must
1663 * break it before continuing.
1665 if(share_entry->op_type & BATCH_OPLOCK)
1669 * It appears that the NT redirector may have a bug, in that
1670 * it tries to do an SMBmv on a file that it has open with a
1671 * batch oplock, and then fails to respond to the oplock break
1672 * request. This only seems to occur when the client is doing an
1673 * SMBmv to the smbd it is using - thus we try and detect this
1674 * condition by checking if the file being moved is open and oplocked by
1675 * this smbd process, and then not sending the oplock break in this
1676 * special case. If the file was open with a deny mode that
1677 * prevents the move the SMBmv will fail anyway with a share
1678 * violation error. JRA.
1680 if(rename_op && (share_entry->pid == pid))
1682 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1683 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1685 * This next line is a test that allows the deny-mode
1686 * processing to be skipped. This seems to be needed as
1687 * NT insists on the rename succeeding (in Office 9x no less !).
1688 * This should be removed as soon as (a) MS fix the redirector
1689 * bug or (b) NT SMB support in Samba makes NT not issue the
1690 * call (as is my fervent hope). JRA.
1696 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1697 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1699 /* Oplock break.... */
1700 unlock_share_entry(conn, dev, inode, token);
1701 if(request_oplock_break(share_entry, dev, inode) == False)
1703 free((char *)old_shares);
1704 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1705 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1708 lock_share_entry(conn, dev, inode, &token);
1709 broke_oplock = True;
1714 /* someone else has a share lock on it, check to see
1716 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1723 free((char *)old_shares);
1724 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1726 } while(broke_oplock);
1729 /* XXXX exactly what share mode combinations should be allowed for
1730 deleting/renaming? */
1731 /* If we got here then either there were no share modes or
1732 all share modes were DENY_DOS and the pid == getpid() */
1737 unlock_share_entry(conn, dev, inode, token);
1738 if(old_shares != NULL)
1739 free((char *)old_shares);
1743 /****************************************************************************
1745 Helper for open_file_shared.
1746 Truncate a file after checking locking; close file if locked.
1747 **************************************************************************/
1748 static void truncate_unless_locked(int fnum, connection_struct *conn, int token,
1751 files_struct *fsp = &Files[fnum];
1753 if (fsp->can_write){
1754 if (is_locked(fnum,conn,0x3FFFFFFF,0,F_WRLCK)){
1755 /* If share modes are in force for this connection we
1756 have the share entry locked. Unlock it before closing. */
1757 if (*share_locked && lp_share_modes(SNUM(conn)))
1758 unlock_share_entry( conn, fsp->fd_ptr->dev,
1759 fsp->fd_ptr->inode, token);
1760 close_file(fnum,False);
1761 /* Share mode no longer locked. */
1762 *share_locked = False;
1764 unix_ERR_class = ERRDOS;
1765 unix_ERR_code = ERRlock;
1768 ftruncate(fsp->fd_ptr->fd,0);
1772 /****************************************************************************
1773 check if we can open a file with a share mode
1774 ****************************************************************************/
1775 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1776 BOOL fcbopen, int *flags)
1778 int old_open_mode = share->share_mode &0xF;
1779 int old_deny_mode = (share->share_mode >>4)&7;
1781 if (old_deny_mode > 4 || old_open_mode > 2)
1783 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1784 deny_mode,old_deny_mode,old_open_mode,fname));
1789 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1792 if ((access_allowed == AFAIL) ||
1793 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1794 (access_allowed == AREAD && *flags == O_WRONLY) ||
1795 (access_allowed == AWRITE && *flags == O_RDONLY))
1797 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1798 deny_mode,old_deny_mode,old_open_mode,
1799 share->pid,fname, fcbopen, *flags, access_allowed));
1803 if (access_allowed == AREAD)
1806 if (access_allowed == AWRITE)
1813 /****************************************************************************
1814 open a file with a share mode
1815 ****************************************************************************/
1816 void open_file_shared(int fnum,connection_struct *conn,char *fname,int share_mode,int ofun,
1817 int mode,int oplock_request, int *Access,int *action)
1819 files_struct *fs_p = &Files[fnum];
1822 int deny_mode = (share_mode>>4)&7;
1824 BOOL file_existed = file_exist(fname,&sbuf);
1825 BOOL share_locked = False;
1826 BOOL fcbopen = False;
1830 int num_share_modes = 0;
1835 /* this is for OS/2 EAs - try and say we don't support them */
1836 if (strstr(fname,".+,;=[]."))
1838 unix_ERR_class = ERRDOS;
1839 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1840 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1841 unix_ERR_code = ERRcannotopen;
1842 #else /* OS2_WPS_FIX */
1843 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1844 #endif /* OS2_WPS_FIX */
1849 if ((ofun & 0x3) == 0 && file_existed)
1857 if ((ofun & 0x3) == 2)
1860 /* note that we ignore the append flag as
1861 append does not mean the same thing under dos and unix */
1863 switch (share_mode&0xF)
1881 if (share_mode&(1<<14)) {
1886 if (flags != O_RDONLY && file_existed &&
1887 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf))))
1897 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1899 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1904 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1906 if (lp_share_modes(SNUM(conn)))
1909 share_mode_entry *old_shares = 0;
1913 dev = (uint32)sbuf.st_dev;
1914 inode = (uint32)sbuf.st_ino;
1915 lock_share_entry(conn, dev, inode, &token);
1916 share_locked = True;
1917 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1921 * Check if the share modes will give us access.
1924 if(share_locked && (num_share_modes != 0))
1931 broke_oplock = False;
1932 for(i = 0; i < num_share_modes; i++)
1934 share_mode_entry *share_entry = &old_shares[i];
1937 * By observation of NetBench, oplocks are broken *before* share
1938 * modes are checked. This allows a file to be closed by the client
1939 * if the share mode would deny access and the client has an oplock.
1940 * Check if someone has an oplock on this file. If so we must break
1941 * it before continuing.
1943 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1946 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1947 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1949 /* Oplock break.... */
1950 unlock_share_entry(conn, dev, inode, token);
1951 if(request_oplock_break(share_entry, dev, inode) == False)
1953 free((char *)old_shares);
1954 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1955 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1957 unix_ERR_class = ERRDOS;
1958 unix_ERR_code = ERRbadshare;
1961 lock_share_entry(conn, dev, inode, &token);
1962 broke_oplock = True;
1966 /* someone else has a share lock on it, check to see
1968 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1970 free((char *)old_shares);
1971 unlock_share_entry(conn, dev, inode, token);
1973 unix_ERR_class = ERRDOS;
1974 unix_ERR_code = ERRbadshare;
1982 free((char *)old_shares);
1983 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1985 } while(broke_oplock);
1989 free((char *)old_shares);
1992 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1993 flags,flags2,mode));
1995 open_file(fnum,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1996 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1999 open_file(fnum,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
2006 if((share_locked == False) && lp_share_modes(SNUM(conn)))
2008 /* We created the file - thus we must now lock the share entry before creating it. */
2009 dev = fs_p->fd_ptr->dev;
2010 inode = fs_p->fd_ptr->inode;
2011 lock_share_entry(conn, dev, inode, &token);
2012 share_locked = True;
2028 fs_p->share_mode = (deny_mode<<4) | open_mode;
2031 (*Access) = open_mode;
2035 if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
2036 if (!file_existed) *action = FILE_WAS_CREATED;
2037 if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
2039 /* We must create the share mode entry before truncate as
2040 truncate can fail due to locking and have to close the
2041 file (which expects the share_mode_entry to be there).
2043 if (lp_share_modes(SNUM(conn)))
2046 /* JRA. Currently this only services Exlcusive and batch
2047 oplocks (no other opens on this file). This needs to
2048 be extended to level II oplocks (multiple reader
2051 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) &&
2052 !IS_VETO_OPLOCK_PATH(conn,fname))
2054 fs_p->granted_oplock = True;
2055 fs_p->sent_oplock_break = False;
2056 global_oplocks_open++;
2059 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2060 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2068 set_share_mode(token, fnum, port, oplock_request);
2071 if ((flags2&O_TRUNC) && file_existed)
2072 truncate_unless_locked(fnum,conn,token,&share_locked);
2075 if (share_locked && lp_share_modes(SNUM(conn)))
2076 unlock_share_entry( conn, dev, inode, token);
2079 /****************************************************************************
2080 seek a file. Try to avoid the seek if possible
2081 ****************************************************************************/
2082 int seek_file(int fnum,uint32 pos)
2085 files_struct *fsp = &Files[fnum];
2087 if (fsp->print_file && lp_postscript(fsp->conn->service))
2090 fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset);
2094 /****************************************************************************
2096 ****************************************************************************/
2097 int read_file(int fnum,char *data,uint32 pos,int n)
2100 files_struct *fsp = &Files[fnum];
2102 #if USE_READ_PREDICTION
2103 if (!fsp->can_write)
2105 ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
2116 int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1;
2120 memcpy(data,fsp->mmap_ptr+pos,num);
2132 if (seek_file(fnum,pos) != pos)
2134 DEBUG(3,("Failed to seek to %d\n",pos));
2139 readret = read(fsp->fd_ptr->fd,data,n);
2140 if (readret > 0) ret += readret;
2147 /****************************************************************************
2149 ****************************************************************************/
2150 int write_file(int fnum,char *data,int n)
2152 files_struct *fsp = &Files[fnum];
2154 if (!fsp->can_write) {
2159 if (!fsp->modified) {
2161 fsp->modified = True;
2162 if (fstat(fsp->fd_ptr->fd,&st) == 0) {
2163 int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
2164 if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
2165 dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
2170 return(write_data(fsp->fd_ptr->fd,data,n));
2174 /****************************************************************************
2175 load parameters specific to a connection/service
2176 ****************************************************************************/
2177 BOOL become_service(connection_struct *conn,BOOL do_chdir)
2179 extern char magic_char;
2180 static connection_struct *last_conn;
2183 if (!conn || !conn->open) {
2188 conn->lastused = smb_last_time;
2193 ChDir(conn->connectpath) != 0 &&
2194 ChDir(conn->origpath) != 0) {
2195 DEBUG(0,("chdir (%s) failed\n",
2196 conn->connectpath));
2200 if (conn == last_conn)
2205 case_default = lp_defaultcase(snum);
2206 case_preserve = lp_preservecase(snum);
2207 short_case_preserve = lp_shortpreservecase(snum);
2208 case_mangle = lp_casemangle(snum);
2209 case_sensitive = lp_casesensitive(snum);
2210 magic_char = lp_magicchar(snum);
2211 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2216 /****************************************************************************
2217 find a service entry
2218 ****************************************************************************/
2219 int find_service(char *service)
2223 string_sub(service,"\\","/");
2225 iService = lp_servicenumber(service);
2227 /* now handle the special case of a home directory */
2230 char *phome_dir = get_home_dir(service);
2235 * Try mapping the servicename, it may
2236 * be a Windows to unix mapped user name.
2238 if(map_username(service))
2239 phome_dir = get_home_dir(service);
2242 DEBUG(3,("checking for home directory %s gave %s\n",service,
2243 phome_dir?phome_dir:"(NULL)"));
2248 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2250 lp_add_home(service,iHomeService,phome_dir);
2251 iService = lp_servicenumber(service);
2256 /* If we still don't have a service, attempt to add it as a printer. */
2259 int iPrinterService;
2261 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2265 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2267 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2269 DEBUG(3,("%s is a valid printer name\n", service));
2270 DEBUG(3,("adding %s as a printer service\n", service));
2271 lp_add_printer(service,iPrinterService);
2272 iService = lp_servicenumber(service);
2274 DEBUG(0,("failed to add %s as a printer service!\n", service));
2277 DEBUG(3,("%s is not a valid printer name\n", service));
2281 /* just possibly it's a default service? */
2284 char *pdefservice = lp_defaultservice();
2285 if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2288 * We need to do a local copy here as lp_defaultservice()
2289 * returns one of the rotating lp_string buffers that
2290 * could get overwritten by the recursive find_service() call
2291 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2294 pstrcpy(defservice, pdefservice);
2295 iService = find_service(defservice);
2298 string_sub(service,"_","/");
2299 iService = lp_add_service(service,iService);
2305 if (!VALID_SNUM(iService))
2307 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2312 DEBUG(3,("find_service() failed to find service %s\n", service));
2318 /****************************************************************************
2319 create an error packet from a cached error.
2320 ****************************************************************************/
2321 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2323 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2325 int32 eclass = wbmpx->wr_errclass;
2326 int32 err = wbmpx->wr_error;
2328 /* We can now delete the auxiliary struct */
2329 free((char *)wbmpx);
2330 Files[fnum].wbmpx_ptr = NULL;
2331 return error_packet(inbuf,outbuf,eclass,err,line);
2340 } unix_smb_errmap[] =
2342 {EPERM,ERRDOS,ERRnoaccess},
2343 {EACCES,ERRDOS,ERRnoaccess},
2344 {ENOENT,ERRDOS,ERRbadfile},
2345 {ENOTDIR,ERRDOS,ERRbadpath},
2346 {EIO,ERRHRD,ERRgeneral},
2347 {EBADF,ERRSRV,ERRsrverror},
2348 {EINVAL,ERRSRV,ERRsrverror},
2349 {EEXIST,ERRDOS,ERRfilexists},
2350 {ENFILE,ERRDOS,ERRnofids},
2351 {EMFILE,ERRDOS,ERRnofids},
2352 {ENOSPC,ERRHRD,ERRdiskfull},
2354 {EDQUOT,ERRHRD,ERRdiskfull},
2357 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2360 {EXDEV,ERRDOS,ERRdiffdevice},
2362 {EROFS,ERRHRD,ERRnowrite},
2366 /****************************************************************************
2367 create an error packet from errno
2368 ****************************************************************************/
2369 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2371 int eclass=def_class;
2375 if (unix_ERR_class != SMB_SUCCESS)
2377 eclass = unix_ERR_class;
2378 ecode = unix_ERR_code;
2379 unix_ERR_class = SMB_SUCCESS;
2384 while (unix_smb_errmap[i].smbclass != 0)
2386 if (unix_smb_errmap[i].unixerror == errno)
2388 eclass = unix_smb_errmap[i].smbclass;
2389 ecode = unix_smb_errmap[i].smbcode;
2396 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2400 /****************************************************************************
2401 create an error packet. Normally called using the ERROR() macro
2402 ****************************************************************************/
2403 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2405 int outsize = set_message(outbuf,0,0,True);
2406 int cmd = CVAL(inbuf,smb_com);
2407 int flgs2 = SVAL(outbuf,smb_flg2);
2409 if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2411 SIVAL(outbuf,smb_rcls,error_code);
2413 DEBUG( 3, ( "32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2414 line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf) ) );
2418 CVAL(outbuf,smb_rcls) = error_class;
2419 SSVAL(outbuf,smb_err,error_code);
2420 DEBUG( 3, ( "error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2422 (int)CVAL(inbuf,smb_com),
2423 smb_fn_name(CVAL(inbuf,smb_com)),
2430 DEBUG(3,("error string = %s\n",strerror(errno)));
2436 /****************************************************************************
2437 this is called when the client exits abruptly
2438 **************************************************************************/
2439 static int sig_pipe(void)
2441 struct cli_state *cli;
2442 BlockSignals(True,SIGPIPE);
2444 if ((cli = server_client()) && cli->initialised) {
2445 DEBUG(3,("lost connection to password server\n"));
2447 BlockSignals(False,SIGPIPE);
2451 exit_server("Got sigpipe\n");
2455 /****************************************************************************
2456 open the socket communication
2457 ****************************************************************************/
2458 static BOOL open_sockets(BOOL is_daemon,int port)
2464 int num_interfaces = iface_count();
2465 int fd_listenset[FD_SETSIZE];
2471 static int atexit_set;
2472 if(atexit_set == 0) {
2482 FD_ZERO(&listen_set);
2484 if(lp_interfaces() && lp_bind_interfaces_only())
2486 /* We have been given an interfaces line, and been
2487 told to only bind to those interfaces. Create a
2488 socket per interface and bind to only these.
2491 if(num_interfaces > FD_SETSIZE)
2493 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2494 max can be %d\n", num_interfaces, FD_SETSIZE));
2498 /* Now open a listen socket for each of the interfaces. */
2499 for(i = 0; i < num_interfaces; i++)
2501 struct in_addr *ifip = iface_n_ip(i);
2505 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2508 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2511 /* ready to listen */
2512 if (listen(s, 5) == -1)
2514 DEBUG(0,("listen: %s\n",strerror(errno)));
2518 FD_SET(s,&listen_set);
2523 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2526 /* open an incoming socket */
2527 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2531 /* ready to listen */
2532 if (listen(s, 5) == -1)
2534 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2539 fd_listenset[0] = s;
2540 FD_SET(s,&listen_set);
2543 /* now accept incoming connections - forking a new process
2544 for each incoming connection */
2545 DEBUG(2,("waiting for a connection\n"));
2551 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2553 num = sys_select(&lfds,NULL);
2555 if (num == -1 && errno == EINTR)
2558 /* Find the sockets that are read-ready - accept on these. */
2559 for( ; num > 0; num--)
2561 struct sockaddr addr;
2562 int in_addrlen = sizeof(addr);
2565 for(i = 0; i < num_interfaces; i++)
2567 if(FD_ISSET(fd_listenset[i],&lfds))
2569 s = fd_listenset[i];
2570 /* Clear this so we don't look at it again. */
2571 FD_CLR(fd_listenset[i],&lfds);
2576 Client = accept(s,&addr,&in_addrlen);
2578 if (Client == -1 && errno == EINTR)
2583 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2587 if (Client != -1 && fork()==0)
2589 /* Child code ... */
2591 CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2593 /* close the listening socket(s) */
2594 for(i = 0; i < num_interfaces; i++)
2595 close(fd_listenset[i]);
2597 /* close our standard file descriptors */
2601 set_socket_options(Client,"SO_KEEPALIVE");
2602 set_socket_options(Client,user_socket_options);
2604 /* Reset global variables in util.c so that
2605 client substitutions will be done correctly
2608 reset_globals_after_fork();
2611 close(Client); /* The parent doesn't need this socket */
2614 * Force parent to check log size after spawning child.
2615 * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
2616 * The parent smbd will log to logserver.smb.
2617 * It writes only two messages for each child
2618 * started/finished. But each child writes, say, 50 messages also in
2619 * logserver.smb, begining with the debug_count of the parent, before the
2620 * child opens its own log file logserver.client. In a worst case
2621 * scenario the size of logserver.smb would be checked after about
2622 * 50*50=2500 messages (ca. 100kb).
2624 force_check_log_size();
2628 } /* end if is_daemon */
2631 /* Started from inetd. fd 0 is the socket. */
2632 /* We will abort gracefully when the client or remote system
2634 CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2637 /* close our standard file descriptors */
2640 set_socket_options(Client,"SO_KEEPALIVE");
2641 set_socket_options(Client,user_socket_options);
2647 /****************************************************************************
2648 process an smb from the client - split out from the process() code so
2649 it can be used by the oplock break code.
2650 ****************************************************************************/
2652 static void process_smb(char *inbuf, char *outbuf)
2656 extern BOOL sslEnabled; /* don't use function for performance reasons */
2657 static int sslConnected = 0;
2658 #endif /* WITH_SSL */
2659 static int trans_num;
2660 int msg_type = CVAL(inbuf,0);
2661 int32 len = smb_len(inbuf);
2662 int nread = len + 4;
2664 if (trans_num == 0) {
2665 /* on the first packet, check the global hosts allow/ hosts
2666 deny parameters before doing any parsing of the packet
2667 passed to us by the client. This prevents attacks on our
2668 parsing code from hosts not in the hosts allow list */
2669 if (!check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1))) {
2670 /* send a negative session response "not listining on calling
2672 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2673 DEBUG( 1, ( "Connection denied from %s\n",
2674 client_addr(Client) ) );
2675 send_smb(Client,(char *)buf);
2676 exit_server("connection denied");
2680 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
2681 DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
2684 if(sslEnabled && !sslConnected){
2685 sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2686 if(sslConnected < 0){ /* an error occured */
2687 exit_server("SSL negotiation failed");
2688 }else if(sslConnected){
2693 #endif /* WITH_SSL */
2696 if(trans_num == 1 && VT_Check(inbuf))
2705 else if(msg_type == 0x85)
2706 return; /* Keepalive packet. */
2708 nread = construct_reply(inbuf,outbuf,nread,max_send);
2712 if (CVAL(outbuf,0) == 0)
2715 if (nread != smb_len(outbuf) + 4)
2717 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2718 nread, smb_len(outbuf)));
2721 send_smb(Client,outbuf);
2726 /****************************************************************************
2727 open the oplock IPC socket communication
2728 ****************************************************************************/
2729 static BOOL open_oplock_ipc(void)
2731 struct sockaddr_in sock_name;
2732 int len = sizeof(sock_name);
2734 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2736 /* Open a lookback UDP socket on a random port. */
2737 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2738 if (oplock_sock == -1)
2740 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2741 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2746 /* Find out the transient UDP port we have been allocated. */
2747 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2749 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2756 oplock_port = ntohs(sock_name.sin_port);
2758 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2759 getpid(), oplock_port));
2764 /****************************************************************************
2765 process an oplock break message.
2766 ****************************************************************************/
2767 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2773 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2774 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2776 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2778 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2779 msg_len, from_port));
2781 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2782 only valid request. */
2784 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2786 case OPLOCK_BREAK_CMD:
2787 /* Ensure that the msg length is correct. */
2788 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2790 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2791 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2795 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2796 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2797 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2798 struct timeval tval;
2799 struct sockaddr_in toaddr;
2801 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2802 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2804 DEBUG(5,("process_local_message: oplock break request from \
2805 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2808 * If we have no record of any currently open oplocks,
2809 * it's not an error, as a close command may have
2810 * just been issued on the file that was oplocked.
2811 * Just return success in this case.
2814 if(global_oplocks_open != 0)
2816 if(oplock_break(dev, inode, &tval) == False)
2818 DEBUG(0,("process_local_message: oplock break failed - \
2819 not returning udp message.\n"));
2825 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2826 oplocks. Returning success.\n"));
2829 /* Send the message back after OR'ing in the 'REPLY' bit. */
2830 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2832 bzero((char *)&toaddr,sizeof(toaddr));
2833 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2834 toaddr.sin_port = htons(from_port);
2835 toaddr.sin_family = AF_INET;
2837 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2838 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2840 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2841 remotepid, strerror(errno)));
2845 DEBUG(5,("process_local_message: oplock break reply sent to \
2846 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2847 from_port, dev, inode));
2852 * Keep this as a debug case - eventually we can remove it.
2855 DEBUG(0,("process_local_message: Received unsolicited break \
2856 reply - dumping info.\n"));
2858 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2860 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2861 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2866 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2867 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2868 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2870 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2871 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2877 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2878 (unsigned int)SVAL(msg_start,0)));
2884 /****************************************************************************
2885 Process an oplock break directly.
2886 ****************************************************************************/
2887 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2889 extern struct current_user current_user;
2892 char *outbuf = NULL;
2893 files_struct *fsp = NULL;
2896 BOOL shutdown_server = False;
2897 connection_struct *saved_conn;
2903 dbgtext( "oplock_break: called for dev = %x, inode = %x.\n", dev, inode );
2904 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
2907 /* We need to search the file open table for the
2908 entry containing this dev and inode, and ensure
2909 we have an oplock on it. */
2910 for( fnum = 0; fnum < MAX_FNUMS; fnum++)
2914 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2915 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
2916 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2925 /* The file could have been closed in the meantime - return success. */
2928 dbgtext( "oplock_break: cannot find open file with " );
2929 dbgtext( "dev = %x, inode = %x (fnum = %d) ", dev, inode, fnum );
2930 dbgtext( "allowing break to succeed.\n" );
2935 /* Ensure we have an oplock on the file */
2937 /* There is a potential race condition in that an oplock could
2938 have been broken due to another udp request, and yet there are
2939 still oplock break messages being sent in the udp message
2940 queue for this file. So return true if we don't have an oplock,
2941 as we may have just freed it.
2944 if(!fsp->granted_oplock)
2948 dbgtext( "oplock_break: file %s (fnum = %d, ", fsp->fsp_name, fnum );
2949 dbgtext( "dev = %x, inode = %x) has no oplock.\n", dev, inode );
2950 dbgtext( "Allowing break to succeed regardless.\n" );
2955 /* mark the oplock break as sent - we don't want to send twice! */
2956 if (fsp->sent_oplock_break)
2960 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
2961 dbgtext( "file %s (fnum = %d, ", fsp->fsp_name, fnum );
2962 dbgtext( "dev = %x, inode = %x)\n", dev, inode );
2965 /* We have to fail the open here as we cannot send another oplock break on
2966 this file whilst we are awaiting a response from the client - neither
2967 can we allow another open to succeed while we are waiting for the
2973 /* Now comes the horrid part. We must send an oplock break to the client,
2974 and then process incoming messages until we get a close or oplock release.
2975 At this point we know we need a new inbuf/outbuf buffer pair.
2976 We cannot use these staticaly as we may recurse into here due to
2977 messages crossing on the wire.
2980 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2982 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2986 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2988 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2994 /* Prepare the SMBlockingX message. */
2995 bzero(outbuf,smb_size);
2996 set_message(outbuf,8,0,True);
2998 SCVAL(outbuf,smb_com,SMBlockingX);
2999 SSVAL(outbuf,smb_tid,fsp->conn->cnum);
3000 SSVAL(outbuf,smb_pid,0xFFFF);
3001 SSVAL(outbuf,smb_uid,0);
3002 SSVAL(outbuf,smb_mid,0xFFFF);
3003 SCVAL(outbuf,smb_vwv0,0xFF);
3004 SSVAL(outbuf,smb_vwv2,fnum);
3005 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
3006 /* Change this when we have level II oplocks. */
3007 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
3009 send_smb(Client, outbuf);
3011 /* Remember we just sent an oplock break on this file. */
3012 fsp->sent_oplock_break = True;
3014 /* We need this in case a readraw crosses on the wire. */
3015 global_oplock_break = True;
3017 /* Process incoming messages. */
3019 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
3020 seconds we should just die.... */
3022 start_time = time(NULL);
3025 * Save the information we need to re-become the
3026 * user, then unbecome the user whilst we're doing this.
3028 saved_conn = fsp->conn;
3029 saved_vuid = current_user.vuid;
3033 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
3035 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
3038 * Die if we got an error.
3041 if (smb_read_error == READ_EOF)
3042 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
3044 if (smb_read_error == READ_ERROR)
3045 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
3047 if (smb_read_error == READ_TIMEOUT)
3048 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
3049 OPLOCK_BREAK_TIMEOUT ) );
3051 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
3052 DEBUGADD( 0, ( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode));
3053 shutdown_server = True;
3058 * There are certain SMB requests that we shouldn't allow
3059 * to recurse. opens, renames and deletes are the obvious
3060 * ones. This is handled in the switch_message() function.
3061 * If global_oplock_break is set they will push the packet onto
3062 * the pending smb queue and return -1 (no reply).
3066 process_smb(inbuf, outbuf);
3069 * Die if we go over the time limit.
3072 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3076 dbgtext( "oplock_break: no break received from client " );
3077 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
3078 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
3079 dbgtext( "(fnum = %d, dev = %x, inode = %x).\n", fnum, dev, inode );
3081 shutdown_server = True;
3087 * Go back to being the user who requested the oplock
3090 if(!become_user(saved_conn, saved_vuid))
3092 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
3093 DEBUGADD( 0, ( "Shutting down server\n" ) );
3096 exit_server("unable to re-become user");
3098 /* Including the directory. */
3101 /* Free the buffers we've been using to recurse. */
3105 /* We need this in case a readraw crossed on the wire. */
3106 if(global_oplock_break)
3107 global_oplock_break = False;
3110 * If the client did not respond we must die.
3115 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
3116 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
3119 exit_server("oplock break failure");
3124 /* The lockingX reply will have removed the oplock flag
3125 from the sharemode. */
3127 fsp->granted_oplock = False;
3128 fsp->sent_oplock_break = False;
3129 global_oplocks_open--;
3132 /* Santity check - remove this later. JRA */
3133 if(global_oplocks_open < 0)
3135 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3136 global_oplocks_open));
3137 exit_server("oplock_break: global_oplocks_open < 0");
3142 dbgtext( "oplock_break: returning success for " );
3143 dbgtext( "fnum = %d, dev = %x, inode = %x.\n", fnum, dev, inode );
3144 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
3150 /****************************************************************************
3151 Send an oplock break message to another smbd process. If the oplock is held
3152 by the local smbd then call the oplock break function directly.
3153 ****************************************************************************/
3155 BOOL request_oplock_break(share_mode_entry *share_entry,
3156 uint32 dev, uint32 inode)
3158 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3159 struct sockaddr_in addr_out;
3164 if(pid == share_entry->pid)
3166 /* We are breaking our own oplock, make sure it's us. */
3167 if(share_entry->op_port != oplock_port)
3169 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3170 should be %d\n", pid, share_entry->op_port, oplock_port));
3174 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3176 /* Call oplock break direct. */
3177 return oplock_break(dev, inode, &share_entry->time);
3180 /* We need to send a OPLOCK_BREAK_CMD message to the
3181 port in the share mode entry. */
3183 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3184 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3185 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3186 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3187 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3188 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3190 /* set the address and port */
3191 bzero((char *)&addr_out,sizeof(addr_out));
3192 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3193 addr_out.sin_port = htons( share_entry->op_port );
3194 addr_out.sin_family = AF_INET;
3198 dbgtext( "request_oplock_break: sending a oplock break message to " );
3199 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
3200 dbgtext( "for dev = %x, inode = %x\n", dev, inode );
3203 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3204 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3208 dbgtext( "request_oplock_break: failed when sending a oplock " );
3209 dbgtext( "break message to pid %d ", share_entry->pid );
3210 dbgtext( "on port %d ", share_entry->op_port );
3211 dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
3212 dbgtext( "Error was %s\n", strerror(errno) );
3218 * Now we must await the oplock broken message coming back
3219 * from the target smbd process. Timeout if it fails to
3220 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3221 * While we get messages that aren't ours, loop.
3224 start_time = time(NULL);
3225 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3227 while(time_left >= 0)
3229 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3230 int32 reply_msg_len;
3231 uint16 reply_from_port;
3232 char *reply_msg_start;
3234 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3235 time_left ? time_left * 1000 : 1) == False)
3237 if(smb_read_error == READ_TIMEOUT)
3241 dbgtext( "request_oplock_break: no response received to oplock " );
3242 dbgtext( "break request to pid %d ", share_entry->pid );
3243 dbgtext( "on port %d ", share_entry->op_port );
3244 dbgtext( "for dev = %x, inode = %x\n", dev, inode );
3247 * This is a hack to make handling of failing clients more robust.
3248 * If a oplock break response message is not received in the timeout
3249 * period we may assume that the smbd servicing that client holding
3250 * the oplock has died and the client changes were lost anyway, so
3251 * we should continue to try and open the file.
3258 dbgtext( "request_oplock_break: error in response received " );
3259 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
3260 dbgtext( "on port %d ", share_entry->op_port );
3261 dbgtext( "for dev = %x, inode = %x.\n", dev, inode );
3262 dbgtext( "Error was (%s).\n", strerror(errno) );
3267 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3268 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3270 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3272 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3275 DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
3276 DEBUGADD( 0, ( " Ignoring.\n" ) );
3281 * Test to see if this is the reply we are awaiting.
3284 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3285 (reply_from_port == share_entry->op_port) &&
3286 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3287 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3288 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3291 * This is the reply we've been waiting for.
3298 * This is another message - probably a break request.
3299 * Process it to prevent potential deadlock.
3300 * Note that the code in switch_message() prevents
3301 * us from recursing into here as any SMB requests
3302 * we might process that would cause another oplock
3303 * break request to be made will be queued.
3307 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3310 time_left -= (time(NULL) - start_time);
3313 DEBUG(3,("request_oplock_break: broke oplock.\n"));
3318 /****************************************************************************
3319 Get the next SMB packet, doing the local message processing automatically.
3320 ****************************************************************************/
3322 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3324 BOOL got_smb = False;
3329 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3334 /* Deal with oplock break requests from other smbd's. */
3335 process_local_message(oplock_sock, inbuf, bufsize);
3339 if(ret && (CVAL(inbuf,0) == 0x85))
3341 /* Keepalive packet. */
3346 while(ret && !got_smb);
3351 /****************************************************************************
3352 check if a snum is in use
3353 ****************************************************************************/
3354 BOOL snum_used(int snum)
3357 for (i=0;i<MAX_CONNECTIONS;i++) {
3358 if (Connections[i].open && (Connections[i].service == snum)) {
3365 /****************************************************************************
3366 reload the services file
3367 **************************************************************************/
3368 BOOL reload_services(BOOL test)
3374 pstrcpy(fname,lp_configfile());
3375 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
3376 pstrcpy(servicesf,fname);
3383 if (test && !lp_file_list_changed())
3386 lp_killunused(snum_used);
3388 ret = lp_load(servicesf,False,False,True);
3392 /* perhaps the config filename is now set */
3394 reload_services(True);
3403 set_socket_options(Client,"SO_KEEPALIVE");
3404 set_socket_options(Client,user_socket_options);
3408 reset_mangled_cache();
3410 /* this forces service parameters to be flushed */
3411 become_service(NULL,True);
3418 /****************************************************************************
3419 this prevents zombie child processes
3420 ****************************************************************************/
3421 static BOOL reload_after_sighup = False;
3423 static int sig_hup(void)
3425 BlockSignals(True,SIGHUP);
3426 DEBUG(0,("Got SIGHUP\n"));
3429 * Fix from <branko.cibej@hermes.si> here.
3430 * We used to reload in the signal handler - this
3434 reload_after_sighup = True;
3435 BlockSignals(False,SIGHUP);
3439 /****************************************************************************
3440 find first available connection slot, starting from a random position.
3441 The randomisation stops problems with the server dieing and clients
3442 thinking the server is still available.
3443 ****************************************************************************/
3444 static connection_struct *find_free_connection(int hash)
3448 hash = (hash % (MAX_CONNECTIONS-2))+1;
3452 for (i=hash+1;i!=hash;) {
3453 if (!Connections[i].open && Connections[i].used == used) {
3454 DEBUG(3,("found free connection number %d\n",i));
3455 memset(&Connections[i], 0, sizeof(&Connections[i]));
3456 Connections[i].cnum = i;
3457 return &Connections[i];
3460 if (i == MAX_CONNECTIONS) {
3470 DEBUG(1,("ERROR! Out of connection structures\n"));
3476 /****************************************************************************
3477 make a connection to a service
3478 ****************************************************************************/
3479 connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode)
3482 struct passwd *pass = NULL;
3486 connection_struct *conn;
3490 snum = find_service(service);
3493 if (strequal(service,"IPC$")) {
3494 DEBUG(3,("refusing IPC connection\n"));
3499 DEBUG(0,("%s (%s) couldn't find service %s\n",
3500 remote_machine, client_addr(Client), service));
3501 *ecode = ERRinvnetname;
3505 if (strequal(service,HOMES_NAME)) {
3506 if (*user && Get_Pwnam(user,True))
3507 return(make_connection(user,user,password,
3508 pwlen,dev,vuid,ecode));
3510 if(lp_security() != SEC_SHARE) {
3511 if (validated_username(vuid)) {
3512 pstrcpy(user,validated_username(vuid));
3513 return(make_connection(user,user,password,pwlen,dev,vuid,ecode));
3516 /* Security = share. Try with sesssetup_user
3517 * as the username. */
3518 if(*sesssetup_user) {
3519 pstrcpy(user,sesssetup_user);
3520 return(make_connection(user,user,password,pwlen,dev,vuid,ecode));
3525 if (!lp_snum_ok(snum) ||
3526 !check_access(Client,
3527 lp_hostsallow(snum), lp_hostsdeny(snum))) {
3532 /* you can only connect to the IPC$ service as an ipc device */
3533 if (strequal(service,"IPC$"))
3536 if (*dev == '?' || !*dev) {
3537 if (lp_print_ok(snum)) {
3538 pstrcpy(dev,"LPT1:");
3544 /* if the request is as a printer and you can't print then refuse */
3546 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3547 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3548 *ecode = ERRinvdevice;
3552 /* lowercase the user name */
3555 /* add it as a possible user name */
3556 add_session_user(service);
3558 /* shall we let them in? */
3559 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) {
3560 DEBUG( 2, ( "Invalid username/password for %s\n", service ) );
3565 conn = find_free_connection(str_checksum(service) + str_checksum(user));
3567 DEBUG(0,("Couldn't find free connection.\n"));
3568 *ecode = ERRnoresource;
3572 /* find out some info about the user */
3573 pass = Get_Pwnam(user,True);
3576 DEBUG(0,( "Couldn't find account %s\n",user));
3581 conn->read_only = lp_readonly(snum);
3585 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3586 string_sub(list,"%S",service);
3588 if (user_in_list(user,list))
3589 conn->read_only = True;
3591 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3592 string_sub(list,"%S",service);
3594 if (user_in_list(user,list))
3595 conn->read_only = False;
3598 /* admin user check */
3600 /* JRA - original code denied admin user if the share was
3601 marked read_only. Changed as I don't think this is needed,
3602 but old code left in case there is a problem here.
3604 if (user_in_list(user,lp_admin_users(snum))
3609 conn->admin_user = True;
3610 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3612 conn->admin_user = False;
3615 conn->force_user = force;
3617 conn->uid = pass->pw_uid;
3618 conn->gid = pass->pw_gid;
3619 conn->num_files_open = 0;
3620 conn->lastused = time(NULL);
3621 conn->service = snum;
3623 conn->printer = (strncmp(dev,"LPT",3) == 0);
3624 conn->ipc = (strncmp(dev,"IPC",3) == 0);
3625 conn->dirptr = NULL;
3626 conn->veto_list = NULL;
3627 conn->hide_list = NULL;
3628 conn->veto_oplock_list = NULL;
3629 string_set(&conn->dirpath,"");
3630 string_set(&conn->user,user);
3632 #ifdef HAVE_GETGRNAM
3633 if (*lp_force_group(snum)) {
3637 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3638 /* default service may be a group name */
3639 string_sub(gname,"%S",service);
3640 gptr = (struct group *)getgrnam(gname);
3643 conn->gid = gptr->gr_gid;
3644 DEBUG(3,("Forced group %s\n",gname));
3646 DEBUG(1,("Couldn't find group %s\n",gname));
3651 if (*lp_force_user(snum)) {
3652 struct passwd *pass2;
3654 fstrcpy(fuser,lp_force_user(snum));
3655 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3657 conn->uid = pass2->pw_uid;
3658 string_set(&conn->user,fuser);
3659 fstrcpy(user,fuser);
3660 conn->force_user = True;
3661 DEBUG(3,("Forced user %s\n",fuser));
3663 DEBUG(1,("Couldn't find user %s\n",fuser));
3669 pstrcpy(s,lp_pathname(snum));
3670 standard_sub(conn,s);
3671 string_set(&conn->connectpath,s);
3672 DEBUG(3,("Connect path is %s\n",s));
3675 /* groups stuff added by ih */
3677 conn->groups = NULL;
3679 if (!IS_IPC(conn)) {
3680 /* Find all the groups this uid is in and
3681 store them. Used by become_user() */
3682 setup_groups(conn->user,conn->uid,conn->gid,
3683 &conn->ngroups,&conn->groups);
3685 /* check number of connections */
3686 if (!claim_connection(conn,
3687 lp_servicename(SNUM(conn)),
3688 lp_max_connections(SNUM(conn)),
3690 DEBUG(1,("too many connections - rejected\n"));
3691 *ecode = ERRnoresource;
3695 if (lp_status(SNUM(conn)))
3696 claim_connection(conn,"STATUS.",
3702 /* execute any "root preexec = " line */
3703 if (*lp_rootpreexec(SNUM(conn))) {
3705 pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
3706 standard_sub(conn,cmd);
3707 DEBUG(5,("cmd=%s\n",cmd));
3708 smbrun(cmd,NULL,False);
3711 if (!become_user(conn, conn->vuid)) {
3712 DEBUG(0,("Can't become connected user!\n"));
3714 if (!IS_IPC(conn)) {
3715 yield_connection(conn,
3716 lp_servicename(SNUM(conn)),
3717 lp_max_connections(SNUM(conn)));
3718 if (lp_status(SNUM(conn))) {
3719 yield_connection(conn,"STATUS.",MAXSTATUS);
3726 if (ChDir(conn->connectpath) != 0) {
3727 DEBUG(0,("Can't change directory to %s (%s)\n",
3728 conn->connectpath,strerror(errno)));
3731 if (!IS_IPC(conn)) {
3732 yield_connection(conn,
3733 lp_servicename(SNUM(conn)),
3734 lp_max_connections(SNUM(conn)));
3735 if (lp_status(SNUM(conn)))
3736 yield_connection(conn,"STATUS.",MAXSTATUS);
3738 *ecode = ERRinvnetname;
3742 string_set(&conn->origpath,conn->connectpath);
3744 #if SOFTLINK_OPTIMISATION
3745 /* resolve any soft links early */
3748 pstrcpy(s,conn->connectpath);
3750 string_set(&conn->connectpath,s);
3751 ChDir(conn->connectpath);
3755 num_connections_open++;
3756 add_session_user(user);
3758 /* execute any "preexec = " line */
3759 if (*lp_preexec(SNUM(conn))) {
3761 pstrcpy(cmd,lp_preexec(SNUM(conn)));
3762 standard_sub(conn,cmd);
3763 smbrun(cmd,NULL,False);
3766 /* we've finished with the sensitive stuff */
3769 /* Add veto/hide lists */
3770 if (!IS_IPC(conn) && !IS_PRINT(conn)) {
3771 set_namearray( &conn->veto_list, lp_veto_files(SNUM(conn)));
3772 set_namearray( &conn->hide_list, lp_hide_files(SNUM(conn)));
3773 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn)));
3776 if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
3779 dbgtext( "%s (%s) ", remote_machine, client_addr(Client) );
3780 dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
3781 dbgtext( "as user %s ", user );
3782 dbgtext( "(uid=%d, gid=%d) ", conn->uid, conn->gid );
3783 dbgtext( "(pid %d)\n", (int)getpid() );
3789 /****************************************************************************
3790 Attempt to break an oplock on a file (if oplocked).
3791 Returns True if the file was closed as a result of
3792 the oplock break, False otherwise.
3793 Used as a last ditch attempt to free a space in the
3794 file table when we have run out.
3795 ****************************************************************************/
3797 static BOOL attempt_close_oplocked_file(files_struct *fsp)
3800 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
3802 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
3804 /* Try and break the oplock. */
3805 file_fd_struct *fd_ptr = fsp->fd_ptr;
3806 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
3807 if(!fsp->open) /* Did the oplock break close the file ? */
3815 /****************************************************************************
3816 find first available file slot
3817 ****************************************************************************/
3818 int find_free_file(void )
3821 static int first_file;
3823 /* we want to give out file handles differently on each new
3824 connection because of a common bug in MS clients where they try to
3825 reuse a file descriptor from an earlier smb connection. This code
3826 increases the chance that the errant client will get an error rather
3827 than causing corruption */
3828 if (first_file == 0) {
3829 first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
3830 if (first_file == 0) first_file = 1;
3833 if (first_file >= MAX_FNUMS)
3836 for (i=first_file;i<MAX_FNUMS;i++)
3837 if (!Files[i].open && !Files[i].reserved) {
3838 memset(&Files[i], 0, sizeof(Files[i]));
3840 Files[i].reserved = True;
3844 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3845 for (i=1;i<first_file;i++)
3846 if (!Files[i].open && !Files[i].reserved) {
3847 memset(&Files[i], 0, sizeof(Files[i]));
3849 Files[i].reserved = True;
3854 * Before we give up, go through the open files
3855 * and see if there are any files opened with a
3856 * batch oplock. If so break the oplock and then
3857 * re-use that entry (if it becomes closed).
3858 * This may help as NT/95 clients tend to keep
3859 * files batch oplocked for quite a long time
3860 * after they have finished with them.
3862 for (i=first_file;i<MAX_FNUMS;i++) {
3863 if(attempt_close_oplocked_file( &Files[i])) {
3864 memset(&Files[i], 0, sizeof(Files[i]));
3866 Files[i].reserved = True;
3871 for (i=1;i<MAX_FNUMS;i++) {
3872 if(attempt_close_oplocked_file( &Files[i])) {
3873 memset(&Files[i], 0, sizeof(Files[i]));
3875 Files[i].reserved = True;
3880 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3885 /****************************************************************************
3886 reply for the core protocol
3887 ****************************************************************************/
3888 int reply_corep(char *outbuf)
3890 int outsize = set_message(outbuf,1,0,True);
3892 Protocol = PROTOCOL_CORE;
3898 /****************************************************************************
3899 reply for the coreplus protocol
3900 ****************************************************************************/
3901 int reply_coreplus(char *outbuf)
3903 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3904 int outsize = set_message(outbuf,13,0,True);
3905 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3906 readbraw and writebraw (possibly) */
3907 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3908 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3910 Protocol = PROTOCOL_COREPLUS;
3916 /****************************************************************************
3917 reply for the lanman 1.0 protocol
3918 ****************************************************************************/
3919 int reply_lanman1(char *outbuf)
3921 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3923 BOOL doencrypt = SMBENCRYPT();
3924 time_t t = time(NULL);
3926 if (lp_security()>=SEC_USER) secword |= 1;
3927 if (doencrypt) secword |= 2;
3929 set_message(outbuf,13,doencrypt?8:0,True);
3930 SSVAL(outbuf,smb_vwv1,secword);
3931 /* Create a token value and add it to the outgoing packet. */
3933 generate_next_challenge(smb_buf(outbuf));
3935 Protocol = PROTOCOL_LANMAN1;
3937 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3938 SSVAL(outbuf,smb_vwv2,max_recv);
3939 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3940 SSVAL(outbuf,smb_vwv4,1);
3941 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3942 readbraw writebraw (possibly) */
3943 SIVAL(outbuf,smb_vwv6,getpid());
3944 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3946 put_dos_date(outbuf,smb_vwv8,t);
3948 return (smb_len(outbuf)+4);
3952 /****************************************************************************
3953 reply for the lanman 2.0 protocol
3954 ****************************************************************************/
3955 int reply_lanman2(char *outbuf)
3957 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3959 BOOL doencrypt = SMBENCRYPT();
3960 time_t t = time(NULL);
3961 struct cli_state *cli = NULL;
3965 if (lp_security() == SEC_SERVER) {
3966 cli = server_cryptkey();
3970 DEBUG(3,("using password server validation\n"));
3971 doencrypt = ((cli->sec_mode & 2) != 0);
3974 if (lp_security()>=SEC_USER) secword |= 1;
3975 if (doencrypt) secword |= 2;
3980 generate_next_challenge(cryptkey);
3982 memcpy(cryptkey, cli->cryptkey, 8);
3983 set_challenge(cli->cryptkey);
3987 set_message(outbuf,13,crypt_len,True);
3988 SSVAL(outbuf,smb_vwv1,secword);
3989 SIVAL(outbuf,smb_vwv6,getpid());
3991 memcpy(smb_buf(outbuf), cryptkey, 8);
3993 Protocol = PROTOCOL_LANMAN2;
3995 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3996 SSVAL(outbuf,smb_vwv2,max_recv);
3997 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3998 SSVAL(outbuf,smb_vwv4,1);
3999 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
4000 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4001 put_dos_date(outbuf,smb_vwv8,t);
4003 return (smb_len(outbuf)+4);
4007 /****************************************************************************
4008 reply for the nt protocol
4009 ****************************************************************************/
4010 int reply_nt1(char *outbuf)
4012 /* dual names + lock_and_read + nt SMBs + remote API calls */
4013 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
4016 other valid capabilities which we may support at some time...
4018 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
4022 BOOL doencrypt = SMBENCRYPT();
4023 time_t t = time(NULL);
4025 struct cli_state *cli = NULL;
4029 if (lp_security() == SEC_SERVER) {
4030 cli = server_cryptkey();
4034 DEBUG(3,("using password server validation\n"));
4035 doencrypt = ((cli->sec_mode & 2) != 0);
4041 generate_next_challenge(cryptkey);
4043 memcpy(cryptkey, cli->cryptkey, 8);
4044 set_challenge(cli->cryptkey);
4048 if (lp_readraw() && lp_writeraw()) {
4049 capabilities |= CAP_RAW_MODE;
4052 if (lp_security() >= SEC_USER) secword |= 1;
4053 if (doencrypt) secword |= 2;
4055 /* decide where (if) to put the encryption challenge, and
4056 follow it with the OEM'd domain name
4058 data_len = crypt_len + strlen(global_myworkgroup) + 1;
4060 set_message(outbuf,17,data_len,True);
4061 pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
4063 CVAL(outbuf,smb_vwv1) = secword;
4064 SSVALS(outbuf,smb_vwv16+1,crypt_len);
4066 memcpy(smb_buf(outbuf), cryptkey, 8);
4068 Protocol = PROTOCOL_NT1;
4070 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4071 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4072 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4073 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4074 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4075 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4076 put_long_date(outbuf+smb_vwv11+1,t);
4077 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4078 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4080 return (smb_len(outbuf)+4);
4083 /* these are the protocol lists used for auto architecture detection:
4086 protocol [PC NETWORK PROGRAM 1.0]
4087 protocol [XENIX CORE]
4088 protocol [MICROSOFT NETWORKS 1.03]
4089 protocol [LANMAN1.0]
4090 protocol [Windows for Workgroups 3.1a]
4091 protocol [LM1.2X002]
4092 protocol [LANMAN2.1]
4093 protocol [NT LM 0.12]
4096 protocol [PC NETWORK PROGRAM 1.0]
4097 protocol [XENIX CORE]
4098 protocol [MICROSOFT NETWORKS 1.03]
4099 protocol [LANMAN1.0]
4100 protocol [Windows for Workgroups 3.1a]
4101 protocol [LM1.2X002]
4102 protocol [LANMAN2.1]
4103 protocol [NT LM 0.12]
4106 protocol [PC NETWORK PROGRAM 1.0]
4107 protocol [XENIX CORE]
4108 protocol [LANMAN1.0]
4109 protocol [LM1.2X002]
4110 protocol [LANMAN2.1]
4114 * Modified to recognize the architecture of the remote machine better.
4116 * This appears to be the matrix of which protocol is used by which
4118 Protocol WfWg Win95 WinNT OS/2
4119 PC NETWORK PROGRAM 1.0 1 1 1 1
4121 MICROSOFT NETWORKS 3.0 2 2
4123 MICROSOFT NETWORKS 1.03 3
4126 Windows for Workgroups 3.1a 5 5 5
4131 * tim@fsg.com 09/29/95
4134 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4135 #define ARCH_WIN95 0x2
4136 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4137 #define ARCH_WINNT 0x8
4138 #define ARCH_SAMBA 0x10
4140 #define ARCH_ALL 0x1F
4142 /* List of supported protocols, most desired first */
4146 int (*proto_reply_fn)(char *);
4148 } supported_protocols[] = {
4149 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4150 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4151 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4152 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4153 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4154 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4155 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4156 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4157 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4162 /****************************************************************************
4164 ****************************************************************************/
4165 static int reply_negprot(connection_struct *conn,
4166 char *inbuf,char *outbuf, int dum_size,
4169 int outsize = set_message(outbuf,1,0,True);
4174 int bcc = SVAL(smb_buf(inbuf),-2);
4175 int arch = ARCH_ALL;
4177 p = smb_buf(inbuf)+1;
4178 while (p < (smb_buf(inbuf) + bcc))
4181 DEBUG(3,("Requested protocol [%s]\n",p));
4182 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4183 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4184 else if (strcsequal(p,"DOS LM1.2X002"))
4185 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4186 else if (strcsequal(p,"DOS LANMAN2.1"))
4187 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4188 else if (strcsequal(p,"NT LM 0.12"))
4189 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4190 else if (strcsequal(p,"LANMAN2.1"))
4191 arch &= ( ARCH_WINNT | ARCH_OS2 );
4192 else if (strcsequal(p,"LM1.2X002"))
4193 arch &= ( ARCH_WINNT | ARCH_OS2 );
4194 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4196 else if (strcsequal(p,"XENIX CORE"))
4197 arch &= ( ARCH_WINNT | ARCH_OS2 );
4198 else if (strcsequal(p,"Samba")) {
4208 set_remote_arch(RA_SAMBA);
4211 set_remote_arch(RA_WFWG);
4214 set_remote_arch(RA_WIN95);
4217 set_remote_arch(RA_WINNT);
4220 set_remote_arch(RA_OS2);
4223 set_remote_arch(RA_UNKNOWN);
4227 /* possibly reload - change of architecture */
4228 reload_services(True);
4230 /* a special case to stop password server loops */
4231 if (Index == 1 && strequal(remote_machine,myhostname) &&
4232 (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4233 exit_server("Password server loop!");
4235 /* Check for protocols, most desirable first */
4236 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4238 p = smb_buf(inbuf)+1;
4240 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4241 while (p < (smb_buf(inbuf) + bcc))
4243 if (strequal(p,supported_protocols[protocol].proto_name))
4252 SSVAL(outbuf,smb_vwv0,choice);
4254 extern fstring remote_proto;
4255 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4256 reload_services(True);
4257 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4258 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4261 DEBUG(0,("No protocol supported !\n"));
4263 SSVAL(outbuf,smb_vwv0,choice);
4265 DEBUG( 5, ( "negprot index=%d\n", choice ) );
4271 /****************************************************************************
4272 close all open files for a connection
4273 ****************************************************************************/
4274 static void close_open_files(connection_struct *conn)
4277 for (i=0;i<MAX_FNUMS;i++)
4278 if (Files[i].conn == conn && Files[i].open) {
4279 if(Files[i].is_directory)
4282 close_file(i,False);
4288 /****************************************************************************
4290 ****************************************************************************/
4291 void close_cnum(connection_struct *conn, uint16 vuid)
4294 DirCacheFlush(SNUM(conn));
4299 DEBUG(0,("cnum not open\n"));
4303 DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
4304 remote_machine,client_addr(Client),
4305 lp_servicename(SNUM(conn))));
4307 yield_connection(conn,
4308 lp_servicename(SNUM(conn)),
4309 lp_max_connections(SNUM(conn)));
4311 if (lp_status(SNUM(conn)))
4312 yield_connection(conn,"STATUS.",MAXSTATUS);
4314 close_open_files(conn);
4315 dptr_closecnum(conn);
4317 /* execute any "postexec = " line */
4318 if (*lp_postexec(SNUM(conn)) &&
4319 become_user(conn, vuid)) {
4321 pstrcpy(cmd,lp_postexec(SNUM(conn)));
4322 standard_sub(conn,cmd);
4323 smbrun(cmd,NULL,False);
4328 /* execute any "root postexec = " line */
4329 if (*lp_rootpostexec(SNUM(conn))) {
4331 pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
4332 standard_sub(conn,cmd);
4333 smbrun(cmd,NULL,False);
4337 num_connections_open--;
4338 if (conn->ngroups && conn->groups) {
4340 conn->groups = NULL;
4344 free_namearray(conn->veto_list);
4345 free_namearray(conn->hide_list);
4346 free_namearray(conn->veto_oplock_list);
4348 string_set(&conn->user,"");
4349 string_set(&conn->dirpath,"");
4350 string_set(&conn->connectpath,"");
4356 /*******************************************************************
4357 prepare to dump a core file - carefully!
4358 ********************************************************************/
4359 static BOOL dump_core(void)
4363 pstrcpy(dname,debugf);
4364 if ((p=strrchr(dname,'/'))) *p=0;
4365 pstrcat(dname,"/corefiles");
4367 sys_chown(dname,getuid(),getgid());
4369 if (chdir(dname)) return(False);
4372 #ifdef HAVE_GETRLIMIT
4376 getrlimit(RLIMIT_CORE, &rlp);
4377 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4378 setrlimit(RLIMIT_CORE, &rlp);
4379 getrlimit(RLIMIT_CORE, &rlp);
4380 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4386 DEBUG(0,("Dumping core in %s\n",dname));
4392 /****************************************************************************
4394 ****************************************************************************/
4395 void exit_server(char *reason)
4397 static int firsttime=1;
4400 if (!firsttime) exit(0);
4404 DEBUG(2,("Closing connections\n"));
4405 for (i=0;i<MAX_CONNECTIONS;i++)
4406 if (Connections[i].open)
4407 close_cnum(&Connections[i],(uint16)-1);
4409 if (dcelogin_atmost_once) {
4414 int oldlevel = DEBUGLEVEL;
4416 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4418 show_msg(last_inbuf);
4419 DEBUGLEVEL = oldlevel;
4420 DEBUG(0,("===============================================================\n"));
4422 if (dump_core()) return;
4428 DEBUG( 3, ( "Server exit (%s)\n", (reason ? reason : "") ) );
4433 These flags determine some of the permissions required to do an operation
4435 Note that I don't set NEED_WRITE on some write operations because they
4436 are used by some brain-dead clients when printing, and I don't want to
4437 force write permissions on print services.
4439 #define AS_USER (1<<0)
4440 #define NEED_WRITE (1<<1)
4441 #define TIME_INIT (1<<2)
4442 #define CAN_IPC (1<<3)
4443 #define AS_GUEST (1<<5)
4444 #define QUEUE_IN_OPLOCK (1<<6)
4447 define a list of possible SMB messages and their corresponding
4448 functions. Any message that has a NULL function is unimplemented -
4449 please feel free to contribute implementations!
4451 struct smb_message_struct
4455 int (*fn)(connection_struct *conn, char *, char *, int, int);
4465 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4466 {SMBtcon,"SMBtcon",reply_tcon,0},
4467 {SMBtdis,"SMBtdis",reply_tdis,0},
4468 {SMBexit,"SMBexit",reply_exit,0},
4469 {SMBioctl,"SMBioctl",reply_ioctl,0},
4470 {SMBecho,"SMBecho",reply_echo,0},
4471 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4472 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4473 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4474 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4475 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4476 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4477 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4478 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4480 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4481 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4482 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4484 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4485 {SMBread,"SMBread",reply_read,AS_USER},
4486 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4487 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4488 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4489 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4490 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4491 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4493 /* this is a Pathworks specific call, allowing the
4494 changing of the root path */
4495 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4497 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4498 {SMBflush,"SMBflush",reply_flush,AS_USER},
4499 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4500 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4501 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4502 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER},
4503 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4504 {SMBlock,"SMBlock",reply_lock,AS_USER},
4505 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4507 /* CORE+ PROTOCOL FOLLOWS */
4509 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4510 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4511 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4512 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4513 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4515 /* LANMAN1.0 PROTOCOL FOLLOWS */
4517 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4518 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4519 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4520 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4521 {SMBwritec,"SMBwritec",NULL,AS_USER},
4522 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4523 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4524 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4525 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4526 {SMBioctls,"SMBioctls",NULL,AS_USER},
4527 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4528 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4530 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4531 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4532 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4533 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4535 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4536 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4537 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4539 /* LANMAN2.0 PROTOCOL FOLLOWS */
4540 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4541 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4542 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4543 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4545 /* NT PROTOCOL FOLLOWS */
4546 {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4547 {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
4548 {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
4549 {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
4551 /* messaging routines */
4552 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4553 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4554 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4555 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4557 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4559 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4560 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4561 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4562 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4565 /****************************************************************************
4566 return a string containing the function name of a SMB command
4567 ****************************************************************************/
4568 char *smb_fn_name(int type)
4570 static char *unknown_name = "SMBunknown";
4571 static int num_smb_messages =
4572 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4575 for (match=0;match<num_smb_messages;match++)
4576 if (smb_messages[match].code == type)
4579 if (match == num_smb_messages)
4580 return(unknown_name);
4582 return(smb_messages[match].name);
4586 /****************************************************************************
4587 do a switch on the message type, and return the response size
4588 ****************************************************************************/
4589 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4593 static int num_smb_messages =
4594 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4599 struct timeval msg_start_time;
4600 struct timeval msg_end_time;
4601 static unsigned long total_time = 0;
4603 GetTimeOfDay(&msg_start_time);
4610 last_message = type;
4612 /* make sure this is an SMB packet */
4613 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4615 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4619 for (match=0;match<num_smb_messages;match++)
4620 if (smb_messages[match].code == type)
4623 if (match == num_smb_messages)
4625 DEBUG(0,("Unknown message type %d!\n",type));
4626 outsize = reply_unknown(inbuf,outbuf);
4630 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4632 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4635 * Queue this message as we are the process of an oplock break.
4638 DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
4639 DEBUGADD( 2, ( "oplock break state.\n" ) );
4641 push_oplock_pending_smb_message( inbuf, size );
4645 if (smb_messages[match].fn)
4647 int cnum = SVAL(inbuf,smb_tid);
4648 int flags = smb_messages[match].flags;
4649 static uint16 last_session_tag = UID_FIELD_INVALID;
4650 /* In share mode security we must ignore the vuid. */
4651 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4652 connection_struct *conn = NULL;
4654 if (VALID_CNUM(cnum) && Connections[cnum].open) {
4655 conn = &Connections[cnum];
4658 /* Ensure this value is replaced in the incoming packet. */
4659 SSVAL(inbuf,smb_uid,session_tag);
4662 * Ensure the correct username is in sesssetup_user.
4663 * This is a really ugly bugfix for problems with
4664 * multiple session_setup_and_X's being done and
4665 * allowing %U and %G substitutions to work correctly.
4666 * There is a reason this code is done here, don't
4667 * move it unless you know what you're doing... :-).
4670 if (session_tag != last_session_tag) {
4671 user_struct *vuser = NULL;
4673 last_session_tag = session_tag;
4674 if(session_tag != UID_FIELD_INVALID)
4675 vuser = get_valid_user_struct(session_tag);
4677 pstrcpy( sesssetup_user, vuser->requested_name);
4680 /* does this protocol need to be run as root? */
4681 if (!(flags & AS_USER))
4684 /* does this protocol need to be run as the connected user? */
4685 if ((flags & AS_USER) && !become_user(conn,session_tag)) {
4686 if (flags & AS_GUEST)
4689 return(ERROR(ERRSRV,ERRinvnid));
4691 /* this code is to work around a bug is MS client 3 without
4692 introducing a security hole - it needs to be able to do
4693 print queue checks as guest if it isn't logged in properly */
4694 if (flags & AS_USER)
4697 /* does it need write permission? */
4698 if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
4699 return(ERROR(ERRSRV,ERRaccess));
4701 /* ipc services are limited */
4702 if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) {
4703 return(ERROR(ERRSRV,ERRaccess));
4706 /* load service specific parameters */
4707 if (OPEN_CNUM(conn) &&
4708 !become_service(conn,(flags & AS_USER)?True:False)) {
4709 return(ERROR(ERRSRV,ERRaccess));
4712 /* does this protocol need to be run as guest? */
4713 if ((flags & AS_GUEST) &&
4715 !check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1)))) {
4716 return(ERROR(ERRSRV,ERRaccess));
4721 outsize = smb_messages[match].fn(conn, inbuf,outbuf,size,bufsize);
4725 outsize = reply_unknown(inbuf,outbuf);
4730 GetTimeOfDay(&msg_end_time);
4731 if (!(smb_messages[match].flags & TIME_INIT))
4733 smb_messages[match].time = 0;
4734 smb_messages[match].flags |= TIME_INIT;
4737 unsigned long this_time =
4738 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4739 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4740 smb_messages[match].time += this_time;
4741 total_time += this_time;
4743 DEBUG(2,("TIME %s %d usecs %g pct\n",
4744 smb_fn_name(type),smb_messages[match].time,
4745 (100.0*smb_messages[match].time) / total_time));
4752 /****************************************************************************
4753 construct a chained reply and add it to the already made reply
4754 **************************************************************************/
4755 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4757 static char *orig_inbuf;
4758 static char *orig_outbuf;
4759 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4760 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4761 char *inbuf2, *outbuf2;
4763 char inbuf_saved[smb_wct];
4764 char outbuf_saved[smb_wct];
4765 extern int chain_size;
4766 int wct = CVAL(outbuf,smb_wct);
4767 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4769 /* maybe its not chained */
4770 if (smb_com2 == 0xFF) {
4771 CVAL(outbuf,smb_vwv0) = 0xFF;
4775 if (chain_size == 0) {
4776 /* this is the first part of the chain */
4778 orig_outbuf = outbuf;
4781 /* we need to tell the client where the next part of the reply will be */
4782 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4783 CVAL(outbuf,smb_vwv0) = smb_com2;
4785 /* remember how much the caller added to the chain, only counting stuff
4786 after the parameter words */
4787 chain_size += outsize - smb_wct;
4789 /* work out pointers into the original packets. The
4790 headers on these need to be filled in */
4791 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4792 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4794 /* remember the original command type */
4795 smb_com1 = CVAL(orig_inbuf,smb_com);
4797 /* save the data which will be overwritten by the new headers */
4798 memcpy(inbuf_saved,inbuf2,smb_wct);
4799 memcpy(outbuf_saved,outbuf2,smb_wct);
4801 /* give the new packet the same header as the last part of the SMB */
4802 memmove(inbuf2,inbuf,smb_wct);
4804 /* create the in buffer */
4805 CVAL(inbuf2,smb_com) = smb_com2;
4807 /* create the out buffer */
4808 bzero(outbuf2,smb_size);
4809 set_message(outbuf2,0,0,True);
4810 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4812 memcpy(outbuf2+4,inbuf2+4,4);
4813 CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4814 CVAL(outbuf2,smb_reh) = 0;
4815 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4817 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4818 SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4819 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4820 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4821 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4822 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4824 DEBUG(3,("Chained message\n"));
4827 /* process the request */
4828 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4829 bufsize-chain_size);
4831 /* copy the new reply and request headers over the old ones, but
4832 preserve the smb_com field */
4833 memmove(orig_outbuf,outbuf2,smb_wct);
4834 CVAL(orig_outbuf,smb_com) = smb_com1;
4836 /* restore the saved data, being careful not to overwrite any
4837 data from the reply header */
4838 memcpy(inbuf2,inbuf_saved,smb_wct);
4840 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4841 if (ofs < 0) ofs = 0;
4842 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4849 /****************************************************************************
4850 Helper function for contruct_reply.
4851 ****************************************************************************/
4853 void construct_reply_common(char *inbuf,char *outbuf)
4855 bzero(outbuf,smb_size);
4857 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4858 set_message(outbuf,0,0,True);
4860 memcpy(outbuf+4,inbuf+4,4);
4861 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4862 CVAL(outbuf,smb_reh) = 0;
4863 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4865 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4866 SSVAL(outbuf,smb_err,SMB_SUCCESS);
4867 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4868 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4869 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4870 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4873 /****************************************************************************
4874 construct a reply to the incoming packet
4875 ****************************************************************************/
4876 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4878 int type = CVAL(inbuf,smb_com);
4880 int msg_type = CVAL(inbuf,0);
4881 extern int chain_size;
4883 smb_last_time = time(NULL);
4890 return(reply_special(inbuf,outbuf));
4892 construct_reply_common(inbuf, outbuf);
4894 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4896 outsize += chain_size;
4899 smb_setlen(outbuf,outsize - 4);
4903 /****************************************************************************
4904 process commands from the client
4905 ****************************************************************************/
4906 static void process(void)
4910 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4911 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4912 if ((InBuffer == NULL) || (OutBuffer == NULL))
4915 InBuffer += SMB_ALIGNMENT;
4916 OutBuffer += SMB_ALIGNMENT;
4919 DEBUG(3,("priming nmbd\n"));
4922 ip = *interpret_addr2("localhost");
4923 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4925 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4929 /* re-initialise the timezone */
4934 int deadtime = lp_deadtime()*60;
4936 int last_keepalive=0;
4937 int service_load_counter = 0;
4938 BOOL got_smb = False;
4941 deadtime = DEFAULT_SMBD_TIMEOUT;
4943 #if USE_READ_PREDICTION
4944 if (lp_readprediction())
4945 do_read_prediction();
4950 for (counter=SMBD_SELECT_LOOP;
4951 !receive_message_or_smb(Client,oplock_sock,
4952 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4953 counter += SMBD_SELECT_LOOP)
4957 BOOL allidle = True;
4958 extern int keepalive;
4960 if (counter > 365 * 3600) /* big number of seconds. */
4963 service_load_counter = 0;
4966 if (smb_read_error == READ_EOF)
4968 DEBUG(3,("end of file from client\n"));
4972 if (smb_read_error == READ_ERROR)
4974 DEBUG(3,("receive_smb error (%s) exiting\n",
4981 /* become root again if waiting */
4984 /* check for smb.conf reload */
4985 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4987 service_load_counter = counter;
4989 /* reload services, if files have changed. */
4990 reload_services(True);
4994 * If reload_after_sighup == True then we got a SIGHUP
4995 * and are being asked to reload. Fix from <branko.cibej@hermes.si>
4998 if (reload_after_sighup)
5000 DEBUG(0,("Reloading services after SIGHUP\n"));
5001 reload_services(False);
5002 reload_after_sighup = False;
5005 /* automatic timeout if all connections are closed */
5006 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
5008 DEBUG( 2, ( "Closing idle connection\n" ) );
5012 if (keepalive && (counter-last_keepalive)>keepalive)
5014 struct cli_state *cli = server_client();
5015 if (!send_keepalive(Client)) {
5016 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
5019 /* also send a keepalive to the password server if its still
5021 if (cli && cli->initialised)
5022 send_keepalive(cli->fd);
5023 last_keepalive = counter;
5026 /* check for connection timeouts */
5027 for (i=0;i<MAX_CONNECTIONS;i++) {
5028 if (Connections[i].open) {
5029 /* close dirptrs on connections that are idle */
5030 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5031 dptr_idlecnum(&Connections[i]);
5033 if (Connections[i].num_files_open > 0 ||
5034 (t-Connections[i].lastused)<deadtime)
5039 if (allidle && num_connections_open>0) {
5040 DEBUG(2,("Closing idle connection 2.\n"));
5044 if(global_machine_pasword_needs_changing)
5046 unsigned char trust_passwd_hash[16];
5048 pstring remote_machine_list;
5051 * We're in domain level security, and the code that
5052 * read the machine password flagged that the machine
5053 * password needs changing.
5057 * First, open the machine password file with an exclusive lock.
5060 if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5061 DEBUG(0,("process: unable to open the machine account password file for \
5062 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5066 if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5067 DEBUG(0,("process: unable to read the machine account password for \
5068 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5069 trust_password_unlock();
5074 * Make sure someone else hasn't already done this.
5077 if(t < lct + lp_machine_password_timeout()) {
5078 trust_password_unlock();
5079 global_machine_pasword_needs_changing = False;
5083 pstrcpy(remote_machine_list, lp_passwordserver());
5085 change_trust_account_password( global_myworkgroup, remote_machine_list);
5086 trust_password_unlock();
5087 global_machine_pasword_needs_changing = False;
5091 * Check to see if we have any change notifies
5092 * outstanding on the queue.
5094 process_pending_change_notify_queue(t);
5098 process_smb(InBuffer, OutBuffer);
5100 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5105 /****************************************************************************
5106 initialise connect, service and file structs
5107 ****************************************************************************/
5108 static void init_structs(void )
5111 get_myname(myhostname,NULL);
5114 * Set the machine NETBIOS name if not already
5115 * set from the config file.
5118 if (!*global_myname)
5121 fstrcpy( global_myname, myhostname );
5122 p = strchr( global_myname, '.' );
5126 strupper( global_myname );
5128 for (i=0;i<MAX_CONNECTIONS;i++)
5130 Connections[i].open = False;
5131 Connections[i].num_files_open=0;
5132 Connections[i].lastused=0;
5133 Connections[i].used=False;
5134 string_init(&Connections[i].user,"");
5135 string_init(&Connections[i].dirpath,"");
5136 string_init(&Connections[i].connectpath,"");
5137 string_init(&Connections[i].origpath,"");
5140 for (i=0;i<MAX_FNUMS;i++)
5142 Files[i].open = False;
5143 string_init(&Files[i].fsp_name,"");
5146 for (i=0;i<MAX_OPEN_FILES;i++)
5148 file_fd_struct *fd_ptr = &FileFd[i];
5149 fd_ptr->ref_count = 0;
5150 fd_ptr->dev = (int32)-1;
5151 fd_ptr->inode = (int32)-1;
5153 fd_ptr->fd_readonly = -1;
5154 fd_ptr->fd_writeonly = -1;
5155 fd_ptr->real_open_flags = -1;
5159 init_rpc_pipe_hnd();
5161 /* for LSA handles */
5162 init_lsa_policy_hnd();
5167 /****************************************************************************
5168 usage on the program
5169 ****************************************************************************/
5170 static void usage(char *pname)
5172 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5174 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5175 printf("Version %s\n",VERSION);
5176 printf("\t-D become a daemon\n");
5177 printf("\t-p port listen on the specified port\n");
5178 printf("\t-d debuglevel set the debuglevel\n");
5179 printf("\t-l log basename. Basename for log/debug files\n");
5180 printf("\t-s services file. Filename of services file\n");
5181 printf("\t-P passive only\n");
5182 printf("\t-a overwrite log file, don't append\n");
5187 /****************************************************************************
5189 ****************************************************************************/
5190 int main(int argc,char *argv[])
5192 extern BOOL append_log;
5193 /* shall I run as a daemon */
5194 BOOL is_daemon = False;
5195 int port = SMB_PORT;
5197 extern char *optarg;
5199 #ifdef HAVE_SET_AUTH_PARAMETERS
5200 set_auth_parameters(argc,argv);
5204 /* needed for SecureWare on SCO */
5212 pstrcpy(debugf,SMBLOGFILE);
5214 pstrcpy(remote_machine, "smb");
5216 setup_logging(argv[0],False);
5218 charset_initialise();
5220 /* make absolutely sure we run as root - to handle cases where people
5221 are crazy enough to have it setuid */
5222 #ifdef HAVE_SETRESUID
5231 fault_setup((void (*)(void *))exit_server);
5232 CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
5234 /* we want total control over the permissions on created files,
5235 so set our umask to 0 */
5242 /* this is for people who can't start the program correctly */
5243 while (argc > 1 && (*argv[1] != '-'))
5249 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5253 pstrcpy(user_socket_options,optarg);
5256 pstrcpy(scope,optarg);
5260 extern BOOL passive;
5265 pstrcpy(servicesf,optarg);
5268 pstrcpy(debugf,optarg);
5272 extern BOOL append_log;
5273 append_log = !append_log;
5283 DEBUGLEVEL = atoi(optarg);
5286 port = atoi(optarg);
5299 DEBUG( 1, ( "smbd version %s started.\n", VERSION ) );
5300 DEBUGADD( 1, ( "Copyright Andrew Tridgell 1992-1997\n" ) );
5302 #ifdef HAVE_GETRLIMIT
5303 #ifdef RLIMIT_NOFILE
5306 getrlimit(RLIMIT_NOFILE, &rlp);
5308 * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5309 * extra fd we need to read directories, as well as the log files
5310 * and standard handles etc.
5312 rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5313 setrlimit(RLIMIT_NOFILE, &rlp);
5314 getrlimit(RLIMIT_NOFILE, &rlp);
5315 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5321 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5322 getuid(),getgid(),geteuid(),getegid()));
5324 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5326 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5332 if (!reload_services(False))
5337 extern BOOL sslEnabled;
5338 sslEnabled = lp_ssl_enabled();
5342 #endif /* WITH_SSL */
5344 codepage_initialise(lp_client_code_page());
5346 pstrcpy(global_myworkgroup, lp_workgroup());
5348 if(!pdb_generate_machine_sid()) {
5349 DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5353 CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
5355 /* Setup the signals that allow the debug log level
5356 to by dynamically changed. */
5358 /* If we are using the malloc debug code we can't use
5359 SIGUSR1 and SIGUSR2 to do debug level changes. */
5362 #if defined(SIGUSR1)
5363 CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5364 #endif /* SIGUSR1 */
5366 #if defined(SIGUSR2)
5367 CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5368 #endif /* SIGUSR2 */
5369 #endif /* MEM_MAN */
5371 DEBUG( 3, ( "loaded services\n" ) );
5373 if (!is_daemon && !is_a_socket(0))
5375 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5381 DEBUG( 3, ( "Becoming a daemon.\n" ) );
5385 if (!directory_exist(lp_lockdir(), NULL)) {
5386 mkdir(lp_lockdir(), 0755);
5390 pidfile_create("smbd");
5393 if (!open_sockets(is_daemon,port))
5396 if (!locking_init(0))
5399 if(!initialize_password_db())
5402 /* possibly reload the services file. */
5403 reload_services(True);
5405 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5409 if (sys_chroot(lp_rootdir()) == 0)
5410 DEBUG( 2, ( "Changed root to %s\n", lp_rootdir() ) );
5413 /* Setup the oplock IPC socket. */
5414 if( !open_oplock_ipc() )
5420 exit_server("normal exit");