Makefile: Added nttrans.o
[Samba/gebeck_regimport.git] / source / smbd / server.c
bloba236e2e6ecbfd5ad81934fd66ecdd7f54585fdaa
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
23 #include "trans2.h"
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;
35 int am_parent = 1;
36 int atexit_set = 0;
38 /* the last message the was processed */
39 int last_message = -1;
41 /* a useful macro to debug the last message processed */
42 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern pstring scope;
45 extern int DEBUGLEVEL;
46 extern int case_default;
47 extern BOOL case_sensitive;
48 extern BOOL case_preserve;
49 extern BOOL use_mangled_map;
50 extern BOOL short_case_preserve;
51 extern BOOL case_mangle;
52 time_t smb_last_time=(time_t)0;
53 extern BOOL global_machine_pasword_needs_changing;
55 extern int smb_read_error;
57 extern pstring user_socket_options;
59 #ifdef DFS_AUTH
60 extern int dcelogin_atmost_once;
61 #endif /* DFS_AUTH */
64 * This is set on startup - it defines the SID for this
65 * machine.
67 extern DOM_SID global_machine_sid;
69 connection_struct Connections[MAX_CONNECTIONS];
70 files_struct Files[MAX_OPEN_FILES];
73 * Indirection for file fd's. Needed as POSIX locking
74 * is based on file/process, not fd/process.
76 file_fd_struct FileFd[MAX_OPEN_FILES];
77 int max_file_fd_used = 0;
79 extern int Protocol;
81 /*
82 * Size of data we can send to client. Set
83 * by the client for all protocols above CORE.
84 * Set by us for CORE protocol.
86 int max_send = BUFFER_SIZE;
88 * Size of the data we can receive. Set by us.
89 * Can be modified by the max xmit parameter.
91 int max_recv = BUFFER_SIZE;
93 /* a fnum to use when chaining */
94 int chain_fnum = -1;
96 /* number of open connections */
97 static int num_connections_open = 0;
99 /* Oplock ipc UDP socket. */
100 int oplock_sock = -1;
101 uint16 oplock_port = 0;
102 /* Current number of oplocks we have outstanding. */
103 int32 global_oplocks_open = 0;
105 BOOL global_oplock_break = False;
107 extern fstring remote_machine;
109 extern pstring OriginalDir;
111 /* these can be set by some functions to override the error codes */
112 int unix_ERR_class=SMB_SUCCESS;
113 int unix_ERR_code=0;
116 extern int extra_time_offset;
118 extern pstring myhostname;
120 static int find_free_connection(int hash);
122 /* for readability... */
123 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
124 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
125 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
126 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
127 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
129 /****************************************************************************
130 when exiting, take the whole family
131 ****************************************************************************/
132 void *dflt_sig(void)
134 exit_server("caught signal");
135 return 0; /* Keep -Wall happy :-) */
137 /****************************************************************************
138 Send a SIGTERM to our process group.
139 *****************************************************************************/
140 void killkids(void)
142 if(am_parent) kill(0,SIGTERM);
145 /****************************************************************************
146 change a dos mode to a unix mode
147 base permission for files:
148 everybody gets read bit set
149 dos readonly is represented in unix by removing everyone's write bit
150 dos archive is represented in unix by the user's execute bit
151 dos system is represented in unix by the group's execute bit
152 dos hidden is represented in unix by the other's execute bit
153 Then apply create mask,
154 then add force bits.
155 base permission for directories:
156 dos directory is represented in unix by unix's dir bit and the exec bit
157 Then apply create mask,
158 then add force bits.
159 ****************************************************************************/
160 mode_t unix_mode(int cnum,int dosmode)
162 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
164 if ( !IS_DOS_READONLY(dosmode) )
165 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
167 if (IS_DOS_DIR(dosmode)) {
168 /* We never make directories read only for the owner as under DOS a user
169 can always create a file in a read-only directory. */
170 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
171 /* Apply directory mask */
172 result &= lp_dir_mode(SNUM(cnum));
173 /* Add in force bits */
174 result |= lp_force_dir_mode(SNUM(cnum));
175 } else {
176 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
177 result |= S_IXUSR;
179 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
180 result |= S_IXGRP;
182 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
183 result |= S_IXOTH;
185 /* Apply mode mask */
186 result &= lp_create_mode(SNUM(cnum));
187 /* Add in force bits */
188 result |= lp_force_create_mode(SNUM(cnum));
190 return(result);
194 /****************************************************************************
195 change a unix mode to a dos mode
196 ****************************************************************************/
197 int dos_mode(int cnum,char *path,struct stat *sbuf)
199 int result = 0;
200 extern struct current_user current_user;
202 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
204 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
205 if (!((sbuf->st_mode & S_IWOTH) ||
206 Connections[cnum].admin_user ||
207 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
208 ((sbuf->st_mode & S_IWGRP) &&
209 in_group(sbuf->st_gid,current_user.gid,
210 current_user.ngroups,current_user.igroups))))
211 result |= aRONLY;
212 } else {
213 if ((sbuf->st_mode & S_IWUSR) == 0)
214 result |= aRONLY;
217 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
218 result |= aARCH;
220 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
221 result |= aSYSTEM;
223 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
224 result |= aHIDDEN;
226 if (S_ISDIR(sbuf->st_mode))
227 result = aDIR | (result & aRONLY);
229 #ifdef S_ISLNK
230 #if LINKS_READ_ONLY
231 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
232 result |= aRONLY;
233 #endif
234 #endif
236 /* hide files with a name starting with a . */
237 if (lp_hide_dot_files(SNUM(cnum)))
239 char *p = strrchr(path,'/');
240 if (p)
241 p++;
242 else
243 p = path;
245 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
246 result |= aHIDDEN;
249 /* Optimization : Only call is_hidden_path if it's not already
250 hidden. */
251 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
253 result |= aHIDDEN;
256 DEBUG(8,("dos_mode returning "));
258 if (result & aHIDDEN) DEBUG(8, ("h"));
259 if (result & aRONLY ) DEBUG(8, ("r"));
260 if (result & aSYSTEM) DEBUG(8, ("s"));
261 if (result & aDIR ) DEBUG(8, ("d"));
262 if (result & aARCH ) DEBUG(8, ("a"));
264 DEBUG(8,("\n"));
266 return(result);
269 /*******************************************************************
270 chmod a file - but preserve some bits
271 ********************************************************************/
272 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
274 struct stat st1;
275 int mask=0;
276 int tmp;
277 int unixmode;
279 if (!st) {
280 st = &st1;
281 if (sys_stat(fname,st)) return(-1);
284 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
286 if (dos_mode(cnum,fname,st) == dosmode) return(0);
288 unixmode = unix_mode(cnum,dosmode);
290 /* preserve the s bits */
291 mask |= (S_ISUID | S_ISGID);
293 /* preserve the t bit */
294 #ifdef S_ISVTX
295 mask |= S_ISVTX;
296 #endif
298 /* possibly preserve the x bits */
299 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
300 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
301 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
303 unixmode |= (st->st_mode & mask);
305 /* if we previously had any r bits set then leave them alone */
306 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
307 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
308 unixmode |= tmp;
311 /* if we previously had any w bits set then leave them alone
312 if the new mode is not rdonly */
313 if (!IS_DOS_READONLY(dosmode) &&
314 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
315 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
316 unixmode |= tmp;
319 return(sys_chmod(fname,unixmode));
322 /*******************************************************************
323 Wrapper around sys_utime that possibly allows DOS semantics rather
324 than POSIX.
325 *******************************************************************/
327 int file_utime(int cnum, char *fname, struct utimbuf *times)
329 extern struct current_user current_user;
330 struct stat sb;
331 int ret = -1;
333 errno = 0;
335 if(sys_utime(fname, times) == 0)
336 return 0;
338 if((errno != EPERM) && (errno != EACCES))
339 return -1;
341 if(!lp_dos_filetimes(SNUM(cnum)))
342 return -1;
344 /* We have permission (given by the Samba admin) to
345 break POSIX semantics and allow a user to change
346 the time on a file they don't own but can write to
347 (as DOS does).
350 if(sys_stat(fname,&sb) != 0)
351 return -1;
353 /* Check if we have write access. */
354 if (CAN_WRITE(cnum)) {
355 if (((sb.st_mode & S_IWOTH) ||
356 Connections[cnum].admin_user ||
357 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
358 ((sb.st_mode & S_IWGRP) &&
359 in_group(sb.st_gid,current_user.gid,
360 current_user.ngroups,current_user.igroups)))) {
361 /* We are allowed to become root and change the filetime. */
362 become_root(False);
363 ret = sys_utime(fname, times);
364 unbecome_root(False);
368 return ret;
371 /*******************************************************************
372 Change a filetime - possibly allowing DOS semantics.
373 *******************************************************************/
375 BOOL set_filetime(int cnum, char *fname, time_t mtime)
377 struct utimbuf times;
379 if (null_mtime(mtime)) return(True);
381 times.modtime = times.actime = mtime;
383 if (file_utime(cnum, fname, &times)) {
384 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
387 return(True);
390 /****************************************************************************
391 check if two filenames are equal
393 this needs to be careful about whether we are case sensitive
394 ****************************************************************************/
395 static BOOL fname_equal(char *name1, char *name2)
397 int l1 = strlen(name1);
398 int l2 = strlen(name2);
400 /* handle filenames ending in a single dot */
401 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
403 BOOL ret;
404 name1[l1-1] = 0;
405 ret = fname_equal(name1,name2);
406 name1[l1-1] = '.';
407 return(ret);
410 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
412 BOOL ret;
413 name2[l2-1] = 0;
414 ret = fname_equal(name1,name2);
415 name2[l2-1] = '.';
416 return(ret);
419 /* now normal filename handling */
420 if (case_sensitive)
421 return(strcmp(name1,name2) == 0);
423 return(strequal(name1,name2));
427 /****************************************************************************
428 mangle the 2nd name and check if it is then equal to the first name
429 ****************************************************************************/
430 static BOOL mangled_equal(char *name1, char *name2)
432 pstring tmpname;
434 if (is_8_3(name2, True))
435 return(False);
437 pstrcpy(tmpname,name2);
438 mangle_name_83(tmpname,sizeof(tmpname));
440 return(strequal(name1,tmpname));
444 /****************************************************************************
445 scan a directory to find a filename, matching without case sensitivity
447 If the name looks like a mangled name then try via the mangling functions
448 ****************************************************************************/
449 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
451 void *cur_dir;
452 char *dname;
453 BOOL mangled;
454 pstring name2;
456 mangled = is_mangled(name);
458 /* handle null paths */
459 if (*path == 0)
460 path = ".";
462 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
463 pstrcpy(name, dname);
464 return(True);
468 * The incoming name can be mangled, and if we de-mangle it
469 * here it will not compare correctly against the filename (name2)
470 * read from the directory and then mangled by the name_map_mangle()
471 * call. We need to mangle both names or neither.
472 * (JRA).
474 if (mangled)
475 mangled = !check_mangled_cache( name );
477 /* open the directory */
478 if (!(cur_dir = OpenDir(cnum, path, True)))
480 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
481 return(False);
484 /* now scan for matching names */
485 while ((dname = ReadDirName(cur_dir)))
487 if (*dname == '.' &&
488 (strequal(dname,".") || strequal(dname,"..")))
489 continue;
491 pstrcpy(name2,dname);
492 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
494 if ((mangled && mangled_equal(name,name2))
495 || fname_equal(name, name2))
497 /* we've found the file, change it's name and return */
498 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
499 pstrcpy(name, dname);
500 CloseDir(cur_dir);
501 return(True);
505 CloseDir(cur_dir);
506 return(False);
509 /****************************************************************************
510 This routine is called to convert names from the dos namespace to unix
511 namespace. It needs to handle any case conversions, mangling, format
512 changes etc.
514 We assume that we have already done a chdir() to the right "root" directory
515 for this service.
517 The function will return False if some part of the name except for the last
518 part cannot be resolved
520 If the saved_last_component != 0, then the unmodified last component
521 of the pathname is returned there. This is used in an exceptional
522 case in reply_mv (so far). If saved_last_component == 0 then nothing
523 is returned there.
525 The bad_path arg is set to True if the filename walk failed. This is
526 used to pick the correct error code to return between ENOENT and ENOTDIR
527 as Windows applications depend on ERRbadpath being returned if a component
528 of a pathname does not exist.
529 ****************************************************************************/
530 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
532 struct stat st;
533 char *start, *end;
534 pstring dirpath;
535 int saved_errno;
537 *dirpath = 0;
538 *bad_path = False;
540 if(saved_last_component)
541 *saved_last_component = 0;
543 /* convert to basic unix format - removing \ chars and cleaning it up */
544 unix_format(name);
545 unix_clean_name(name);
547 /* names must be relative to the root of the service - trim any leading /.
548 also trim trailing /'s */
549 trim_string(name,"/","/");
552 * Ensure saved_last_component is valid even if file exists.
554 if(saved_last_component) {
555 end = strrchr(name, '/');
556 if(end)
557 pstrcpy(saved_last_component, end + 1);
558 else
559 pstrcpy(saved_last_component, name);
562 if (!case_sensitive &&
563 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
564 strnorm(name);
566 /* check if it's a printer file */
567 if (Connections[cnum].printer)
569 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
571 char *s;
572 fstring name2;
573 slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
574 /* sanitise the name */
575 for (s=name2 ; *s ; s++)
576 if (!issafe(*s)) *s = '_';
577 pstrcpy(name,(char *)mktemp(name2));
579 return(True);
582 /* stat the name - if it exists then we are all done! */
583 if (sys_stat(name,&st) == 0)
584 return(True);
586 saved_errno = errno;
588 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
590 /* a special case - if we don't have any mangling chars and are case
591 sensitive then searching won't help */
592 if (case_sensitive && !is_mangled(name) &&
593 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
594 return(False);
596 /* now we need to recursively match the name against the real
597 directory structure */
599 start = name;
600 while (strncmp(start,"./",2) == 0)
601 start += 2;
603 /* now match each part of the path name separately, trying the names
604 as is first, then trying to scan the directory for matching names */
605 for (;start;start = (end?end+1:(char *)NULL))
607 /* pinpoint the end of this section of the filename */
608 end = strchr(start, '/');
610 /* chop the name at this point */
611 if (end) *end = 0;
613 if(saved_last_component != 0)
614 pstrcpy(saved_last_component, end ? end + 1 : start);
616 /* check if the name exists up to this point */
617 if (sys_stat(name, &st) == 0)
619 /* it exists. it must either be a directory or this must be
620 the last part of the path for it to be OK */
621 if (end && !(st.st_mode & S_IFDIR))
623 /* an intermediate part of the name isn't a directory */
624 DEBUG(5,("Not a dir %s\n",start));
625 *end = '/';
626 return(False);
629 else
631 pstring rest;
633 *rest = 0;
635 /* remember the rest of the pathname so it can be restored
636 later */
637 if (end) pstrcpy(rest,end+1);
639 /* try to find this part of the path in the directory */
640 if (strchr(start,'?') || strchr(start,'*') ||
641 !scan_directory(dirpath, start, cnum, end?True:False))
643 if (end)
645 /* an intermediate part of the name can't be found */
646 DEBUG(5,("Intermediate not found %s\n",start));
647 *end = '/';
648 /* We need to return the fact that the intermediate
649 name resolution failed. This is used to return an
650 error of ERRbadpath rather than ERRbadfile. Some
651 Windows applications depend on the difference between
652 these two errors.
654 *bad_path = True;
655 return(False);
658 /* just the last part of the name doesn't exist */
659 /* we may need to strupper() or strlower() it in case
660 this conversion is being used for file creation
661 purposes */
662 /* if the filename is of mixed case then don't normalise it */
663 if (!case_preserve &&
664 (!strhasupper(start) || !strhaslower(start)))
665 strnorm(start);
667 /* check on the mangled stack to see if we can recover the
668 base of the filename */
669 if (is_mangled(start))
670 check_mangled_cache( start );
672 DEBUG(5,("New file %s\n",start));
673 return(True);
676 /* restore the rest of the string */
677 if (end)
679 pstrcpy(start+strlen(start)+1,rest);
680 end = start + strlen(start);
684 /* add to the dirpath that we have resolved so far */
685 if (*dirpath) pstrcat(dirpath,"/");
686 pstrcat(dirpath,start);
688 /* restore the / that we wiped out earlier */
689 if (end) *end = '/';
692 /* the name has been resolved */
693 DEBUG(5,("conversion finished %s\n",name));
694 return(True);
698 /****************************************************************************
699 normalise for DOS usage
700 ****************************************************************************/
701 static void disk_norm(int *bsize,int *dfree,int *dsize)
703 /* check if the disk is beyond the max disk size */
704 int maxdisksize = lp_maxdisksize();
705 if (maxdisksize) {
706 /* convert to blocks - and don't overflow */
707 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
708 if (*dsize > maxdisksize) *dsize = maxdisksize;
709 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
710 applications getting
711 div by 0 errors */
714 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
716 *dfree /= 2;
717 *dsize /= 2;
718 *bsize *= 2;
719 if (*bsize > WORDMAX )
721 *bsize = WORDMAX;
722 if (*dsize > WORDMAX)
723 *dsize = WORDMAX;
724 if (*dfree > WORDMAX)
725 *dfree = WORDMAX;
726 break;
731 /****************************************************************************
732 return number of 1K blocks available on a path and total number
733 ****************************************************************************/
734 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
736 char *df_command = lp_dfree_command();
737 int dfree_retval;
738 #ifdef QUOTAS
739 int dfreeq_retval;
740 int dfreeq = 0;
741 int bsizeq = *bsize;
742 int dsizeq = *dsize;
743 #endif
745 #ifndef NO_STATFS
746 #ifdef USE_STATVFS
747 struct statvfs fs;
748 #else
749 #ifdef ULTRIX
750 struct fs_data fs;
751 #else
752 struct statfs fs;
753 #endif
754 #endif
755 #endif
757 /* possibly use system() to get the result */
758 if (df_command && *df_command)
760 int ret;
761 pstring syscmd;
762 pstring outfile;
764 slprintf(outfile,sizeof(outfile)-1, "%s/dfree.smb.%d",tmpdir(),(int)getpid());
765 slprintf(syscmd,sizeof(syscmd)-1,"%s %s",df_command,path);
766 standard_sub_basic(syscmd);
768 ret = smbrun(syscmd,outfile,False);
769 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
772 FILE *f = fopen(outfile,"r");
773 *dsize = 0;
774 *dfree = 0;
775 *bsize = 1024;
776 if (f)
778 fscanf(f,"%d %d %d",dsize,dfree,bsize);
779 fclose(f);
781 else
782 DEBUG(0,("Can't open %s\n",outfile));
785 unlink(outfile);
786 disk_norm(bsize,dfree,dsize);
787 dfree_retval = ((*bsize)/1024)*(*dfree);
788 #ifdef QUOTAS
789 /* Ensure we return the min value between the users quota and
790 what's free on the disk. Thanks to Albrecht Gebhardt
791 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
793 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
795 disk_norm(&bsizeq, &dfreeq, &dsizeq);
796 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
797 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
798 dfree_retval : dfreeq_retval ;
799 /* maybe dfree and dfreeq are calculated using different bsizes
800 so convert dfree from bsize into bsizeq */
801 /* avoid overflows due to multiplication, so do not:
802 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
803 bsize and bsizeq are powers of 2 so its better to
804 to divide them getting a multiplication or division factor
805 for dfree. Rene Nieuwenhuizen (07-10-1997) */
806 if (*bsize >= bsizeq)
807 *dfree = *dfree * (*bsize / bsizeq);
808 else
809 *dfree = *dfree / (bsizeq / *bsize);
810 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
811 *bsize = bsizeq;
812 *dsize = dsizeq;
814 #endif
815 return(dfree_retval);
818 #ifdef NO_STATFS
819 DEBUG(1,("Warning - no statfs function\n"));
820 return(1);
821 #else
822 #ifdef STATFS4
823 if (statfs(path,&fs,sizeof(fs),0) != 0)
824 #else
825 #ifdef USE_STATVFS
826 if (statvfs(path, &fs))
827 #else
828 #ifdef STATFS3
829 if (statfs(path,&fs,sizeof(fs)) == -1)
830 #else
831 if (statfs(path,&fs) == -1)
832 #endif /* STATFS3 */
833 #endif /* USE_STATVFS */
834 #endif /* STATFS4 */
836 DEBUG(3,("dfree call failed code errno=%d\n",errno));
837 *bsize = 1024;
838 *dfree = 1;
839 *dsize = 1;
840 return(((*bsize)/1024)*(*dfree));
843 #ifdef ULTRIX
844 *bsize = 1024;
845 *dfree = fs.fd_req.bfree;
846 *dsize = fs.fd_req.btot;
847 #else
848 #ifdef USE_STATVFS
849 *bsize = fs.f_frsize;
850 #else
851 #ifdef USE_F_FSIZE
852 /* eg: osf1 has f_fsize = fundamental filesystem block size,
853 f_bsize = optimal transfer block size (MX: 94-04-19) */
854 *bsize = fs.f_fsize;
855 #else
856 *bsize = fs.f_bsize;
857 #endif /* STATFS3 */
858 #endif /* USE_STATVFS */
860 #ifdef STATFS4
861 *dfree = fs.f_bfree;
862 #else
863 *dfree = fs.f_bavail;
864 #endif /* STATFS4 */
865 *dsize = fs.f_blocks;
866 #endif /* ULTRIX */
868 #if defined(SCO) || defined(ISC) || defined(MIPS)
869 *bsize = 512;
870 #endif
872 /* handle rediculous bsize values - some OSes are broken */
873 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
875 disk_norm(bsize,dfree,dsize);
877 if (*bsize < 256)
878 *bsize = 512;
879 if ((*dsize)<1)
881 DEBUG(0,("dfree seems to be broken on your system\n"));
882 *dsize = 20*1024*1024/(*bsize);
883 *dfree = MAX(1,*dfree);
885 dfree_retval = ((*bsize)/1024)*(*dfree);
886 #ifdef QUOTAS
887 /* Ensure we return the min value between the users quota and
888 what's free on the disk. Thanks to Albrecht Gebhardt
889 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
891 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
893 disk_norm(&bsizeq, &dfreeq, &dsizeq);
894 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
895 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
896 dfree_retval : dfreeq_retval ;
897 /* maybe dfree and dfreeq are calculated using different bsizes
898 so convert dfree from bsize into bsizeq */
899 /* avoid overflows due to multiplication, so do not:
900 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
901 bsize and bsizeq are powers of 2 so its better to
902 to divide them getting a multiplication or division factor
903 for dfree. Rene Nieuwenhuizen (07-10-1997) */
904 if (*bsize >= bsizeq)
905 *dfree = *dfree * (*bsize / bsizeq);
906 else
907 *dfree = *dfree / (bsizeq / *bsize);
908 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
909 *bsize = bsizeq;
910 *dsize = dsizeq;
912 #endif
913 return(dfree_retval);
914 #endif
918 /****************************************************************************
919 wrap it to get filenames right
920 ****************************************************************************/
921 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
923 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
928 /****************************************************************************
929 check a filename - possibly caling reducename
931 This is called by every routine before it allows an operation on a filename.
932 It does any final confirmation necessary to ensure that the filename is
933 a valid one for the user to access.
934 ****************************************************************************/
935 BOOL check_name(char *name,int cnum)
937 BOOL ret;
939 errno = 0;
941 if( IS_VETO_PATH(cnum, name))
943 DEBUG(5,("file path name %s vetoed\n",name));
944 return(0);
947 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
949 /* Check if we are allowing users to follow symlinks */
950 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
951 University of Geneva */
953 #ifdef S_ISLNK
954 if (!lp_symlinks(SNUM(cnum)))
956 struct stat statbuf;
957 if ( (sys_lstat(name,&statbuf) != -1) &&
958 (S_ISLNK(statbuf.st_mode)) )
960 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
961 ret=0;
964 #endif
966 if (!ret)
967 DEBUG(5,("check_name on %s failed\n",name));
969 return(ret);
972 /****************************************************************************
973 check a filename - possibly caling reducename
974 ****************************************************************************/
975 static void check_for_pipe(char *fname)
977 /* special case of pipe opens */
978 char s[10];
979 StrnCpy(s,fname,9);
980 strlower(s);
981 if (strstr(s,"pipe/"))
983 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
984 unix_ERR_class = ERRSRV;
985 unix_ERR_code = ERRaccess;
989 /****************************************************************************
990 fd support routines - attempt to do a sys_open
991 ****************************************************************************/
992 static int fd_attempt_open(char *fname, int flags, int mode)
994 int fd = sys_open(fname,flags,mode);
996 /* Fix for files ending in '.' */
997 if((fd == -1) && (errno == ENOENT) &&
998 (strchr(fname,'.')==NULL))
1000 pstrcat(fname,".");
1001 fd = sys_open(fname,flags,mode);
1004 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
1005 if ((fd == -1) && (errno == ENAMETOOLONG))
1007 int max_len;
1008 char *p = strrchr(fname, '/');
1010 if (p == fname) /* name is "/xxx" */
1012 max_len = pathconf("/", _PC_NAME_MAX);
1013 p++;
1015 else if ((p == NULL) || (p == fname))
1017 p = fname;
1018 max_len = pathconf(".", _PC_NAME_MAX);
1020 else
1022 *p = '\0';
1023 max_len = pathconf(fname, _PC_NAME_MAX);
1024 *p = '/';
1025 p++;
1027 if (strlen(p) > max_len)
1029 char tmp = p[max_len];
1031 p[max_len] = '\0';
1032 if ((fd = sys_open(fname,flags,mode)) == -1)
1033 p[max_len] = tmp;
1036 #endif
1037 return fd;
1040 /****************************************************************************
1041 Cache a uid_t currently with this file open. This is an optimization only
1042 used when multiple sessionsetup's have been done to one smbd.
1043 ****************************************************************************/
1044 static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
1046 if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
1047 return;
1048 fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
1051 /****************************************************************************
1052 Remove a uid_t that currently has this file open. This is an optimization only
1053 used when multiple sessionsetup's have been done to one smbd.
1054 ****************************************************************************/
1055 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
1057 int i;
1058 for(i = 0; i < fd_ptr->uid_cache_count; i++)
1059 if(fd_ptr->uid_users_cache[i] == u) {
1060 if(i < (fd_ptr->uid_cache_count-1))
1061 memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
1062 sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
1063 fd_ptr->uid_cache_count--;
1065 return;
1068 /****************************************************************************
1069 Check if a uid_t that currently has this file open is present. This is an
1070 optimization only used when multiple sessionsetup's have been done to one smbd.
1071 ****************************************************************************/
1072 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
1074 int i;
1075 for(i = 0; i < fd_ptr->uid_cache_count; i++)
1076 if(fd_ptr->uid_users_cache[i] == u)
1077 return True;
1078 return False;
1081 /****************************************************************************
1082 fd support routines - attempt to find an already open file by dev
1083 and inode - increments the ref_count of the returned file_fd_struct *.
1084 ****************************************************************************/
1085 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1087 int i;
1088 file_fd_struct *fd_ptr;
1090 if(sbuf == 0)
1091 return 0;
1093 for(i = 0; i <= max_file_fd_used; i++) {
1094 fd_ptr = &FileFd[i];
1095 if((fd_ptr->ref_count > 0) &&
1096 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1097 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1098 fd_ptr->ref_count++;
1099 DEBUG(3,
1100 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1101 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1102 return fd_ptr;
1105 return 0;
1108 /****************************************************************************
1109 fd support routines - attempt to find a empty slot in the FileFd array.
1110 Increments the ref_count of the returned entry.
1111 ****************************************************************************/
1112 static file_fd_struct *fd_get_new(void)
1114 extern struct current_user current_user;
1115 int i;
1116 file_fd_struct *fd_ptr;
1118 for(i = 0; i < MAX_OPEN_FILES; i++) {
1119 fd_ptr = &FileFd[i];
1120 if(fd_ptr->ref_count == 0) {
1121 fd_ptr->dev = (uint32)-1;
1122 fd_ptr->inode = (uint32)-1;
1123 fd_ptr->fd = -1;
1124 fd_ptr->fd_readonly = -1;
1125 fd_ptr->fd_writeonly = -1;
1126 fd_ptr->real_open_flags = -1;
1127 fd_ptr->uid_cache_count = 0;
1128 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
1129 fd_ptr->ref_count++;
1130 /* Increment max used counter if neccessary, cuts down
1131 on search time when re-using */
1132 if(i > max_file_fd_used)
1133 max_file_fd_used = i;
1134 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1135 i, fd_ptr->dev, fd_ptr->inode));
1136 return fd_ptr;
1139 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
1140 return 0;
1143 /****************************************************************************
1144 fd support routines - attempt to re-open an already open fd as O_RDWR.
1145 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1146 ****************************************************************************/
1147 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1149 int fd = sys_open( fname, O_RDWR, mode);
1151 if(fd == -1)
1152 return;
1154 if(fd_ptr->real_open_flags == O_RDONLY)
1155 fd_ptr->fd_readonly = fd_ptr->fd;
1156 if(fd_ptr->real_open_flags == O_WRONLY)
1157 fd_ptr->fd_writeonly = fd_ptr->fd;
1159 fd_ptr->fd = fd;
1160 fd_ptr->real_open_flags = O_RDWR;
1163 /****************************************************************************
1164 fd support routines - attempt to close the file referenced by this fd.
1165 Decrements the ref_count and returns it.
1166 ****************************************************************************/
1167 static int fd_attempt_close(file_fd_struct *fd_ptr)
1169 extern struct current_user current_user;
1171 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1172 fd_ptr - &FileFd[0],
1173 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1174 fd_ptr->real_open_flags,
1175 fd_ptr->ref_count));
1176 if(fd_ptr->ref_count > 0) {
1177 fd_ptr->ref_count--;
1178 if(fd_ptr->ref_count == 0) {
1179 if(fd_ptr->fd != -1)
1180 close(fd_ptr->fd);
1181 if(fd_ptr->fd_readonly != -1)
1182 close(fd_ptr->fd_readonly);
1183 if(fd_ptr->fd_writeonly != -1)
1184 close(fd_ptr->fd_writeonly);
1185 fd_ptr->fd = -1;
1186 fd_ptr->fd_readonly = -1;
1187 fd_ptr->fd_writeonly = -1;
1188 fd_ptr->real_open_flags = -1;
1189 fd_ptr->dev = (uint32)-1;
1190 fd_ptr->inode = (uint32)-1;
1191 fd_ptr->uid_cache_count = 0;
1192 } else
1193 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1195 return fd_ptr->ref_count;
1198 /****************************************************************************
1199 fd support routines - check that current user has permissions
1200 to open this file. Used when uid not found in optimization cache.
1201 This is really ugly code, as due to POSIX locking braindamage we must
1202 fork and then attempt to open the file, and return success or failure
1203 via an exit code.
1204 ****************************************************************************/
1205 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
1207 pid_t child_pid;
1209 if((child_pid = fork()) < 0) {
1210 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
1211 return False;
1214 if(child_pid) {
1216 * Parent.
1218 pid_t wpid;
1219 int status_code;
1220 if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
1221 DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
1222 return(False);
1225 if (child_pid != wpid) {
1226 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
1227 return(False);
1229 #if defined(WIFEXITED) && defined(WEXITSTATUS)
1230 if (WIFEXITED(status_code) == 0) {
1231 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
1232 return(False);
1234 if (WEXITSTATUS(status_code) != 0) {
1235 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1236 return(False);
1238 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1239 if(status_code != 0) {
1240 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1241 return(False);
1243 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1246 * Success - the child could open the file.
1248 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
1249 return True;
1250 } else {
1252 * Child.
1254 int fd;
1255 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
1256 if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
1257 /* Access denied. */
1258 _exit(EACCES);
1260 close(fd);
1261 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
1262 _exit(0);
1265 return False;
1268 /****************************************************************************
1269 open a file
1270 ****************************************************************************/
1271 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1273 extern struct current_user current_user;
1274 pstring fname;
1275 struct stat statbuf;
1276 file_fd_struct *fd_ptr;
1277 files_struct *fsp = &Files[fnum];
1278 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1280 fsp->open = False;
1281 fsp->fd_ptr = 0;
1282 fsp->granted_oplock = False;
1283 errno = EPERM;
1285 pstrcpy(fname,fname1);
1287 /* check permissions */
1290 * This code was changed after seeing a client open request
1291 * containing the open mode of (DENY_WRITE/read-only) with
1292 * the 'create if not exist' bit set. The previous code
1293 * would fail to open the file read only on a read-only share
1294 * as it was checking the flags parameter directly against O_RDONLY,
1295 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1296 * JRA.
1299 if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1300 /* It's a read-only share - fail if we wanted to write. */
1301 if(accmode != O_RDONLY) {
1302 DEBUG(3,("Permission denied opening %s\n",fname));
1303 check_for_pipe(fname);
1304 return;
1306 else if(flags & O_CREAT) {
1307 /* We don't want to write - but we must make sure that O_CREAT
1308 doesn't create the file if we have write access into the
1309 directory.
1311 flags &= ~O_CREAT;
1315 /* this handles a bug in Win95 - it doesn't say to create the file when it
1316 should */
1317 if (Connections[cnum].printer)
1318 flags |= O_CREAT;
1321 if (flags == O_WRONLY)
1322 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1326 * Ensure we have a valid struct stat so we can search the
1327 * open fd table.
1329 if(sbuf == 0) {
1330 if(sys_stat(fname, &statbuf) < 0) {
1331 if(errno != ENOENT) {
1332 DEBUG(3,("Error doing stat on file %s (%s)\n",
1333 fname,strerror(errno)));
1335 check_for_pipe(fname);
1336 return;
1338 sbuf = 0;
1339 } else {
1340 sbuf = &statbuf;
1345 * Check to see if we have this file already
1346 * open. If we do, just use the already open fd and increment the
1347 * reference count (fd_get_already_open increments the ref_count).
1349 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1351 * File was already open.
1355 * Check it wasn't open for exclusive use.
1357 if((flags & O_CREAT) && (flags & O_EXCL)) {
1358 fd_ptr->ref_count--;
1359 errno = EEXIST;
1360 return;
1364 * Ensure that the user attempting to open
1365 * this file has permissions to do so, if
1366 * the user who originally opened the file wasn't
1367 * the same as the current user.
1370 if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
1371 if(!check_access_allowed_for_current_user( fname, accmode )) {
1372 /* Error - permission denied. */
1373 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
1374 fname, flags, accmode));
1375 /* Ensure the ref_count is decremented. */
1376 fd_ptr->ref_count--;
1377 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1378 errno = EACCES;
1379 return;
1383 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
1386 * If not opened O_RDWR try
1387 * and do that here - a chmod may have been done
1388 * between the last open and now.
1390 if(fd_ptr->real_open_flags != O_RDWR)
1391 fd_attempt_reopen(fname, mode, fd_ptr);
1394 * Ensure that if we wanted write access
1395 * it has been opened for write, and if we wanted read it
1396 * was open for read.
1398 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1399 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1400 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1401 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1402 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1403 check_for_pipe(fname);
1404 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1405 fd_ptr->ref_count--;
1406 return;
1409 } else {
1410 int open_flags;
1411 /* We need to allocate a new file_fd_struct (this increments the
1412 ref_count). */
1413 if((fd_ptr = fd_get_new()) == 0)
1414 return;
1416 * Whatever the requested flags, attempt read/write access,
1417 * as we don't know what flags future file opens may require.
1418 * If this fails, try again with the required flags.
1419 * Even if we open read/write when only read access was
1420 * requested the setting of the can_write flag in
1421 * the file_struct will protect us from errant
1422 * write requests. We never need to worry about O_APPEND
1423 * as this is not set anywhere in Samba.
1425 fd_ptr->real_open_flags = O_RDWR;
1426 /* Set the flags as needed without the read/write modes. */
1427 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1428 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1430 * On some systems opening a file for R/W access on a read only
1431 * filesystems sets errno to EROFS.
1433 #ifdef EROFS
1434 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1435 #else /* No EROFS */
1436 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1437 #endif /* EROFS */
1438 if(flags & O_WRONLY) {
1439 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1440 fd_ptr->real_open_flags = O_WRONLY;
1441 } else {
1442 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1443 fd_ptr->real_open_flags = O_RDONLY;
1448 if ((fd_ptr->fd >=0) &&
1449 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1450 pstring dname;
1451 int dum1,dum2,dum3;
1452 char *p;
1453 pstrcpy(dname,fname);
1454 p = strrchr(dname,'/');
1455 if (p) *p = 0;
1456 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1457 lp_minprintspace(SNUM(cnum))) {
1458 fd_attempt_close(fd_ptr);
1459 fsp->fd_ptr = 0;
1460 if(fd_ptr->ref_count == 0)
1461 sys_unlink(fname);
1462 errno = ENOSPC;
1463 return;
1467 if (fd_ptr->fd < 0)
1469 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1470 fname,strerror(errno),flags));
1471 /* Ensure the ref_count is decremented. */
1472 fd_attempt_close(fd_ptr);
1473 check_for_pipe(fname);
1474 return;
1477 if (fd_ptr->fd >= 0)
1479 if(sbuf == 0) {
1480 /* Do the fstat */
1481 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1482 /* Error - backout !! */
1483 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1484 fd_ptr->fd, fname,strerror(errno)));
1485 /* Ensure the ref_count is decremented. */
1486 fd_attempt_close(fd_ptr);
1487 return;
1489 sbuf = &statbuf;
1492 /* Set the correct entries in fd_ptr. */
1493 fd_ptr->dev = (uint32)sbuf->st_dev;
1494 fd_ptr->inode = (uint32)sbuf->st_ino;
1496 fsp->fd_ptr = fd_ptr;
1497 Connections[cnum].num_files_open++;
1498 fsp->mode = sbuf->st_mode;
1499 GetTimeOfDay(&fsp->open_time);
1500 fsp->vuid = current_user.vuid;
1501 fsp->size = 0;
1502 fsp->pos = -1;
1503 fsp->open = True;
1504 fsp->mmap_ptr = NULL;
1505 fsp->mmap_size = 0;
1506 fsp->can_lock = True;
1507 fsp->can_read = ((flags & O_WRONLY)==0);
1508 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1509 fsp->share_mode = 0;
1510 fsp->print_file = Connections[cnum].printer;
1511 fsp->modified = False;
1512 fsp->granted_oplock = False;
1513 fsp->sent_oplock_break = False;
1514 fsp->cnum = cnum;
1516 * Note that the file name here is the *untranslated* name
1517 * ie. it is still in the DOS codepage sent from the client.
1518 * All use of this filename will pass though the sys_xxxx
1519 * functions which will do the dos_to_unix translation before
1520 * mapping into a UNIX filename. JRA.
1522 string_set(&fsp->name,fname);
1523 fsp->wbmpx_ptr = NULL;
1526 * If the printer is marked as postscript output a leading
1527 * file identifier to ensure the file is treated as a raw
1528 * postscript file.
1529 * This has a similar effect as CtrlD=0 in WIN.INI file.
1530 * tim@fsg.com 09/06/94
1532 if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write)
1534 DEBUG(3,("Writing postscript line\n"));
1535 write_file(fnum,"%!\n",3);
1538 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1539 timestring(),
1540 *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname,
1541 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1542 Connections[cnum].num_files_open,fnum));
1546 #if USE_MMAP
1547 /* mmap it if read-only */
1548 if (!fsp->can_write)
1550 fsp->mmap_size = file_size(fname);
1551 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1552 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1554 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1556 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1557 fsp->mmap_ptr = NULL;
1560 #endif
1563 /*******************************************************************
1564 sync a file
1565 ********************************************************************/
1566 void sync_file(int fnum)
1568 #ifndef NO_FSYNC
1569 fsync(Files[fnum].fd_ptr->fd);
1570 #endif
1573 /****************************************************************************
1574 run a file if it is a magic script
1575 ****************************************************************************/
1576 static void check_magic(int fnum,int cnum)
1578 if (!*lp_magicscript(SNUM(cnum)))
1579 return;
1581 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1584 char *p;
1585 if (!(p = strrchr(Files[fnum].name,'/')))
1586 p = Files[fnum].name;
1587 else
1588 p++;
1590 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1591 return;
1595 int ret;
1596 pstring magic_output;
1597 pstring fname;
1598 pstrcpy(fname,Files[fnum].name);
1600 if (*lp_magicoutput(SNUM(cnum)))
1601 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1602 else
1603 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
1605 chmod(fname,0755);
1606 ret = smbrun(fname,magic_output,False);
1607 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1608 unlink(fname);
1613 /****************************************************************************
1614 close a file - possibly invalidating the read prediction
1616 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1617 operation otherwise it came as the result of some other operation such as
1618 the closing of the connection. In the latter case printing and
1619 magic scripts are not run
1620 ****************************************************************************/
1621 void close_file(int fnum, BOOL normal_close)
1623 files_struct *fs_p = &Files[fnum];
1624 int cnum = fs_p->cnum;
1625 uint32 dev = fs_p->fd_ptr->dev;
1626 uint32 inode = fs_p->fd_ptr->inode;
1627 int token;
1629 Files[fnum].reserved = False;
1631 #if USE_READ_PREDICTION
1632 invalidate_read_prediction(fs_p->fd_ptr->fd);
1633 #endif
1635 fs_p->open = False;
1636 Connections[cnum].num_files_open--;
1637 if(fs_p->wbmpx_ptr)
1639 free((char *)fs_p->wbmpx_ptr);
1640 fs_p->wbmpx_ptr = NULL;
1643 #if USE_MMAP
1644 if(fs_p->mmap_ptr)
1646 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1647 fs_p->mmap_ptr = NULL;
1649 #endif
1651 if (lp_share_modes(SNUM(cnum)))
1653 lock_share_entry( cnum, dev, inode, &token);
1654 del_share_mode(token, fnum);
1657 fd_attempt_close(fs_p->fd_ptr);
1659 if (lp_share_modes(SNUM(cnum)))
1660 unlock_share_entry( cnum, dev, inode, token);
1662 /* NT uses smbclose to start a print - weird */
1663 if (normal_close && fs_p->print_file)
1664 print_file(fnum);
1666 /* check for magic scripts */
1667 if (normal_close)
1668 check_magic(fnum,cnum);
1670 if(fs_p->granted_oplock == True)
1671 global_oplocks_open--;
1673 fs_p->sent_oplock_break = False;
1675 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1676 timestring(),Connections[cnum].user,fs_p->name,
1677 Connections[cnum].num_files_open));
1679 if (fs_p->name) {
1680 string_free(&fs_p->name);
1683 /* we will catch bugs faster by zeroing this structure */
1684 memset(fs_p, 0, sizeof(*fs_p));
1687 enum {AFAIL,AREAD,AWRITE,AALL};
1689 /*******************************************************************
1690 reproduce the share mode access table
1691 ********************************************************************/
1692 static int access_table(int new_deny,int old_deny,int old_mode,
1693 int share_pid,char *fname)
1695 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1697 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1698 int pid = getpid();
1699 if (old_deny == new_deny && share_pid == pid)
1700 return(AALL);
1702 if (old_mode == 0) return(AREAD);
1704 /* the new smbpub.zip spec says that if the file extension is
1705 .com, .dll, .exe or .sym then allow the open. I will force
1706 it to read-only as this seems sensible although the spec is
1707 a little unclear on this. */
1708 if ((fname = strrchr(fname,'.'))) {
1709 if (strequal(fname,".com") ||
1710 strequal(fname,".dll") ||
1711 strequal(fname,".exe") ||
1712 strequal(fname,".sym"))
1713 return(AREAD);
1716 return(AFAIL);
1719 switch (new_deny)
1721 case DENY_WRITE:
1722 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1723 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1724 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1725 return(AFAIL);
1726 case DENY_READ:
1727 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1728 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1729 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1730 return(AFAIL);
1731 case DENY_NONE:
1732 if (old_deny==DENY_WRITE) return(AREAD);
1733 if (old_deny==DENY_READ) return(AWRITE);
1734 if (old_deny==DENY_NONE) return(AALL);
1735 return(AFAIL);
1737 return(AFAIL);
1740 /*******************************************************************
1741 check if the share mode on a file allows it to be deleted or unlinked
1742 return True if sharing doesn't prevent the operation
1743 ********************************************************************/
1744 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1746 int i;
1747 int ret = False;
1748 share_mode_entry *old_shares = 0;
1749 int num_share_modes;
1750 struct stat sbuf;
1751 int token;
1752 int pid = getpid();
1753 uint32 dev, inode;
1755 if(!lp_share_modes(SNUM(cnum)))
1756 return True;
1758 if (sys_stat(fname,&sbuf) == -1) return(True);
1760 dev = (uint32)sbuf.st_dev;
1761 inode = (uint32)sbuf.st_ino;
1763 lock_share_entry(cnum, dev, inode, &token);
1764 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1767 * Check if the share modes will give us access.
1770 if(num_share_modes != 0)
1772 BOOL broke_oplock;
1777 broke_oplock = False;
1778 for(i = 0; i < num_share_modes; i++)
1780 share_mode_entry *share_entry = &old_shares[i];
1783 * Break oplocks before checking share modes. See comment in
1784 * open_file_shared for details.
1785 * Check if someone has an oplock on this file. If so we must
1786 * break it before continuing.
1788 if(share_entry->op_type & BATCH_OPLOCK)
1792 * It appears that the NT redirector may have a bug, in that
1793 * it tries to do an SMBmv on a file that it has open with a
1794 * batch oplock, and then fails to respond to the oplock break
1795 * request. This only seems to occur when the client is doing an
1796 * SMBmv to the smbd it is using - thus we try and detect this
1797 * condition by checking if the file being moved is open and oplocked by
1798 * this smbd process, and then not sending the oplock break in this
1799 * special case. If the file was open with a deny mode that
1800 * prevents the move the SMBmv will fail anyway with a share
1801 * violation error. JRA.
1803 if(rename_op && (share_entry->pid == pid))
1805 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1806 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1808 * This next line is a test that allows the deny-mode
1809 * processing to be skipped. This seems to be needed as
1810 * NT insists on the rename succeeding (in Office 9x no less !).
1811 * This should be removed as soon as (a) MS fix the redirector
1812 * bug or (b) NT SMB support in Samba makes NT not issue the
1813 * call (as is my fervent hope). JRA.
1815 continue;
1817 else
1819 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1820 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1822 /* Oplock break.... */
1823 unlock_share_entry(cnum, dev, inode, token);
1824 if(request_oplock_break(share_entry, dev, inode) == False)
1826 free((char *)old_shares);
1827 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1828 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1829 return False;
1831 lock_share_entry(cnum, dev, inode, &token);
1832 broke_oplock = True;
1833 break;
1837 /* someone else has a share lock on it, check to see
1838 if we can too */
1839 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1840 goto free_and_exit;
1842 } /* end for */
1844 if(broke_oplock)
1846 free((char *)old_shares);
1847 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1849 } while(broke_oplock);
1852 /* XXXX exactly what share mode combinations should be allowed for
1853 deleting/renaming? */
1854 /* If we got here then either there were no share modes or
1855 all share modes were DENY_DOS and the pid == getpid() */
1856 ret = True;
1858 free_and_exit:
1860 unlock_share_entry(cnum, dev, inode, token);
1861 if(old_shares != NULL)
1862 free((char *)old_shares);
1863 return(ret);
1866 /****************************************************************************
1867 C. Hoch 11/22/95
1868 Helper for open_file_shared.
1869 Truncate a file after checking locking; close file if locked.
1870 **************************************************************************/
1871 static void truncate_unless_locked(int fnum, int cnum, int token,
1872 BOOL *share_locked)
1874 if (Files[fnum].can_write){
1875 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1876 /* If share modes are in force for this connection we
1877 have the share entry locked. Unlock it before closing. */
1878 if (*share_locked && lp_share_modes(SNUM(cnum)))
1879 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1880 Files[fnum].fd_ptr->inode, token);
1881 close_file(fnum,False);
1882 /* Share mode no longer locked. */
1883 *share_locked = False;
1884 errno = EACCES;
1885 unix_ERR_class = ERRDOS;
1886 unix_ERR_code = ERRlock;
1888 else
1889 ftruncate(Files[fnum].fd_ptr->fd,0);
1893 /****************************************************************************
1894 check if we can open a file with a share mode
1895 ****************************************************************************/
1896 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1897 BOOL fcbopen, int *flags)
1899 int old_open_mode = share->share_mode &0xF;
1900 int old_deny_mode = (share->share_mode >>4)&7;
1902 if (old_deny_mode > 4 || old_open_mode > 2)
1904 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1905 deny_mode,old_deny_mode,old_open_mode,fname));
1906 return False;
1910 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1911 share->pid,fname);
1913 if ((access_allowed == AFAIL) ||
1914 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1915 (access_allowed == AREAD && *flags == O_WRONLY) ||
1916 (access_allowed == AWRITE && *flags == O_RDONLY))
1918 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1919 deny_mode,old_deny_mode,old_open_mode,
1920 share->pid,fname, fcbopen, *flags, access_allowed));
1921 return False;
1924 if (access_allowed == AREAD)
1925 *flags = O_RDONLY;
1927 if (access_allowed == AWRITE)
1928 *flags = O_WRONLY;
1931 return True;
1934 /****************************************************************************
1935 open a file with a share mode
1936 ****************************************************************************/
1937 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1938 int mode,int oplock_request, int *Access,int *action)
1940 files_struct *fs_p = &Files[fnum];
1941 int flags=0;
1942 int flags2=0;
1943 int deny_mode = (share_mode>>4)&7;
1944 struct stat sbuf;
1945 BOOL file_existed = file_exist(fname,&sbuf);
1946 BOOL share_locked = False;
1947 BOOL fcbopen = False;
1948 int token;
1949 uint32 dev = 0;
1950 uint32 inode = 0;
1951 int num_share_modes = 0;
1953 fs_p->open = False;
1954 fs_p->fd_ptr = 0;
1956 /* this is for OS/2 EAs - try and say we don't support them */
1957 if (strstr(fname,".+,;=[]."))
1959 unix_ERR_class = ERRDOS;
1960 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1961 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1962 unix_ERR_code = ERRcannotopen;
1963 #else /* OS2_WPS_FIX */
1964 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1965 #endif /* OS2_WPS_FIX */
1967 return;
1970 if ((ofun & 0x3) == 0 && file_existed)
1972 errno = EEXIST;
1973 return;
1976 if (ofun & 0x10)
1977 flags2 |= O_CREAT;
1978 if ((ofun & 0x3) == 2)
1979 flags2 |= O_TRUNC;
1981 /* note that we ignore the append flag as
1982 append does not mean the same thing under dos and unix */
1984 switch (share_mode&0xF)
1986 case 1:
1987 flags = O_WRONLY;
1988 break;
1989 case 0xF:
1990 fcbopen = True;
1991 flags = O_RDWR;
1992 break;
1993 case 2:
1994 flags = O_RDWR;
1995 break;
1996 default:
1997 flags = O_RDONLY;
1998 break;
2001 #if defined(O_SYNC)
2002 if (share_mode&(1<<14)) {
2003 flags2 |= O_SYNC;
2005 #endif /* O_SYNC */
2007 if (flags != O_RDONLY && file_existed &&
2008 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
2010 if (!fcbopen)
2012 errno = EACCES;
2013 return;
2015 flags = O_RDONLY;
2018 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
2020 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
2021 errno = EINVAL;
2022 return;
2025 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
2027 if (lp_share_modes(SNUM(cnum)))
2029 int i;
2030 share_mode_entry *old_shares = 0;
2032 if (file_existed)
2034 dev = (uint32)sbuf.st_dev;
2035 inode = (uint32)sbuf.st_ino;
2036 lock_share_entry(cnum, dev, inode, &token);
2037 share_locked = True;
2038 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
2042 * Check if the share modes will give us access.
2045 if(share_locked && (num_share_modes != 0))
2047 BOOL broke_oplock;
2052 broke_oplock = False;
2053 for(i = 0; i < num_share_modes; i++)
2055 share_mode_entry *share_entry = &old_shares[i];
2058 * By observation of NetBench, oplocks are broken *before* share
2059 * modes are checked. This allows a file to be closed by the client
2060 * if the share mode would deny access and the client has an oplock.
2061 * Check if someone has an oplock on this file. If so we must break
2062 * it before continuing.
2064 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
2067 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
2068 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
2070 /* Oplock break.... */
2071 unlock_share_entry(cnum, dev, inode, token);
2072 if(request_oplock_break(share_entry, dev, inode) == False)
2074 free((char *)old_shares);
2075 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
2076 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
2077 errno = EACCES;
2078 unix_ERR_class = ERRDOS;
2079 unix_ERR_code = ERRbadshare;
2080 return;
2082 lock_share_entry(cnum, dev, inode, &token);
2083 broke_oplock = True;
2084 break;
2087 /* someone else has a share lock on it, check to see
2088 if we can too */
2089 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
2091 free((char *)old_shares);
2092 unlock_share_entry(cnum, dev, inode, token);
2093 errno = EACCES;
2094 unix_ERR_class = ERRDOS;
2095 unix_ERR_code = ERRbadshare;
2096 return;
2099 } /* end for */
2101 if(broke_oplock)
2103 free((char *)old_shares);
2104 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
2106 } while(broke_oplock);
2109 if(old_shares != 0)
2110 free((char *)old_shares);
2113 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
2114 flags,flags2,mode));
2116 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
2117 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
2119 flags = O_RDONLY;
2120 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
2123 if (fs_p->open)
2125 int open_mode=0;
2127 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
2129 /* We created the file - thus we must now lock the share entry before creating it. */
2130 dev = fs_p->fd_ptr->dev;
2131 inode = fs_p->fd_ptr->inode;
2132 lock_share_entry(cnum, dev, inode, &token);
2133 share_locked = True;
2136 switch (flags)
2138 case O_RDONLY:
2139 open_mode = 0;
2140 break;
2141 case O_RDWR:
2142 open_mode = 2;
2143 break;
2144 case O_WRONLY:
2145 open_mode = 1;
2146 break;
2149 fs_p->share_mode = (deny_mode<<4) | open_mode;
2151 if (Access)
2152 (*Access) = open_mode;
2154 if (action)
2156 if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
2157 if (!file_existed) *action = FILE_WAS_CREATED;
2158 if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
2160 /* We must create the share mode entry before truncate as
2161 truncate can fail due to locking and have to close the
2162 file (which expects the share_mode_entry to be there).
2164 if (lp_share_modes(SNUM(cnum)))
2166 uint16 port = 0;
2167 /* JRA. Currently this only services Exlcusive and batch
2168 oplocks (no other opens on this file). This needs to
2169 be extended to level II oplocks (multiple reader
2170 oplocks). */
2172 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
2173 !IS_VETO_OPLOCK_PATH(cnum,fname))
2175 fs_p->granted_oplock = True;
2176 fs_p->sent_oplock_break = False;
2177 global_oplocks_open++;
2178 port = oplock_port;
2180 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2181 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2184 else
2186 port = 0;
2187 oplock_request = 0;
2189 set_share_mode(token, fnum, port, oplock_request);
2192 if ((flags2&O_TRUNC) && file_existed)
2193 truncate_unless_locked(fnum,cnum,token,&share_locked);
2196 if (share_locked && lp_share_modes(SNUM(cnum)))
2197 unlock_share_entry( cnum, dev, inode, token);
2200 /****************************************************************************
2201 seek a file. Try to avoid the seek if possible
2202 ****************************************************************************/
2203 int seek_file(int fnum,uint32 pos)
2205 uint32 offset = 0;
2206 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2207 offset = 3;
2209 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
2210 - offset);
2211 return(Files[fnum].pos);
2214 /****************************************************************************
2215 read from a file
2216 ****************************************************************************/
2217 int read_file(int fnum,char *data,uint32 pos,int n)
2219 int ret=0,readret;
2221 #if USE_READ_PREDICTION
2222 if (!Files[fnum].can_write)
2224 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2226 data += ret;
2227 n -= ret;
2228 pos += ret;
2230 #endif
2232 #if USE_MMAP
2233 if (Files[fnum].mmap_ptr)
2235 int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2236 num = MIN(n,num);
2237 if (num > 0)
2239 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2240 data += num;
2241 pos += num;
2242 n -= num;
2243 ret += num;
2246 #endif
2248 if (n <= 0)
2249 return(ret);
2251 if (seek_file(fnum,pos) != pos)
2253 DEBUG(3,("Failed to seek to %d\n",pos));
2254 return(ret);
2257 if (n > 0) {
2258 readret = read(Files[fnum].fd_ptr->fd,data,n);
2259 if (readret > 0) ret += readret;
2262 return(ret);
2266 /****************************************************************************
2267 write to a file
2268 ****************************************************************************/
2269 int write_file(int fnum,char *data,int n)
2271 if (!Files[fnum].can_write) {
2272 errno = EPERM;
2273 return(0);
2276 if (!Files[fnum].modified) {
2277 struct stat st;
2278 Files[fnum].modified = True;
2279 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2280 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2281 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2282 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2287 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2291 /****************************************************************************
2292 load parameters specific to a connection/service
2293 ****************************************************************************/
2294 BOOL become_service(int cnum,BOOL do_chdir)
2296 extern char magic_char;
2297 static int last_cnum = -1;
2298 int snum;
2300 if (!OPEN_CNUM(cnum))
2302 last_cnum = -1;
2303 return(False);
2306 Connections[cnum].lastused = smb_last_time;
2308 snum = SNUM(cnum);
2310 if (do_chdir &&
2311 ChDir(Connections[cnum].connectpath) != 0 &&
2312 ChDir(Connections[cnum].origpath) != 0)
2314 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2315 Connections[cnum].connectpath,cnum));
2316 return(False);
2319 if (cnum == last_cnum)
2320 return(True);
2322 last_cnum = cnum;
2324 case_default = lp_defaultcase(snum);
2325 case_preserve = lp_preservecase(snum);
2326 short_case_preserve = lp_shortpreservecase(snum);
2327 case_mangle = lp_casemangle(snum);
2328 case_sensitive = lp_casesensitive(snum);
2329 magic_char = lp_magicchar(snum);
2330 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2331 return(True);
2335 /****************************************************************************
2336 find a service entry
2337 ****************************************************************************/
2338 int find_service(char *service)
2340 int iService;
2342 string_sub(service,"\\","/");
2344 iService = lp_servicenumber(service);
2346 /* now handle the special case of a home directory */
2347 if (iService < 0)
2349 char *phome_dir = get_home_dir(service);
2351 if(!phome_dir)
2354 * Try mapping the servicename, it may
2355 * be a Windows to unix mapped user name.
2357 if(map_username(service))
2358 phome_dir = get_home_dir(service);
2361 DEBUG(3,("checking for home directory %s gave %s\n",service,
2362 phome_dir?phome_dir:"(NULL)"));
2364 if (phome_dir)
2366 int iHomeService;
2367 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2369 lp_add_home(service,iHomeService,phome_dir);
2370 iService = lp_servicenumber(service);
2375 /* If we still don't have a service, attempt to add it as a printer. */
2376 if (iService < 0)
2378 int iPrinterService;
2380 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2382 char *pszTemp;
2384 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2385 pszTemp = PRINTCAP;
2386 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2388 DEBUG(3,("%s is a valid printer name\n", service));
2389 DEBUG(3,("adding %s as a printer service\n", service));
2390 lp_add_printer(service,iPrinterService);
2391 iService = lp_servicenumber(service);
2392 if (iService < 0)
2393 DEBUG(0,("failed to add %s as a printer service!\n", service));
2395 else
2396 DEBUG(3,("%s is not a valid printer name\n", service));
2400 /* just possibly it's a default service? */
2401 if (iService < 0)
2403 char *pdefservice = lp_defaultservice();
2404 if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2407 * We need to do a local copy here as lp_defaultservice()
2408 * returns one of the rotating lp_string buffers that
2409 * could get overwritten by the recursive find_service() call
2410 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2412 pstring defservice;
2413 pstrcpy(defservice, pdefservice);
2414 iService = find_service(defservice);
2415 if (iService >= 0)
2417 string_sub(service,"_","/");
2418 iService = lp_add_service(service,iService);
2423 if (iService >= 0)
2424 if (!VALID_SNUM(iService))
2426 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2427 iService = -1;
2430 if (iService < 0)
2431 DEBUG(3,("find_service() failed to find service %s\n", service));
2433 return (iService);
2437 /****************************************************************************
2438 create an error packet from a cached error.
2439 ****************************************************************************/
2440 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2442 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2444 int32 eclass = wbmpx->wr_errclass;
2445 int32 err = wbmpx->wr_error;
2447 /* We can now delete the auxiliary struct */
2448 free((char *)wbmpx);
2449 Files[fnum].wbmpx_ptr = NULL;
2450 return error_packet(inbuf,outbuf,eclass,err,line);
2454 struct
2456 int unixerror;
2457 int smbclass;
2458 int smbcode;
2459 } unix_smb_errmap[] =
2461 {EPERM,ERRDOS,ERRnoaccess},
2462 {EACCES,ERRDOS,ERRnoaccess},
2463 {ENOENT,ERRDOS,ERRbadfile},
2464 {ENOTDIR,ERRDOS,ERRbadpath},
2465 {EIO,ERRHRD,ERRgeneral},
2466 {EBADF,ERRSRV,ERRsrverror},
2467 {EINVAL,ERRSRV,ERRsrverror},
2468 {EEXIST,ERRDOS,ERRfilexists},
2469 {ENFILE,ERRDOS,ERRnofids},
2470 {EMFILE,ERRDOS,ERRnofids},
2471 {ENOSPC,ERRHRD,ERRdiskfull},
2472 #ifdef EDQUOT
2473 {EDQUOT,ERRHRD,ERRdiskfull},
2474 #endif
2475 #ifdef ENOTEMPTY
2476 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2477 #endif
2478 #ifdef EXDEV
2479 {EXDEV,ERRDOS,ERRdiffdevice},
2480 #endif
2481 {EROFS,ERRHRD,ERRnowrite},
2482 {0,0,0}
2485 /****************************************************************************
2486 create an error packet from errno
2487 ****************************************************************************/
2488 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2490 int eclass=def_class;
2491 int ecode=def_code;
2492 int i=0;
2494 if (unix_ERR_class != SMB_SUCCESS)
2496 eclass = unix_ERR_class;
2497 ecode = unix_ERR_code;
2498 unix_ERR_class = SMB_SUCCESS;
2499 unix_ERR_code = 0;
2501 else
2503 while (unix_smb_errmap[i].smbclass != 0)
2505 if (unix_smb_errmap[i].unixerror == errno)
2507 eclass = unix_smb_errmap[i].smbclass;
2508 ecode = unix_smb_errmap[i].smbcode;
2509 break;
2511 i++;
2515 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2519 /****************************************************************************
2520 create an error packet. Normally called using the ERROR() macro
2521 ****************************************************************************/
2522 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2524 int outsize = set_message(outbuf,0,0,True);
2525 int cmd = CVAL(inbuf,smb_com);
2526 int flgs2 = SVAL(outbuf,smb_flg2);
2528 if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2530 SIVAL(outbuf,smb_rcls,error_code);
2532 DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2533 timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2535 else
2537 CVAL(outbuf,smb_rcls) = error_class;
2538 SSVAL(outbuf,smb_err,error_code);
2539 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2540 timestring(),
2541 line,
2542 (int)CVAL(inbuf,smb_com),
2543 smb_fn_name(CVAL(inbuf,smb_com)),
2544 error_class,
2545 error_code));
2549 if (errno != 0)
2550 DEBUG(3,("error string = %s\n",strerror(errno)));
2552 return(outsize);
2556 #ifndef SIGCLD_IGNORE
2557 /****************************************************************************
2558 this prevents zombie child processes
2559 ****************************************************************************/
2560 static int sig_cld(void)
2562 static int depth = 0;
2563 if (depth != 0)
2565 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2566 depth=0;
2567 return(0);
2569 depth++;
2571 BlockSignals(True,SIGCLD);
2572 DEBUG(5,("got SIGCLD\n"));
2574 #ifdef USE_WAITPID
2575 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2576 #endif
2578 /* Stop zombies */
2579 /* Stevens, Adv. Unix Prog. says that on system V you must call
2580 wait before reinstalling the signal handler, because the kernel
2581 calls the handler from within the signal-call when there is a
2582 child that has exited. This would lead to an infinite recursion
2583 if done vice versa. */
2585 #ifndef DONT_REINSTALL_SIG
2586 #ifdef SIGCLD_IGNORE
2587 signal(SIGCLD, SIG_IGN);
2588 #else
2589 signal(SIGCLD, SIGNAL_CAST sig_cld);
2590 #endif
2591 #endif
2593 #ifndef USE_WAITPID
2594 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2595 #endif
2596 depth--;
2597 BlockSignals(False,SIGCLD);
2598 return 0;
2600 #endif
2602 /****************************************************************************
2603 this is called when the client exits abruptly
2604 **************************************************************************/
2605 static int sig_pipe(void)
2607 struct cli_state *cli;
2608 BlockSignals(True,SIGPIPE);
2610 if ((cli = server_client()) && cli->initialised) {
2611 DEBUG(3,("lost connection to password server\n"));
2612 cli_shutdown(cli);
2613 #ifndef DONT_REINSTALL_SIG
2614 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2615 #endif
2616 BlockSignals(False,SIGPIPE);
2617 return 0;
2620 exit_server("Got sigpipe\n");
2621 return(0);
2624 /****************************************************************************
2625 open the socket communication
2626 ****************************************************************************/
2627 static BOOL open_sockets(BOOL is_daemon,int port)
2629 extern int Client;
2631 if (is_daemon)
2633 int num_interfaces = iface_count();
2634 int fd_listenset[FD_SETSIZE];
2635 fd_set listen_set;
2636 int s;
2637 int i;
2639 /* Stop zombies */
2640 #ifdef SIGCLD_IGNORE
2641 signal(SIGCLD, SIG_IGN);
2642 #else
2643 signal(SIGCLD, SIGNAL_CAST sig_cld);
2644 #endif
2646 if(atexit_set == 0)
2647 atexit(killkids);
2649 FD_ZERO(&listen_set);
2651 if(lp_interfaces() && lp_bind_interfaces_only())
2653 /* We have been given an interfaces line, and been
2654 told to only bind to those interfaces. Create a
2655 socket per interface and bind to only these.
2658 if(num_interfaces > FD_SETSIZE)
2660 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2661 max can be %d\n", num_interfaces, FD_SETSIZE));
2662 return False;
2665 /* Now open a listen socket for each of the interfaces. */
2666 for(i = 0; i < num_interfaces; i++)
2668 struct in_addr *ifip = iface_n_ip(i);
2670 if(ifip == NULL)
2672 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2673 continue;
2675 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2676 if(s == -1)
2677 return False;
2678 /* ready to listen */
2679 if (listen(s, 5) == -1)
2681 DEBUG(0,("listen: %s\n",strerror(errno)));
2682 close(s);
2683 return False;
2685 FD_SET(s,&listen_set);
2688 else
2690 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2691 num_interfaces = 1;
2693 /* open an incoming socket */
2694 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2695 if (s == -1)
2696 return(False);
2698 /* ready to listen */
2699 if (listen(s, 5) == -1)
2701 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2702 close(s);
2703 return False;
2706 fd_listenset[0] = s;
2707 FD_SET(s,&listen_set);
2710 /* now accept incoming connections - forking a new process
2711 for each incoming connection */
2712 DEBUG(2,("waiting for a connection\n"));
2713 while (1)
2715 fd_set lfds;
2716 int num;
2718 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2720 num = sys_select(&lfds,NULL);
2722 if (num == -1 && errno == EINTR)
2723 continue;
2725 /* Find the sockets that are read-ready - accept on these. */
2726 for( ; num > 0; num--)
2728 struct sockaddr addr;
2729 int in_addrlen = sizeof(addr);
2731 s = -1;
2732 for(i = 0; i < num_interfaces; i++)
2734 if(FD_ISSET(fd_listenset[i],&lfds))
2736 s = fd_listenset[i];
2737 /* Clear this so we don't look at it again. */
2738 FD_CLR(fd_listenset[i],&lfds);
2739 break;
2743 Client = accept(s,&addr,&in_addrlen);
2745 if (Client == -1 && errno == EINTR)
2746 continue;
2748 if (Client == -1)
2750 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2751 continue;
2754 #ifdef NO_FORK_DEBUG
2755 #ifndef NO_SIGNAL_TEST
2756 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2757 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2758 #endif /* NO_SIGNAL_TEST */
2759 return True;
2760 #else /* NO_FORK_DEBUG */
2761 if (Client != -1 && fork()==0)
2763 /* Child code ... */
2765 #ifndef NO_SIGNAL_TEST
2766 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2767 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2768 #endif /* NO_SIGNAL_TEST */
2769 /* close the listening socket(s) */
2770 for(i = 0; i < num_interfaces; i++)
2771 close(fd_listenset[i]);
2773 /* close our standard file descriptors */
2774 close_low_fds();
2775 am_parent = 0;
2777 set_socket_options(Client,"SO_KEEPALIVE");
2778 set_socket_options(Client,user_socket_options);
2780 /* Reset global variables in util.c so that
2781 client substitutions will be done correctly
2782 in the process.
2784 reset_globals_after_fork();
2785 return True;
2787 close(Client); /* The parent doesn't need this socket */
2788 #endif /* NO_FORK_DEBUG */
2789 } /* end for num */
2790 } /* end while 1 */
2791 } /* end if is_daemon */
2792 else
2794 /* Started from inetd. fd 0 is the socket. */
2795 /* We will abort gracefully when the client or remote system
2796 goes away */
2797 #ifndef NO_SIGNAL_TEST
2798 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2799 #endif
2800 Client = dup(0);
2802 /* close our standard file descriptors */
2803 close_low_fds();
2805 set_socket_options(Client,"SO_KEEPALIVE");
2806 set_socket_options(Client,user_socket_options);
2809 return True;
2812 /****************************************************************************
2813 process an smb from the client - split out from the process() code so
2814 it can be used by the oplock break code.
2815 ****************************************************************************/
2817 static void process_smb(char *inbuf, char *outbuf)
2819 extern int Client;
2820 #ifdef USE_SSL
2821 extern BOOL sslEnabled; /* don't use function for performance reasons */
2822 static int sslConnected = 0;
2823 #endif /* USE_SSL */
2824 static int trans_num;
2825 int msg_type = CVAL(inbuf,0);
2826 int32 len = smb_len(inbuf);
2827 int nread = len + 4;
2829 if (trans_num == 0) {
2830 /* on the first packet, check the global hosts allow/ hosts
2831 deny parameters before doing any parsing of the packet
2832 passed to us by the client. This prevents attacks on our
2833 parsing code from hosts not in the hosts allow list */
2834 if (!check_access(-1)) {
2835 /* send a negative session response "not listining on calling
2836 name" */
2837 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2838 DEBUG(1,("%s Connection denied from %s\n",
2839 timestring(),client_addr(Client)));
2840 send_smb(Client,(char *)buf);
2841 exit_server("connection denied");
2845 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2846 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2848 #ifdef USE_SSL
2849 if(sslEnabled && !sslConnected){
2850 sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2851 if(sslConnected < 0){ /* an error occured */
2852 exit_server("SSL negotiation failed");
2853 }else if(sslConnected){
2854 trans_num++;
2855 return;
2858 #endif /* USE_SSL */
2860 #ifdef WITH_VTP
2861 if(trans_num == 1 && VT_Check(inbuf))
2863 VT_Process();
2864 return;
2866 #endif
2868 if (msg_type == 0)
2869 show_msg(inbuf);
2870 else if(msg_type == 0x85)
2871 return; /* Keepalive packet. */
2873 nread = construct_reply(inbuf,outbuf,nread,max_send);
2875 if(nread > 0)
2877 if (CVAL(outbuf,0) == 0)
2878 show_msg(outbuf);
2880 if (nread != smb_len(outbuf) + 4)
2882 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2883 nread, smb_len(outbuf)));
2885 else
2886 send_smb(Client,outbuf);
2888 trans_num++;
2891 /****************************************************************************
2892 open the oplock IPC socket communication
2893 ****************************************************************************/
2894 static BOOL open_oplock_ipc(void)
2896 struct sockaddr_in sock_name;
2897 int len = sizeof(sock_name);
2899 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2901 /* Open a lookback UDP socket on a random port. */
2902 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2903 if (oplock_sock == -1)
2905 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2906 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2907 oplock_port = 0;
2908 return(False);
2911 /* Find out the transient UDP port we have been allocated. */
2912 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2914 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2915 strerror(errno)));
2916 close(oplock_sock);
2917 oplock_sock = -1;
2918 oplock_port = 0;
2919 return False;
2921 oplock_port = ntohs(sock_name.sin_port);
2923 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2924 getpid(), oplock_port));
2926 return True;
2929 /****************************************************************************
2930 process an oplock break message.
2931 ****************************************************************************/
2932 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2934 int32 msg_len;
2935 uint16 from_port;
2936 char *msg_start;
2938 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2939 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2941 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2943 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2944 msg_len, from_port));
2946 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2947 only valid request. */
2949 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2951 case OPLOCK_BREAK_CMD:
2952 /* Ensure that the msg length is correct. */
2953 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2955 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2956 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2957 return False;
2960 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2961 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2962 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2963 struct timeval tval;
2964 struct sockaddr_in toaddr;
2966 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2967 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2969 DEBUG(5,("process_local_message: oplock break request from \
2970 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2973 * If we have no record of any currently open oplocks,
2974 * it's not an error, as a close command may have
2975 * just been issued on the file that was oplocked.
2976 * Just return success in this case.
2979 if(global_oplocks_open != 0)
2981 if(oplock_break(dev, inode, &tval) == False)
2983 DEBUG(0,("process_local_message: oplock break failed - \
2984 not returning udp message.\n"));
2985 return False;
2988 else
2990 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2991 oplocks. Returning success.\n"));
2994 /* Send the message back after OR'ing in the 'REPLY' bit. */
2995 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2997 bzero((char *)&toaddr,sizeof(toaddr));
2998 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2999 toaddr.sin_port = htons(from_port);
3000 toaddr.sin_family = AF_INET;
3002 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
3003 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
3005 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
3006 remotepid, strerror(errno)));
3007 return False;
3010 DEBUG(5,("process_local_message: oplock break reply sent to \
3011 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
3012 from_port, dev, inode));
3015 break;
3017 * Keep this as a debug case - eventually we can remove it.
3019 case 0x8001:
3020 DEBUG(0,("process_local_message: Received unsolicited break \
3021 reply - dumping info.\n"));
3023 if(msg_len != OPLOCK_BREAK_MSG_LEN)
3025 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
3026 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
3027 return False;
3031 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
3032 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
3033 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
3035 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
3036 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
3039 return False;
3041 default:
3042 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
3043 (unsigned int)SVAL(msg_start,0)));
3044 return False;
3046 return True;
3049 /****************************************************************************
3050 Process an oplock break directly.
3051 ****************************************************************************/
3052 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
3054 extern struct current_user current_user;
3055 extern int Client;
3056 char *inbuf = NULL;
3057 char *outbuf = NULL;
3058 files_struct *fsp = NULL;
3059 int fnum;
3060 time_t start_time;
3061 BOOL shutdown_server = False;
3062 int saved_cnum;
3063 int saved_vuid;
3064 pstring saved_dir;
3066 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
3067 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
3069 /* We need to search the file open table for the
3070 entry containing this dev and inode, and ensure
3071 we have an oplock on it. */
3072 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
3074 if(OPEN_FNUM(fnum))
3076 if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
3077 (Files[fnum].open_time.tv_sec == tval->tv_sec) &&
3078 (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
3079 fsp = &Files[fnum];
3080 break;
3085 if(fsp == NULL)
3087 /* The file could have been closed in the meantime - return success. */
3088 DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
3089 allowing break to succeed.\n", timestring(), dev, inode, fnum));
3090 return True;
3093 /* Ensure we have an oplock on the file */
3095 /* There is a potential race condition in that an oplock could
3096 have been broken due to another udp request, and yet there are
3097 still oplock break messages being sent in the udp message
3098 queue for this file. So return true if we don't have an oplock,
3099 as we may have just freed it.
3102 if(!fsp->granted_oplock)
3104 DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
3105 return True;
3108 /* mark the oplock break as sent - we don't want to send twice! */
3109 if (fsp->sent_oplock_break)
3111 DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
3113 /* We have to fail the open here as we cannot send another oplock break on this
3114 file whilst we are awaiting a response from the client - neither can we
3115 allow another open to succeed while we are waiting for the client. */
3116 return False;
3119 /* Now comes the horrid part. We must send an oplock break to the client,
3120 and then process incoming messages until we get a close or oplock release.
3121 At this point we know we need a new inbuf/outbuf buffer pair.
3122 We cannot use these staticaly as we may recurse into here due to
3123 messages crossing on the wire.
3126 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3128 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
3129 return False;
3132 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3134 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
3135 free(inbuf);
3136 inbuf = NULL;
3137 return False;
3140 /* Prepare the SMBlockingX message. */
3141 bzero(outbuf,smb_size);
3142 set_message(outbuf,8,0,True);
3144 SCVAL(outbuf,smb_com,SMBlockingX);
3145 SSVAL(outbuf,smb_tid,fsp->cnum);
3146 SSVAL(outbuf,smb_pid,0xFFFF);
3147 SSVAL(outbuf,smb_uid,0);
3148 SSVAL(outbuf,smb_mid,0xFFFF);
3149 SCVAL(outbuf,smb_vwv0,0xFF);
3150 SSVAL(outbuf,smb_vwv2,fnum);
3151 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
3152 /* Change this when we have level II oplocks. */
3153 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
3155 send_smb(Client, outbuf);
3157 /* Remember we just sent an oplock break on this file. */
3158 fsp->sent_oplock_break = True;
3160 /* We need this in case a readraw crosses on the wire. */
3161 global_oplock_break = True;
3163 /* Process incoming messages. */
3165 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
3166 seconds we should just die.... */
3168 start_time = time(NULL);
3171 * Save the information we need to re-become the
3172 * user, then unbecome the user whilst we're doing this.
3174 saved_cnum = fsp->cnum;
3175 saved_vuid = current_user.vuid;
3176 GetWd(saved_dir);
3177 unbecome_user();
3179 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
3181 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
3184 * Die if we got an error.
3187 if (smb_read_error == READ_EOF)
3188 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
3190 if (smb_read_error == READ_ERROR)
3191 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
3192 timestring(), strerror(errno)));
3194 if (smb_read_error == READ_TIMEOUT)
3195 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
3196 timestring(), OPLOCK_BREAK_TIMEOUT));
3198 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3199 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3200 shutdown_server = True;
3201 break;
3205 * There are certain SMB requests that we shouldn't allow
3206 * to recurse. opens, renames and deletes are the obvious
3207 * ones. This is handled in the switch_message() function.
3208 * If global_oplock_break is set they will push the packet onto
3209 * the pending smb queue and return -1 (no reply).
3210 * JRA.
3213 process_smb(inbuf, outbuf);
3216 * Die if we go over the time limit.
3219 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3221 DEBUG(0,("%s oplock_break: no break received from client within \
3222 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3223 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3224 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3225 shutdown_server = True;
3226 break;
3231 * Go back to being the user who requested the oplock
3232 * break.
3234 if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3236 DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3237 timestring()));
3238 close_sockets();
3239 close(oplock_sock);
3240 exit_server("unable to re-become user");
3242 /* Including the directory. */
3243 ChDir(saved_dir);
3245 /* Free the buffers we've been using to recurse. */
3246 free(inbuf);
3247 free(outbuf);
3249 /* We need this in case a readraw crossed on the wire. */
3250 if(global_oplock_break)
3251 global_oplock_break = False;
3254 * If the client did not respond we must die.
3257 if(shutdown_server)
3259 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3260 timestring()));
3261 close_sockets();
3262 close(oplock_sock);
3263 exit_server("oplock break failure");
3266 if(OPEN_FNUM(fnum))
3268 /* The lockingX reply will have removed the oplock flag
3269 from the sharemode. */
3270 /* Paranoia.... */
3271 fsp->granted_oplock = False;
3272 fsp->sent_oplock_break = False;
3273 global_oplocks_open--;
3276 /* Santity check - remove this later. JRA */
3277 if(global_oplocks_open < 0)
3279 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3280 global_oplocks_open));
3281 exit_server("oplock_break: global_oplocks_open < 0");
3284 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3285 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3287 return True;
3290 /****************************************************************************
3291 Send an oplock break message to another smbd process. If the oplock is held
3292 by the local smbd then call the oplock break function directly.
3293 ****************************************************************************/
3295 BOOL request_oplock_break(share_mode_entry *share_entry,
3296 uint32 dev, uint32 inode)
3298 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3299 struct sockaddr_in addr_out;
3300 int pid = getpid();
3301 time_t start_time;
3302 int time_left;
3304 if(pid == share_entry->pid)
3306 /* We are breaking our own oplock, make sure it's us. */
3307 if(share_entry->op_port != oplock_port)
3309 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3310 should be %d\n", pid, share_entry->op_port, oplock_port));
3311 return False;
3314 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3316 /* Call oplock break direct. */
3317 return oplock_break(dev, inode, &share_entry->time);
3320 /* We need to send a OPLOCK_BREAK_CMD message to the
3321 port in the share mode entry. */
3323 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3324 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3325 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3326 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3327 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3328 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3330 /* set the address and port */
3331 bzero((char *)&addr_out,sizeof(addr_out));
3332 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3333 addr_out.sin_port = htons( share_entry->op_port );
3334 addr_out.sin_family = AF_INET;
3336 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3337 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3339 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3340 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3342 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3343 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3344 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3345 strerror(errno)));
3346 return False;
3350 * Now we must await the oplock broken message coming back
3351 * from the target smbd process. Timeout if it fails to
3352 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3353 * While we get messages that aren't ours, loop.
3356 start_time = time(NULL);
3357 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3359 while(time_left >= 0)
3361 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3362 int32 reply_msg_len;
3363 uint16 reply_from_port;
3364 char *reply_msg_start;
3366 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3367 time_left ? time_left * 1000 : 1) == False)
3369 if(smb_read_error == READ_TIMEOUT)
3371 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3372 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3373 share_entry->op_port, dev, inode));
3375 * This is a hack to make handling of failing clients more robust.
3376 * If a oplock break response message is not received in the timeout
3377 * period we may assume that the smbd servicing that client holding
3378 * the oplock has died and the client changes were lost anyway, so
3379 * we should continue to try and open the file.
3381 break;
3383 else
3384 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3385 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3386 share_entry->op_port, dev, inode, strerror(errno)));
3387 return False;
3390 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3391 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3393 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3395 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3397 /* Ignore it. */
3398 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3399 timestring()));
3400 continue;
3404 * Test to see if this is the reply we are awaiting.
3407 if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3408 (reply_from_port == share_entry->op_port) &&
3409 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3410 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3411 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3414 * This is the reply we've been waiting for.
3416 break;
3418 else
3421 * This is another message - probably a break request.
3422 * Process it to prevent potential deadlock.
3423 * Note that the code in switch_message() prevents
3424 * us from recursing into here as any SMB requests
3425 * we might process that would cause another oplock
3426 * break request to be made will be queued.
3427 * JRA.
3430 process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3433 time_left -= (time(NULL) - start_time);
3436 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3438 return True;
3441 /****************************************************************************
3442 Get the next SMB packet, doing the local message processing automatically.
3443 ****************************************************************************/
3445 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3447 BOOL got_smb = False;
3448 BOOL ret;
3452 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3453 timeout,&got_smb);
3455 if(ret && !got_smb)
3457 /* Deal with oplock break requests from other smbd's. */
3458 process_local_message(oplock_sock, inbuf, bufsize);
3459 continue;
3462 if(ret && (CVAL(inbuf,0) == 0x85))
3464 /* Keepalive packet. */
3465 got_smb = False;
3469 while(ret && !got_smb);
3471 return ret;
3474 /****************************************************************************
3475 check if a snum is in use
3476 ****************************************************************************/
3477 BOOL snum_used(int snum)
3479 int i;
3480 for (i=0;i<MAX_CONNECTIONS;i++)
3481 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3482 return(True);
3483 return(False);
3486 /****************************************************************************
3487 reload the services file
3488 **************************************************************************/
3489 BOOL reload_services(BOOL test)
3491 BOOL ret;
3493 if (lp_loaded())
3495 pstring fname;
3496 pstrcpy(fname,lp_configfile());
3497 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3499 pstrcpy(servicesf,fname);
3500 test = False;
3504 reopen_logs();
3506 if (test && !lp_file_list_changed())
3507 return(True);
3509 lp_killunused(snum_used);
3511 ret = lp_load(servicesf,False,False,True);
3513 /* perhaps the config filename is now set */
3514 if (!test)
3515 reload_services(True);
3517 reopen_logs();
3519 load_interfaces();
3522 extern int Client;
3523 if (Client != -1) {
3524 set_socket_options(Client,"SO_KEEPALIVE");
3525 set_socket_options(Client,user_socket_options);
3529 reset_mangled_cache();
3531 /* this forces service parameters to be flushed */
3532 become_service(-1,True);
3534 return(ret);
3539 /****************************************************************************
3540 this prevents zombie child processes
3541 ****************************************************************************/
3542 static BOOL reload_after_sighup = False;
3544 static int sig_hup(void)
3546 BlockSignals(True,SIGHUP);
3547 DEBUG(0,("Got SIGHUP\n"));
3550 * Fix from <branko.cibej@hermes.si> here.
3551 * We used to reload in the signal handler - this
3552 * is a *BIG* no-no.
3555 reload_after_sighup = True;
3556 #ifndef DONT_REINSTALL_SIG
3557 signal(SIGHUP,SIGNAL_CAST sig_hup);
3558 #endif
3559 BlockSignals(False,SIGHUP);
3560 return(0);
3564 /****************************************************************************
3565 make a connection to a service
3566 ****************************************************************************/
3567 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3569 int cnum;
3570 int snum;
3571 struct passwd *pass = NULL;
3572 connection_struct *pcon;
3573 BOOL guest = False;
3574 BOOL force = False;
3576 strlower(service);
3578 snum = find_service(service);
3579 if (snum < 0)
3581 extern int Client;
3582 if (strequal(service,"IPC$"))
3584 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3585 return(-3);
3588 DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));
3589 return(-2);
3592 if (strequal(service,HOMES_NAME))
3594 if (*user && Get_Pwnam(user,True))
3595 return(make_connection(user,user,password,pwlen,dev,vuid));
3597 if(lp_security() != SEC_SHARE)
3599 if (validated_username(vuid))
3601 pstrcpy(user,validated_username(vuid));
3602 return(make_connection(user,user,password,pwlen,dev,vuid));
3605 else
3608 * Security = share. Try with sesssetup_user as the username.
3610 if(*sesssetup_user)
3612 pstrcpy(user,sesssetup_user);
3613 return(make_connection(user,user,password,pwlen,dev,vuid));
3618 if (!lp_snum_ok(snum) || !check_access(snum)) {
3619 return(-4);
3622 /* you can only connect to the IPC$ service as an ipc device */
3623 if (strequal(service,"IPC$"))
3624 pstrcpy(dev,"IPC");
3626 if (*dev == '?' || !*dev)
3628 if (lp_print_ok(snum))
3629 pstrcpy(dev,"LPT1:");
3630 else
3631 pstrcpy(dev,"A:");
3634 /* if the request is as a printer and you can't print then refuse */
3635 strupper(dev);
3636 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3637 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3638 return(-6);
3641 /* lowercase the user name */
3642 strlower(user);
3644 /* add it as a possible user name */
3645 add_session_user(service);
3647 /* shall we let them in? */
3648 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3650 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3651 return(-1);
3654 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3655 if (cnum < 0)
3657 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3658 return(-1);
3661 pcon = &Connections[cnum];
3662 bzero((char *)pcon,sizeof(*pcon));
3664 /* find out some info about the user */
3665 pass = Get_Pwnam(user,True);
3667 if (pass == NULL)
3669 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3670 return(-7);
3673 pcon->read_only = lp_readonly(snum);
3676 pstring list;
3677 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3678 string_sub(list,"%S",service);
3680 if (user_in_list(user,list))
3681 pcon->read_only = True;
3683 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3684 string_sub(list,"%S",service);
3686 if (user_in_list(user,list))
3687 pcon->read_only = False;
3690 /* admin user check */
3692 /* JRA - original code denied admin user if the share was
3693 marked read_only. Changed as I don't think this is needed,
3694 but old code left in case there is a problem here.
3696 if (user_in_list(user,lp_admin_users(snum))
3697 #if 0
3698 && !pcon->read_only)
3699 #else
3701 #endif
3703 pcon->admin_user = True;
3704 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3706 else
3707 pcon->admin_user = False;
3709 pcon->force_user = force;
3710 pcon->vuid = vuid;
3711 pcon->uid = pass->pw_uid;
3712 pcon->gid = pass->pw_gid;
3713 pcon->num_files_open = 0;
3714 pcon->lastused = time(NULL);
3715 pcon->service = snum;
3716 pcon->used = True;
3717 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3718 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3719 pcon->dirptr = NULL;
3720 pcon->veto_list = NULL;
3721 pcon->hide_list = NULL;
3722 pcon->veto_oplock_list = NULL;
3723 string_set(&pcon->dirpath,"");
3724 string_set(&pcon->user,user);
3726 #if HAVE_GETGRNAM
3727 if (*lp_force_group(snum))
3729 struct group *gptr;
3730 pstring gname;
3732 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3733 /* default service may be a group name */
3734 string_sub(gname,"%S",service);
3735 gptr = (struct group *)getgrnam(gname);
3737 if (gptr)
3739 pcon->gid = gptr->gr_gid;
3740 DEBUG(3,("Forced group %s\n",gname));
3742 else
3743 DEBUG(1,("Couldn't find group %s\n",gname));
3745 #endif
3747 if (*lp_force_user(snum))
3749 struct passwd *pass2;
3750 fstring fuser;
3751 fstrcpy(fuser,lp_force_user(snum));
3752 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3753 if (pass2)
3755 pcon->uid = pass2->pw_uid;
3756 string_set(&pcon->user,fuser);
3757 fstrcpy(user,fuser);
3758 pcon->force_user = True;
3759 DEBUG(3,("Forced user %s\n",fuser));
3761 else
3762 DEBUG(1,("Couldn't find user %s\n",fuser));
3766 pstring s;
3767 pstrcpy(s,lp_pathname(snum));
3768 standard_sub(cnum,s);
3769 string_set(&pcon->connectpath,s);
3770 DEBUG(3,("Connect path is %s\n",s));
3773 /* groups stuff added by ih */
3774 pcon->ngroups = 0;
3775 pcon->igroups = NULL;
3776 pcon->groups = NULL;
3777 pcon->attrs = NULL;
3779 if (!IS_IPC(cnum))
3781 /* Find all the groups this uid is in and store them. Used by become_user() */
3782 setup_groups(pcon->user,pcon->uid,pcon->gid,
3783 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3785 /* check number of connections */
3786 if (!claim_connection(cnum,
3787 lp_servicename(SNUM(cnum)),
3788 lp_max_connections(SNUM(cnum)),False))
3790 DEBUG(1,("too many connections - rejected\n"));
3791 return(-8);
3794 if (lp_status(SNUM(cnum)))
3795 claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3796 } /* IS_IPC */
3798 pcon->open = True;
3800 /* execute any "root preexec = " line */
3801 if (*lp_rootpreexec(SNUM(cnum)))
3803 pstring cmd;
3804 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3805 standard_sub(cnum,cmd);
3806 DEBUG(5,("cmd=%s\n",cmd));
3807 smbrun(cmd,NULL,False);
3810 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3812 DEBUG(0,("Can't become connected user!\n"));
3813 pcon->open = False;
3814 if (!IS_IPC(cnum)) {
3815 yield_connection(cnum,
3816 lp_servicename(SNUM(cnum)),
3817 lp_max_connections(SNUM(cnum)));
3818 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3820 return(-1);
3823 if (ChDir(pcon->connectpath) != 0)
3825 DEBUG(0,("Can't change directory to %s (%s)\n",
3826 pcon->connectpath,strerror(errno)));
3827 pcon->open = False;
3828 unbecome_user();
3829 if (!IS_IPC(cnum)) {
3830 yield_connection(cnum,
3831 lp_servicename(SNUM(cnum)),
3832 lp_max_connections(SNUM(cnum)));
3833 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3835 return(-5);
3838 string_set(&pcon->origpath,pcon->connectpath);
3840 #if SOFTLINK_OPTIMISATION
3841 /* resolve any soft links early */
3843 pstring s;
3844 pstrcpy(s,pcon->connectpath);
3845 GetWd(s);
3846 string_set(&pcon->connectpath,s);
3847 ChDir(pcon->connectpath);
3849 #endif
3851 num_connections_open++;
3852 add_session_user(user);
3854 /* execute any "preexec = " line */
3855 if (*lp_preexec(SNUM(cnum)))
3857 pstring cmd;
3858 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3859 standard_sub(cnum,cmd);
3860 smbrun(cmd,NULL,False);
3863 /* we've finished with the sensitive stuff */
3864 unbecome_user();
3866 /* Add veto/hide lists */
3867 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3869 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3870 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3871 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3875 extern int Client;
3876 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3877 timestring(),
3878 remote_machine,
3879 client_addr(Client),
3880 lp_servicename(SNUM(cnum)),user,
3881 pcon->uid,
3882 pcon->gid,
3883 (int)getpid()));
3886 return(cnum);
3889 /****************************************************************************
3890 Attempt to break an oplock on a file (if oplocked).
3891 Returns True if the file was closed as a result of
3892 the oplock break, False otherwise.
3893 Used as a last ditch attempt to free a space in the
3894 file table when we have run out.
3895 ****************************************************************************/
3897 static BOOL attempt_close_oplocked_file(files_struct *fp)
3900 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3902 if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3904 /* Try and break the oplock. */
3905 file_fd_struct *fsp = fp->fd_ptr;
3906 if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3907 if(!fp->open) /* Did the oplock break close the file ? */
3908 return True;
3912 return False;
3915 /****************************************************************************
3916 find first available file slot
3917 ****************************************************************************/
3918 int find_free_file(void )
3920 int i;
3921 static int first_file;
3923 /* we want to give out file handles differently on each new
3924 connection because of a common bug in MS clients where they try to
3925 reuse a file descriptor from an earlier smb connection. This code
3926 increases the chance that the errant client will get an error rather
3927 than causing corruption */
3928 if (first_file == 0) {
3929 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3930 if (first_file == 0) first_file = 1;
3933 if (first_file >= MAX_OPEN_FILES)
3934 first_file = 1;
3936 for (i=first_file;i<MAX_OPEN_FILES;i++)
3937 if (!Files[i].open && !Files[i].reserved) {
3938 memset(&Files[i], 0, sizeof(Files[i]));
3939 first_file = i+1;
3940 Files[i].reserved = True;
3941 return(i);
3944 /* returning a file handle of 0 is a bad idea - so we start at 1 */
3945 for (i=1;i<first_file;i++)
3946 if (!Files[i].open && !Files[i].reserved) {
3947 memset(&Files[i], 0, sizeof(Files[i]));
3948 first_file = i+1;
3949 Files[i].reserved = True;
3950 return(i);
3954 * Before we give up, go through the open files
3955 * and see if there are any files opened with a
3956 * batch oplock. If so break the oplock and then
3957 * re-use that entry (if it becomes closed).
3958 * This may help as NT/95 clients tend to keep
3959 * files batch oplocked for quite a long time
3960 * after they have finished with them.
3962 for (i=first_file;i<MAX_OPEN_FILES;i++) {
3963 if(attempt_close_oplocked_file( &Files[i])) {
3964 memset(&Files[i], 0, sizeof(Files[i]));
3965 first_file = i+1;
3966 Files[i].reserved = True;
3967 return(i);
3971 for (i=1;i<MAX_OPEN_FILES;i++) {
3972 if(attempt_close_oplocked_file( &Files[i])) {
3973 memset(&Files[i], 0, sizeof(Files[i]));
3974 first_file = i+1;
3975 Files[i].reserved = True;
3976 return(i);
3980 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3981 return(-1);
3984 /****************************************************************************
3985 find first available connection slot, starting from a random position.
3986 The randomisation stops problems with the server dieing and clients
3987 thinking the server is still available.
3988 ****************************************************************************/
3989 static int find_free_connection(int hash )
3991 int i;
3992 BOOL used=False;
3993 hash = (hash % (MAX_CONNECTIONS-2))+1;
3995 again:
3997 for (i=hash+1;i!=hash;)
3999 if (!Connections[i].open && Connections[i].used == used)
4001 DEBUG(3,("found free connection number %d\n",i));
4002 return(i);
4004 i++;
4005 if (i == MAX_CONNECTIONS)
4006 i = 1;
4009 if (!used)
4011 used = !used;
4012 goto again;
4015 DEBUG(1,("ERROR! Out of connection structures\n"));
4016 return(-1);
4020 /****************************************************************************
4021 reply for the core protocol
4022 ****************************************************************************/
4023 int reply_corep(char *outbuf)
4025 int outsize = set_message(outbuf,1,0,True);
4027 Protocol = PROTOCOL_CORE;
4029 return outsize;
4033 /****************************************************************************
4034 reply for the coreplus protocol
4035 ****************************************************************************/
4036 int reply_coreplus(char *outbuf)
4038 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4039 int outsize = set_message(outbuf,13,0,True);
4040 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
4041 readbraw and writebraw (possibly) */
4042 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4043 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
4045 Protocol = PROTOCOL_COREPLUS;
4047 return outsize;
4051 /****************************************************************************
4052 reply for the lanman 1.0 protocol
4053 ****************************************************************************/
4054 int reply_lanman1(char *outbuf)
4056 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4057 int secword=0;
4058 BOOL doencrypt = SMBENCRYPT();
4059 time_t t = time(NULL);
4061 if (lp_security()>=SEC_USER) secword |= 1;
4062 if (doencrypt) secword |= 2;
4064 set_message(outbuf,13,doencrypt?8:0,True);
4065 SSVAL(outbuf,smb_vwv1,secword);
4066 /* Create a token value and add it to the outgoing packet. */
4067 if (doencrypt)
4068 generate_next_challenge(smb_buf(outbuf));
4070 Protocol = PROTOCOL_LANMAN1;
4072 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4073 SSVAL(outbuf,smb_vwv2,max_recv);
4074 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
4075 SSVAL(outbuf,smb_vwv4,1);
4076 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
4077 readbraw writebraw (possibly) */
4078 SIVAL(outbuf,smb_vwv6,getpid());
4079 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4081 put_dos_date(outbuf,smb_vwv8,t);
4083 return (smb_len(outbuf)+4);
4087 /****************************************************************************
4088 reply for the lanman 2.0 protocol
4089 ****************************************************************************/
4090 int reply_lanman2(char *outbuf)
4092 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4093 int secword=0;
4094 BOOL doencrypt = SMBENCRYPT();
4095 time_t t = time(NULL);
4096 struct cli_state *cli = NULL;
4097 char cryptkey[8];
4098 char crypt_len = 0;
4100 if (lp_security() == SEC_SERVER) {
4101 cli = server_cryptkey();
4104 if (cli) {
4105 DEBUG(3,("using password server validation\n"));
4106 doencrypt = ((cli->sec_mode & 2) != 0);
4109 if (lp_security()>=SEC_USER) secword |= 1;
4110 if (doencrypt) secword |= 2;
4112 if (doencrypt) {
4113 crypt_len = 8;
4114 if (!cli) {
4115 generate_next_challenge(cryptkey);
4116 } else {
4117 memcpy(cryptkey, cli->cryptkey, 8);
4118 set_challenge(cli->cryptkey);
4122 set_message(outbuf,13,crypt_len,True);
4123 SSVAL(outbuf,smb_vwv1,secword);
4124 SIVAL(outbuf,smb_vwv6,getpid());
4125 if (doencrypt)
4126 memcpy(smb_buf(outbuf), cryptkey, 8);
4128 Protocol = PROTOCOL_LANMAN2;
4130 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4131 SSVAL(outbuf,smb_vwv2,max_recv);
4132 SSVAL(outbuf,smb_vwv3,lp_maxmux());
4133 SSVAL(outbuf,smb_vwv4,1);
4134 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
4135 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4136 put_dos_date(outbuf,smb_vwv8,t);
4138 return (smb_len(outbuf)+4);
4142 /****************************************************************************
4143 reply for the nt protocol
4144 ****************************************************************************/
4145 int reply_nt1(char *outbuf)
4147 /* dual names + lock_and_read + nt SMBs + remote API calls */
4148 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS
4149 #ifdef HAVE_NT_SMBS
4150 |CAP_NT_SMBS
4151 #endif /* HAVE_NT_SMBS */
4155 other valid capabilities which we may support at some time...
4156 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
4157 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
4160 int secword=0;
4161 BOOL doencrypt = SMBENCRYPT();
4162 time_t t = time(NULL);
4163 int data_len;
4164 struct cli_state *cli = NULL;
4165 char cryptkey[8];
4166 char crypt_len = 0;
4168 if (lp_security() == SEC_SERVER) {
4169 cli = server_cryptkey();
4172 if (cli) {
4173 DEBUG(3,("using password server validation\n"));
4174 doencrypt = ((cli->sec_mode & 2) != 0);
4177 if (doencrypt) {
4178 crypt_len = 8;
4179 if (!cli) {
4180 generate_next_challenge(cryptkey);
4181 } else {
4182 memcpy(cryptkey, cli->cryptkey, 8);
4183 set_challenge(cli->cryptkey);
4187 if (lp_readraw() && lp_writeraw()) {
4188 capabilities |= CAP_RAW_MODE;
4191 if (lp_security() >= SEC_USER) secword |= 1;
4192 if (doencrypt) secword |= 2;
4194 /* decide where (if) to put the encryption challenge, and
4195 follow it with the OEM'd domain name
4197 data_len = crypt_len + strlen(global_myworkgroup) + 1;
4199 set_message(outbuf,17,data_len,True);
4200 pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
4202 CVAL(outbuf,smb_vwv1) = secword;
4203 SSVALS(outbuf,smb_vwv16+1,crypt_len);
4204 if (doencrypt)
4205 memcpy(smb_buf(outbuf), cryptkey, 8);
4207 Protocol = PROTOCOL_NT1;
4209 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4210 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4211 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4212 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4213 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4214 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4215 put_long_date(outbuf+smb_vwv11+1,t);
4216 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4217 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4219 return (smb_len(outbuf)+4);
4222 /* these are the protocol lists used for auto architecture detection:
4224 WinNT 3.51:
4225 protocol [PC NETWORK PROGRAM 1.0]
4226 protocol [XENIX CORE]
4227 protocol [MICROSOFT NETWORKS 1.03]
4228 protocol [LANMAN1.0]
4229 protocol [Windows for Workgroups 3.1a]
4230 protocol [LM1.2X002]
4231 protocol [LANMAN2.1]
4232 protocol [NT LM 0.12]
4234 Win95:
4235 protocol [PC NETWORK PROGRAM 1.0]
4236 protocol [XENIX CORE]
4237 protocol [MICROSOFT NETWORKS 1.03]
4238 protocol [LANMAN1.0]
4239 protocol [Windows for Workgroups 3.1a]
4240 protocol [LM1.2X002]
4241 protocol [LANMAN2.1]
4242 protocol [NT LM 0.12]
4244 OS/2:
4245 protocol [PC NETWORK PROGRAM 1.0]
4246 protocol [XENIX CORE]
4247 protocol [LANMAN1.0]
4248 protocol [LM1.2X002]
4249 protocol [LANMAN2.1]
4253 * Modified to recognize the architecture of the remote machine better.
4255 * This appears to be the matrix of which protocol is used by which
4256 * MS product.
4257 Protocol WfWg Win95 WinNT OS/2
4258 PC NETWORK PROGRAM 1.0 1 1 1 1
4259 XENIX CORE 2 2
4260 MICROSOFT NETWORKS 3.0 2 2
4261 DOS LM1.2X002 3 3
4262 MICROSOFT NETWORKS 1.03 3
4263 DOS LANMAN2.1 4 4
4264 LANMAN1.0 4 3
4265 Windows for Workgroups 3.1a 5 5 5
4266 LM1.2X002 6 4
4267 LANMAN2.1 7 5
4268 NT LM 0.12 6 8
4270 * tim@fsg.com 09/29/95
4273 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
4274 #define ARCH_WIN95 0x2
4275 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
4276 #define ARCH_WINNT 0x8
4277 #define ARCH_SAMBA 0x10
4279 #define ARCH_ALL 0x1F
4281 /* List of supported protocols, most desired first */
4282 struct {
4283 char *proto_name;
4284 char *short_name;
4285 int (*proto_reply_fn)(char *);
4286 int protocol_level;
4287 } supported_protocols[] = {
4288 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
4289 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
4290 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4291 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4292 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
4293 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4294 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
4295 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4296 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
4297 {NULL,NULL},
4301 /****************************************************************************
4302 reply to a negprot
4303 ****************************************************************************/
4304 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4306 int outsize = set_message(outbuf,1,0,True);
4307 int Index=0;
4308 int choice= -1;
4309 int protocol;
4310 char *p;
4311 int bcc = SVAL(smb_buf(inbuf),-2);
4312 int arch = ARCH_ALL;
4314 p = smb_buf(inbuf)+1;
4315 while (p < (smb_buf(inbuf) + bcc))
4317 Index++;
4318 DEBUG(3,("Requested protocol [%s]\n",p));
4319 if (strcsequal(p,"Windows for Workgroups 3.1a"))
4320 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4321 else if (strcsequal(p,"DOS LM1.2X002"))
4322 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4323 else if (strcsequal(p,"DOS LANMAN2.1"))
4324 arch &= ( ARCH_WFWG | ARCH_WIN95 );
4325 else if (strcsequal(p,"NT LM 0.12"))
4326 arch &= ( ARCH_WIN95 | ARCH_WINNT );
4327 else if (strcsequal(p,"LANMAN2.1"))
4328 arch &= ( ARCH_WINNT | ARCH_OS2 );
4329 else if (strcsequal(p,"LM1.2X002"))
4330 arch &= ( ARCH_WINNT | ARCH_OS2 );
4331 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4332 arch &= ARCH_WINNT;
4333 else if (strcsequal(p,"XENIX CORE"))
4334 arch &= ( ARCH_WINNT | ARCH_OS2 );
4335 else if (strcsequal(p,"Samba")) {
4336 arch = ARCH_SAMBA;
4337 break;
4340 p += strlen(p) + 2;
4343 switch ( arch ) {
4344 case ARCH_SAMBA:
4345 set_remote_arch(RA_SAMBA);
4346 break;
4347 case ARCH_WFWG:
4348 set_remote_arch(RA_WFWG);
4349 break;
4350 case ARCH_WIN95:
4351 set_remote_arch(RA_WIN95);
4352 break;
4353 case ARCH_WINNT:
4354 set_remote_arch(RA_WINNT);
4355 break;
4356 case ARCH_OS2:
4357 set_remote_arch(RA_OS2);
4358 break;
4359 default:
4360 set_remote_arch(RA_UNKNOWN);
4361 break;
4364 /* possibly reload - change of architecture */
4365 reload_services(True);
4367 /* a special case to stop password server loops */
4368 if (Index == 1 && strequal(remote_machine,myhostname) &&
4369 (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4370 exit_server("Password server loop!");
4372 /* Check for protocols, most desirable first */
4373 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4375 p = smb_buf(inbuf)+1;
4376 Index = 0;
4377 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4378 while (p < (smb_buf(inbuf) + bcc))
4380 if (strequal(p,supported_protocols[protocol].proto_name))
4381 choice = Index;
4382 Index++;
4383 p += strlen(p) + 2;
4385 if(choice != -1)
4386 break;
4389 SSVAL(outbuf,smb_vwv0,choice);
4390 if(choice != -1) {
4391 extern fstring remote_proto;
4392 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4393 reload_services(True);
4394 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4395 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4397 else {
4398 DEBUG(0,("No protocol supported !\n"));
4400 SSVAL(outbuf,smb_vwv0,choice);
4402 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4404 return(outsize);
4408 /****************************************************************************
4409 close all open files for a connection
4410 ****************************************************************************/
4411 static void close_open_files(int cnum)
4413 int i;
4414 for (i=0;i<MAX_OPEN_FILES;i++)
4415 if( Files[i].cnum == cnum && Files[i].open) {
4416 close_file(i,False);
4422 /****************************************************************************
4423 close a cnum
4424 ****************************************************************************/
4425 void close_cnum(int cnum, uint16 vuid)
4427 extern int Client;
4428 DirCacheFlush(SNUM(cnum));
4430 unbecome_user();
4432 if (!OPEN_CNUM(cnum))
4434 DEBUG(0,("Can't close cnum %d\n",cnum));
4435 return;
4438 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4439 timestring(),
4440 remote_machine,client_addr(Client),
4441 lp_servicename(SNUM(cnum))));
4443 yield_connection(cnum,
4444 lp_servicename(SNUM(cnum)),
4445 lp_max_connections(SNUM(cnum)));
4447 if (lp_status(SNUM(cnum)))
4448 yield_connection(cnum,"STATUS.",MAXSTATUS);
4450 close_open_files(cnum);
4451 dptr_closecnum(cnum);
4453 /* execute any "postexec = " line */
4454 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4456 pstring cmd;
4457 pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4458 standard_sub(cnum,cmd);
4459 smbrun(cmd,NULL,False);
4460 unbecome_user();
4463 unbecome_user();
4464 /* execute any "root postexec = " line */
4465 if (*lp_rootpostexec(SNUM(cnum)))
4467 pstring cmd;
4468 pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4469 standard_sub(cnum,cmd);
4470 smbrun(cmd,NULL,False);
4473 Connections[cnum].open = False;
4474 num_connections_open--;
4475 if (Connections[cnum].ngroups && Connections[cnum].groups)
4477 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4478 free(Connections[cnum].groups);
4479 free(Connections[cnum].igroups);
4480 Connections[cnum].groups = NULL;
4481 Connections[cnum].igroups = NULL;
4482 Connections[cnum].ngroups = 0;
4485 free_namearray(Connections[cnum].veto_list);
4486 free_namearray(Connections[cnum].hide_list);
4487 free_namearray(Connections[cnum].veto_oplock_list);
4489 string_set(&Connections[cnum].user,"");
4490 string_set(&Connections[cnum].dirpath,"");
4491 string_set(&Connections[cnum].connectpath,"");
4496 #if DUMP_CORE
4497 /*******************************************************************
4498 prepare to dump a core file - carefully!
4499 ********************************************************************/
4500 static BOOL dump_core(void)
4502 char *p;
4503 pstring dname;
4504 pstrcpy(dname,debugf);
4505 if ((p=strrchr(dname,'/'))) *p=0;
4506 pstrcat(dname,"/corefiles");
4507 mkdir(dname,0700);
4508 sys_chown(dname,getuid(),getgid());
4509 chmod(dname,0700);
4510 if (chdir(dname)) return(False);
4511 umask(~(0700));
4513 #ifndef NO_GETRLIMIT
4514 #ifdef RLIMIT_CORE
4516 struct rlimit rlp;
4517 getrlimit(RLIMIT_CORE, &rlp);
4518 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4519 setrlimit(RLIMIT_CORE, &rlp);
4520 getrlimit(RLIMIT_CORE, &rlp);
4521 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4523 #endif
4524 #endif
4527 DEBUG(0,("Dumping core in %s\n",dname));
4528 return(True);
4530 #endif
4532 /****************************************************************************
4533 exit the server
4534 ****************************************************************************/
4535 void exit_server(char *reason)
4537 static int firsttime=1;
4538 int i;
4540 if (!firsttime) exit(0);
4541 firsttime = 0;
4543 unbecome_user();
4544 DEBUG(2,("Closing connections\n"));
4545 for (i=0;i<MAX_CONNECTIONS;i++)
4546 if (Connections[i].open)
4547 close_cnum(i,(uint16)-1);
4548 #ifdef DFS_AUTH
4549 if (dcelogin_atmost_once)
4550 dfs_unlogin();
4551 #endif
4552 if (!reason) {
4553 int oldlevel = DEBUGLEVEL;
4554 DEBUGLEVEL = 10;
4555 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4556 if (last_inbuf)
4557 show_msg(last_inbuf);
4558 DEBUGLEVEL = oldlevel;
4559 DEBUG(0,("===============================================================\n"));
4560 #if DUMP_CORE
4561 if (dump_core()) return;
4562 #endif
4565 locking_end();
4567 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4568 exit(0);
4571 /****************************************************************************
4572 do some standard substitutions in a string
4573 ****************************************************************************/
4574 void standard_sub(int cnum,char *str)
4576 if (VALID_CNUM(cnum)) {
4577 char *p, *s, *home;
4579 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4580 switch (*(p+1)) {
4581 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4582 string_sub(p,"%H",home);
4583 else
4584 p += 2;
4585 break;
4586 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4587 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4588 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4589 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4591 * Patch from jkf@soton.ac.uk
4592 * Left the %N (NIS server name) in standard_sub_basic as it
4593 * is a feature for logon servers, hence uses the username.
4594 * The %p (NIS server path) code is here as it is used
4595 * instead of the default "path =" string in [homes] and so
4596 * needs the service name, not the username.
4598 case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4599 case '\0' : p++; break; /* don't run off the end of the string */
4600 default : p+=2; break;
4604 standard_sub_basic(str);
4608 These flags determine some of the permissions required to do an operation
4610 Note that I don't set NEED_WRITE on some write operations because they
4611 are used by some brain-dead clients when printing, and I don't want to
4612 force write permissions on print services.
4614 #define AS_USER (1<<0)
4615 #define NEED_WRITE (1<<1)
4616 #define TIME_INIT (1<<2)
4617 #define CAN_IPC (1<<3)
4618 #define AS_GUEST (1<<5)
4619 #define QUEUE_IN_OPLOCK (1<<6)
4622 define a list of possible SMB messages and their corresponding
4623 functions. Any message that has a NULL function is unimplemented -
4624 please feel free to contribute implementations!
4626 struct smb_message_struct
4628 int code;
4629 char *name;
4630 int (*fn)(char *, char *, int, int);
4631 int flags;
4632 #if PROFILING
4633 unsigned long time;
4634 #endif
4636 smb_messages[] = {
4638 /* CORE PROTOCOL */
4640 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4641 {SMBtcon,"SMBtcon",reply_tcon,0},
4642 {SMBtdis,"SMBtdis",reply_tdis,0},
4643 {SMBexit,"SMBexit",reply_exit,0},
4644 {SMBioctl,"SMBioctl",reply_ioctl,0},
4645 {SMBecho,"SMBecho",reply_echo,0},
4646 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4647 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4648 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4649 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4650 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4651 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4652 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4653 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4655 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4656 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4657 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4659 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4660 {SMBread,"SMBread",reply_read,AS_USER},
4661 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4662 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4663 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4664 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4665 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4666 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4668 /* this is a Pathworks specific call, allowing the
4669 changing of the root path */
4670 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4672 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4673 {SMBflush,"SMBflush",reply_flush,AS_USER},
4674 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4675 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4676 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4677 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4678 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4679 {SMBlock,"SMBlock",reply_lock,AS_USER},
4680 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4682 /* CORE+ PROTOCOL FOLLOWS */
4684 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4685 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4686 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4687 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4688 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4690 /* LANMAN1.0 PROTOCOL FOLLOWS */
4692 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4693 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4694 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4695 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4696 {SMBwritec,"SMBwritec",NULL,AS_USER},
4697 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4698 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4699 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4700 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4701 {SMBioctls,"SMBioctls",NULL,AS_USER},
4702 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4703 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4705 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4706 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4707 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4708 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4710 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4711 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4712 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4714 /* LANMAN2.0 PROTOCOL FOLLOWS */
4715 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4716 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4717 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4718 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4720 #ifdef HAVE_NT_SMBS
4721 /* NT PROTOCOL FOLLOWS */
4722 {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4723 {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
4724 {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
4725 {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
4726 #endif /* HAVE_NT_SMBS */
4728 /* messaging routines */
4729 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4730 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4731 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4732 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4734 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4736 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4737 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4738 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4739 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4742 /****************************************************************************
4743 return a string containing the function name of a SMB command
4744 ****************************************************************************/
4745 char *smb_fn_name(int type)
4747 static char *unknown_name = "SMBunknown";
4748 static int num_smb_messages =
4749 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4750 int match;
4752 for (match=0;match<num_smb_messages;match++)
4753 if (smb_messages[match].code == type)
4754 break;
4756 if (match == num_smb_messages)
4757 return(unknown_name);
4759 return(smb_messages[match].name);
4763 /****************************************************************************
4764 do a switch on the message type, and return the response size
4765 ****************************************************************************/
4766 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4768 static int pid= -1;
4769 int outsize = 0;
4770 static int num_smb_messages =
4771 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4772 int match;
4774 #if PROFILING
4775 struct timeval msg_start_time;
4776 struct timeval msg_end_time;
4777 static unsigned long total_time = 0;
4779 GetTimeOfDay(&msg_start_time);
4780 #endif
4782 if (pid == -1)
4783 pid = getpid();
4785 errno = 0;
4786 last_message = type;
4788 /* make sure this is an SMB packet */
4789 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4791 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4792 return(-1);
4795 for (match=0;match<num_smb_messages;match++)
4796 if (smb_messages[match].code == type)
4797 break;
4799 if (match == num_smb_messages)
4801 DEBUG(0,("Unknown message type %d!\n",type));
4802 outsize = reply_unknown(inbuf,outbuf);
4804 else
4806 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4808 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4811 * Queue this message as we are the process of an oplock break.
4814 DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4815 timestring() ));
4817 push_smb_message( inbuf, size);
4818 return -1;
4821 if (smb_messages[match].fn)
4823 int cnum = SVAL(inbuf,smb_tid);
4824 int flags = smb_messages[match].flags;
4825 static uint16 last_session_tag = UID_FIELD_INVALID;
4826 /* In share mode security we must ignore the vuid. */
4827 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4828 /* Ensure this value is replaced in the incoming packet. */
4829 SSVAL(inbuf,smb_uid,session_tag);
4832 * Ensure the correct username is in sesssetup_user.
4833 * This is a really ugly bugfix for problems with
4834 * multiple session_setup_and_X's being done and
4835 * allowing %U and %G substitutions to work correctly.
4836 * There is a reason this code is done here, don't
4837 * move it unless you know what you're doing... :-).
4838 * JRA.
4840 if(session_tag != last_session_tag ) {
4841 user_struct *vuser = NULL;
4843 last_session_tag = session_tag;
4844 if(session_tag != UID_FIELD_INVALID)
4845 vuser = get_valid_user_struct(session_tag);
4846 if(vuser != NULL)
4847 pstrcpy( sesssetup_user, vuser->requested_name);
4850 /* does this protocol need to be run as root? */
4851 if (!(flags & AS_USER))
4852 unbecome_user();
4854 /* does this protocol need to be run as the connected user? */
4855 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4856 if (flags & AS_GUEST)
4857 flags &= ~AS_USER;
4858 else
4859 return(ERROR(ERRSRV,ERRinvnid));
4861 /* this code is to work around a bug is MS client 3 without
4862 introducing a security hole - it needs to be able to do
4863 print queue checks as guest if it isn't logged in properly */
4864 if (flags & AS_USER)
4865 flags &= ~AS_GUEST;
4867 /* does it need write permission? */
4868 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4869 return(ERROR(ERRSRV,ERRaccess));
4871 /* ipc services are limited */
4872 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4873 return(ERROR(ERRSRV,ERRaccess));
4875 /* load service specific parameters */
4876 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4877 return(ERROR(ERRSRV,ERRaccess));
4879 /* does this protocol need to be run as guest? */
4880 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4881 return(ERROR(ERRSRV,ERRaccess));
4883 last_inbuf = inbuf;
4885 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4887 else
4889 outsize = reply_unknown(inbuf,outbuf);
4893 #if PROFILING
4894 GetTimeOfDay(&msg_end_time);
4895 if (!(smb_messages[match].flags & TIME_INIT))
4897 smb_messages[match].time = 0;
4898 smb_messages[match].flags |= TIME_INIT;
4901 unsigned long this_time =
4902 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4903 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4904 smb_messages[match].time += this_time;
4905 total_time += this_time;
4907 DEBUG(2,("TIME %s %d usecs %g pct\n",
4908 smb_fn_name(type),smb_messages[match].time,
4909 (100.0*smb_messages[match].time) / total_time));
4910 #endif
4912 return(outsize);
4916 /****************************************************************************
4917 construct a chained reply and add it to the already made reply
4918 **************************************************************************/
4919 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4921 static char *orig_inbuf;
4922 static char *orig_outbuf;
4923 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4924 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4925 char *inbuf2, *outbuf2;
4926 int outsize2;
4927 char inbuf_saved[smb_wct];
4928 char outbuf_saved[smb_wct];
4929 extern int chain_size;
4930 int wct = CVAL(outbuf,smb_wct);
4931 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4933 /* maybe its not chained */
4934 if (smb_com2 == 0xFF) {
4935 CVAL(outbuf,smb_vwv0) = 0xFF;
4936 return outsize;
4939 if (chain_size == 0) {
4940 /* this is the first part of the chain */
4941 orig_inbuf = inbuf;
4942 orig_outbuf = outbuf;
4945 /* we need to tell the client where the next part of the reply will be */
4946 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4947 CVAL(outbuf,smb_vwv0) = smb_com2;
4949 /* remember how much the caller added to the chain, only counting stuff
4950 after the parameter words */
4951 chain_size += outsize - smb_wct;
4953 /* work out pointers into the original packets. The
4954 headers on these need to be filled in */
4955 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4956 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4958 /* remember the original command type */
4959 smb_com1 = CVAL(orig_inbuf,smb_com);
4961 /* save the data which will be overwritten by the new headers */
4962 memcpy(inbuf_saved,inbuf2,smb_wct);
4963 memcpy(outbuf_saved,outbuf2,smb_wct);
4965 /* give the new packet the same header as the last part of the SMB */
4966 memmove(inbuf2,inbuf,smb_wct);
4968 /* create the in buffer */
4969 CVAL(inbuf2,smb_com) = smb_com2;
4971 /* create the out buffer */
4972 bzero(outbuf2,smb_size);
4973 set_message(outbuf2,0,0,True);
4974 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4976 memcpy(outbuf2+4,inbuf2+4,4);
4977 CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4978 CVAL(outbuf2,smb_reh) = 0;
4979 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4980 means a reply */
4981 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4982 SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4983 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4984 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4985 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4986 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4988 DEBUG(3,("Chained message\n"));
4989 show_msg(inbuf2);
4991 /* process the request */
4992 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4993 bufsize-chain_size);
4995 /* copy the new reply and request headers over the old ones, but
4996 preserve the smb_com field */
4997 memmove(orig_outbuf,outbuf2,smb_wct);
4998 CVAL(orig_outbuf,smb_com) = smb_com1;
5000 /* restore the saved data, being careful not to overwrite any
5001 data from the reply header */
5002 memcpy(inbuf2,inbuf_saved,smb_wct);
5004 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
5005 if (ofs < 0) ofs = 0;
5006 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
5009 return outsize2;
5014 /****************************************************************************
5015 construct a reply to the incoming packet
5016 ****************************************************************************/
5017 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
5019 int type = CVAL(inbuf,smb_com);
5020 int outsize = 0;
5021 int msg_type = CVAL(inbuf,0);
5022 extern int chain_size;
5024 smb_last_time = time(NULL);
5026 chain_size = 0;
5027 chain_fnum = -1;
5028 reset_chain_pnum();
5030 bzero(outbuf,smb_size);
5032 if (msg_type != 0)
5033 return(reply_special(inbuf,outbuf));
5035 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
5036 set_message(outbuf,0,0,True);
5038 memcpy(outbuf+4,inbuf+4,4);
5039 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
5040 CVAL(outbuf,smb_reh) = 0;
5041 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
5042 means a reply */
5043 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
5044 SSVAL(outbuf,smb_err,SMB_SUCCESS);
5045 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
5046 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
5047 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
5048 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
5050 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
5052 outsize += chain_size;
5054 if(outsize > 4)
5055 smb_setlen(outbuf,outsize - 4);
5056 return(outsize);
5059 /****************************************************************************
5060 process commands from the client
5061 ****************************************************************************/
5062 static void process(void)
5064 extern int Client;
5066 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5067 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5068 if ((InBuffer == NULL) || (OutBuffer == NULL))
5069 return;
5071 InBuffer += SMB_ALIGNMENT;
5072 OutBuffer += SMB_ALIGNMENT;
5074 #if PRIME_NMBD
5075 DEBUG(3,("priming nmbd\n"));
5077 struct in_addr ip;
5078 ip = *interpret_addr2("localhost");
5079 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
5080 *OutBuffer = 0;
5081 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
5083 #endif
5085 /* re-initialise the timezone */
5086 TimeInit();
5088 while (True)
5090 int deadtime = lp_deadtime()*60;
5091 int counter;
5092 int last_keepalive=0;
5093 int service_load_counter = 0;
5094 BOOL got_smb = False;
5096 if (deadtime <= 0)
5097 deadtime = DEFAULT_SMBD_TIMEOUT;
5099 #if USE_READ_PREDICTION
5100 if (lp_readprediction())
5101 do_read_prediction();
5102 #endif
5104 errno = 0;
5106 for (counter=SMBD_SELECT_LOOP;
5107 !receive_message_or_smb(Client,oplock_sock,
5108 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
5109 counter += SMBD_SELECT_LOOP)
5111 int i;
5112 time_t t;
5113 BOOL allidle = True;
5114 extern int keepalive;
5116 if (counter > 365 * 3600) /* big number of seconds. */
5118 counter = 0;
5119 service_load_counter = 0;
5122 if (smb_read_error == READ_EOF)
5124 DEBUG(3,("end of file from client\n"));
5125 return;
5128 if (smb_read_error == READ_ERROR)
5130 DEBUG(3,("receive_smb error (%s) exiting\n",
5131 strerror(errno)));
5132 return;
5135 t = time(NULL);
5137 /* become root again if waiting */
5138 unbecome_user();
5140 /* check for smb.conf reload */
5141 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5143 service_load_counter = counter;
5145 /* reload services, if files have changed. */
5146 reload_services(True);
5150 * If reload_after_sighup == True then we got a SIGHUP
5151 * and are being asked to reload. Fix from <branko.cibej@hermes.si>
5154 if (reload_after_sighup)
5156 DEBUG(0,("Reloading services after SIGHUP\n"));
5157 reload_services(False);
5158 reload_after_sighup = False;
5161 /* automatic timeout if all connections are closed */
5162 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
5164 DEBUG(2,("%s Closing idle connection\n",timestring()));
5165 return;
5168 if (keepalive && (counter-last_keepalive)>keepalive)
5170 struct cli_state *cli = server_client();
5171 if (!send_keepalive(Client)) {
5172 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5173 return;
5175 /* also send a keepalive to the password server if its still
5176 connected */
5177 if (cli && cli->initialised)
5178 send_keepalive(cli->fd);
5179 last_keepalive = counter;
5182 /* check for connection timeouts */
5183 for (i=0;i<MAX_CONNECTIONS;i++)
5184 if (Connections[i].open)
5186 /* close dirptrs on connections that are idle */
5187 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5188 dptr_idlecnum(i);
5190 if (Connections[i].num_files_open > 0 ||
5191 (t-Connections[i].lastused)<deadtime)
5192 allidle = False;
5195 if (allidle && num_connections_open>0)
5197 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5198 return;
5201 if(global_machine_pasword_needs_changing)
5203 unsigned char trust_passwd_hash[16];
5204 time_t lct;
5205 pstring remote_machine_list;
5208 * We're in domain level security, and the code that
5209 * read the machine password flagged that the machine
5210 * password needs changing.
5214 * First, open the machine password file with an exclusive lock.
5217 if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5218 DEBUG(0,("process: unable to open the machine account password file for \
5219 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5220 continue;
5223 if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5224 DEBUG(0,("process: unable to read the machine account password for \
5225 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5226 trust_password_unlock();
5227 continue;
5231 * Make sure someone else hasn't already done this.
5234 if(t < lct + lp_machine_password_timeout()) {
5235 trust_password_unlock();
5236 global_machine_pasword_needs_changing = False;
5237 continue;
5240 pstrcpy(remote_machine_list, lp_passwordserver());
5242 change_trust_account_password( global_myworkgroup, remote_machine_list);
5243 trust_password_unlock();
5244 global_machine_pasword_needs_changing = False;
5248 if(got_smb)
5249 process_smb(InBuffer, OutBuffer);
5250 else
5251 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5256 /****************************************************************************
5257 initialise connect, service and file structs
5258 ****************************************************************************/
5259 static void init_structs(void )
5261 int i;
5262 get_myname(myhostname,NULL);
5265 * Set the machine NETBIOS name if not already
5266 * set from the config file.
5269 if (!*global_myname)
5271 char *p;
5272 fstrcpy( global_myname, myhostname );
5273 p = strchr( global_myname, '.' );
5274 if (p)
5275 *p = 0;
5277 strupper( global_myname );
5279 for (i=0;i<MAX_CONNECTIONS;i++)
5281 Connections[i].open = False;
5282 Connections[i].num_files_open=0;
5283 Connections[i].lastused=0;
5284 Connections[i].used=False;
5285 string_init(&Connections[i].user,"");
5286 string_init(&Connections[i].dirpath,"");
5287 string_init(&Connections[i].connectpath,"");
5288 string_init(&Connections[i].origpath,"");
5291 for (i=0;i<MAX_OPEN_FILES;i++)
5293 Files[i].open = False;
5294 string_init(&Files[i].name,"");
5297 for (i=0;i<MAX_OPEN_FILES;i++)
5299 file_fd_struct *fd_ptr = &FileFd[i];
5300 fd_ptr->ref_count = 0;
5301 fd_ptr->dev = (int32)-1;
5302 fd_ptr->inode = (int32)-1;
5303 fd_ptr->fd = -1;
5304 fd_ptr->fd_readonly = -1;
5305 fd_ptr->fd_writeonly = -1;
5306 fd_ptr->real_open_flags = -1;
5309 /* for RPC pipes */
5310 init_rpc_pipe_hnd();
5312 /* for LSA handles */
5313 init_lsa_policy_hnd();
5315 init_dptrs();
5318 /****************************************************************************
5319 usage on the program
5320 ****************************************************************************/
5321 static void usage(char *pname)
5323 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5325 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5326 printf("Version %s\n",VERSION);
5327 printf("\t-D become a daemon\n");
5328 printf("\t-p port listen on the specified port\n");
5329 printf("\t-d debuglevel set the debuglevel\n");
5330 printf("\t-l log basename. Basename for log/debug files\n");
5331 printf("\t-s services file. Filename of services file\n");
5332 printf("\t-P passive only\n");
5333 printf("\t-a overwrite log file, don't append\n");
5334 printf("\n");
5338 /****************************************************************************
5339 main program
5340 ****************************************************************************/
5341 int main(int argc,char *argv[])
5343 extern BOOL append_log;
5344 /* shall I run as a daemon */
5345 BOOL is_daemon = False;
5346 int port = SMB_PORT;
5347 int opt;
5348 extern char *optarg;
5350 #ifdef NEED_AUTH_PARAMETERS
5351 set_auth_parameters(argc,argv);
5352 #endif
5354 #ifdef SecureWare
5355 setluid(0);
5356 #endif
5358 append_log = True;
5360 TimeInit();
5362 pstrcpy(debugf,SMBLOGFILE);
5364 pstrcpy(remote_machine, "smb");
5366 setup_logging(argv[0],False);
5368 charset_initialise();
5370 /* make absolutely sure we run as root - to handle cases where people
5371 are crazy enough to have it setuid */
5372 #ifdef USE_SETRES
5373 setresuid(0,0,0);
5374 #else
5375 setuid(0);
5376 seteuid(0);
5377 setuid(0);
5378 seteuid(0);
5379 #endif
5381 fault_setup((void (*)(void *))exit_server);
5382 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5384 /* we want total control over the permissions on created files,
5385 so set our umask to 0 */
5386 umask(0);
5388 GetWd(OriginalDir);
5390 init_uid();
5392 /* this is for people who can't start the program correctly */
5393 while (argc > 1 && (*argv[1] != '-'))
5395 argv++;
5396 argc--;
5399 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5400 switch (opt)
5402 case 'O':
5403 pstrcpy(user_socket_options,optarg);
5404 break;
5405 case 'i':
5406 pstrcpy(scope,optarg);
5407 break;
5408 case 'P':
5410 extern BOOL passive;
5411 passive = True;
5413 break;
5414 case 's':
5415 pstrcpy(servicesf,optarg);
5416 break;
5417 case 'l':
5418 pstrcpy(debugf,optarg);
5419 break;
5420 case 'a':
5422 extern BOOL append_log;
5423 append_log = !append_log;
5425 break;
5426 case 'D':
5427 is_daemon = True;
5428 break;
5429 case 'd':
5430 if (*optarg == 'A')
5431 DEBUGLEVEL = 10000;
5432 else
5433 DEBUGLEVEL = atoi(optarg);
5434 break;
5435 case 'p':
5436 port = atoi(optarg);
5437 break;
5438 case 'h':
5439 usage(argv[0]);
5440 exit(0);
5441 break;
5442 default:
5443 usage(argv[0]);
5444 exit(1);
5447 reopen_logs();
5449 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5450 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5452 #ifndef NO_GETRLIMIT
5453 #ifdef RLIMIT_NOFILE
5455 struct rlimit rlp;
5456 getrlimit(RLIMIT_NOFILE, &rlp);
5458 * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5459 * extra fd we need to read directories, as well as the log files
5460 * and standard handles etc.
5462 rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5463 setrlimit(RLIMIT_NOFILE, &rlp);
5464 getrlimit(RLIMIT_NOFILE, &rlp);
5465 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5467 #endif
5468 #endif
5471 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5472 getuid(),getgid(),geteuid(),getegid()));
5474 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5476 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5477 exit(1);
5480 init_structs();
5482 if (!reload_services(False))
5483 return(-1);
5485 #ifdef USE_SSL
5487 extern BOOL sslEnabled;
5488 sslEnabled = lp_ssl_enabled();
5489 if(sslEnabled)
5490 sslutil_init(True);
5492 #endif /* USE_SSL */
5494 codepage_initialise(lp_client_code_page());
5496 pstrcpy(global_myworkgroup, lp_workgroup());
5498 if(!pdb_generate_machine_sid())
5500 DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5501 exit(1);
5504 #ifndef NO_SIGNAL_TEST
5505 signal(SIGHUP,SIGNAL_CAST sig_hup);
5506 #endif
5508 /* Setup the signals that allow the debug log level
5509 to by dynamically changed. */
5511 /* If we are using the malloc debug code we can't use
5512 SIGUSR1 and SIGUSR2 to do debug level changes. */
5514 #ifndef MEM_MAN
5515 #if defined(SIGUSR1)
5516 signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5517 #endif /* SIGUSR1 */
5519 #if defined(SIGUSR2)
5520 signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5521 #endif /* SIGUSR2 */
5522 #endif /* MEM_MAN */
5524 DEBUG(3,("%s loaded services\n",timestring()));
5526 if (!is_daemon && !is_a_socket(0))
5528 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5529 is_daemon = True;
5532 if (is_daemon)
5534 DEBUG(3,("%s becoming a daemon\n",timestring()));
5535 become_daemon();
5538 if (!directory_exist(lp_lockdir(), NULL)) {
5539 mkdir(lp_lockdir(), 0755);
5542 if (is_daemon) {
5543 pidfile_create("smbd");
5546 if (!open_sockets(is_daemon,port))
5547 exit(1);
5549 if (!locking_init(0))
5550 exit(1);
5552 if(!initialize_password_db())
5553 exit(1);
5555 /* possibly reload the services file. */
5556 reload_services(True);
5558 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5560 if (*lp_rootdir())
5562 if (sys_chroot(lp_rootdir()) == 0)
5563 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5566 /* Setup the oplock IPC socket. */
5567 if(!open_oplock_ipc())
5568 exit(1);
5570 process();
5571 close_sockets();
5573 exit_server("normal exit");
5574 return(0);