added some debug lines to the rename code
[Samba.git] / source / smbd / server.c
blob3f4f6c7034792db459ccf3594b527a68897394c8
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "trans2.h"
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
34 int am_parent = 1;
35 int atexit_set = 0;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
43 extern pstring scope;
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 time_t smb_last_time=(time_t)0;
53 extern int smb_read_error;
55 extern pstring user_socket_options;
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
67 extern int Protocol;
69 /*
70 * Size of data we can send to client. Set
71 * by the client for all protocols above CORE.
72 * Set by us for CORE protocol.
74 int max_send = BUFFER_SIZE;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv = BUFFER_SIZE;
81 /* a fnum to use when chaining */
82 int chain_fnum = -1;
84 /* number of open connections */
85 static int num_connections_open = 0;
87 /* Oplock ipc UDP socket. */
88 int oplock_sock = -1;
89 uint16 oplock_port = 0;
90 /* Current number of oplocks we have outstanding. */
91 int32 global_oplocks_open = 0;
93 BOOL global_oplock_break = False;
95 extern fstring remote_machine;
97 extern pstring OriginalDir;
99 /* these can be set by some functions to override the error codes */
100 int unix_ERR_class=SUCCESS;
101 int unix_ERR_code=0;
104 extern int extra_time_offset;
106 extern pstring myhostname;
108 static int find_free_connection(int hash);
110 /* for readability... */
111 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
112 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
113 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
114 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
115 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
117 /****************************************************************************
118 when exiting, take the whole family
119 ****************************************************************************/
120 void *dflt_sig(void)
122 exit_server("caught signal");
123 return 0; /* Keep -Wall happy :-) */
125 /****************************************************************************
126 Send a SIGTERM to our process group.
127 *****************************************************************************/
128 void killkids(void)
130 if(am_parent) kill(0,SIGTERM);
133 /****************************************************************************
134 change a dos mode to a unix mode
135 base permission for files:
136 everybody gets read bit set
137 dos readonly is represented in unix by removing everyone's write bit
138 dos archive is represented in unix by the user's execute bit
139 dos system is represented in unix by the group's execute bit
140 dos hidden is represented in unix by the other's execute bit
141 Then apply create mask,
142 then add force bits.
143 base permission for directories:
144 dos directory is represented in unix by unix's dir bit and the exec bit
145 Then apply create mask,
146 then add force bits.
147 ****************************************************************************/
148 mode_t unix_mode(int cnum,int dosmode)
150 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
152 if ( !IS_DOS_READONLY(dosmode) )
153 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
155 if (IS_DOS_DIR(dosmode)) {
156 /* We never make directories read only for the owner as under DOS a user
157 can always create a file in a read-only directory. */
158 result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
159 /* Apply directory mask */
160 result &= lp_dir_mode(SNUM(cnum));
161 /* Add in force bits */
162 result |= lp_force_dir_mode(SNUM(cnum));
163 } else {
164 if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
165 result |= S_IXUSR;
167 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
168 result |= S_IXGRP;
170 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
171 result |= S_IXOTH;
173 /* Apply mode mask */
174 result &= lp_create_mode(SNUM(cnum));
175 /* Add in force bits */
176 result |= lp_force_create_mode(SNUM(cnum));
178 return(result);
182 /****************************************************************************
183 change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
187 int result = 0;
188 extern struct current_user current_user;
190 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
192 if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
193 if (!((sbuf->st_mode & S_IWOTH) ||
194 Connections[cnum].admin_user ||
195 ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
196 ((sbuf->st_mode & S_IWGRP) &&
197 in_group(sbuf->st_gid,current_user.gid,
198 current_user.ngroups,current_user.igroups))))
199 result |= aRONLY;
200 } else {
201 if ((sbuf->st_mode & S_IWUSR) == 0)
202 result |= aRONLY;
205 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
206 result |= aARCH;
208 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
209 result |= aSYSTEM;
211 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
212 result |= aHIDDEN;
214 if (S_ISDIR(sbuf->st_mode))
215 result = aDIR | (result & aRONLY);
217 #ifdef S_ISLNK
218 #if LINKS_READ_ONLY
219 if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
220 result |= aRONLY;
221 #endif
222 #endif
224 /* hide files with a name starting with a . */
225 if (lp_hide_dot_files(SNUM(cnum)))
227 char *p = strrchr(path,'/');
228 if (p)
229 p++;
230 else
231 p = path;
233 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
234 result |= aHIDDEN;
237 /* Optimization : Only call is_hidden_path if it's not already
238 hidden. */
239 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
241 result |= aHIDDEN;
244 DEBUG(8,("dos_mode returning "));
246 if (result & aHIDDEN) DEBUG(8, ("h"));
247 if (result & aRONLY ) DEBUG(8, ("r"));
248 if (result & aSYSTEM) DEBUG(8, ("s"));
249 if (result & aDIR ) DEBUG(8, ("d"));
250 if (result & aARCH ) DEBUG(8, ("a"));
252 DEBUG(8,("\n"));
254 return(result);
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
262 struct stat st1;
263 int mask=0;
264 int tmp;
265 int unixmode;
267 if (!st) {
268 st = &st1;
269 if (sys_stat(fname,st)) return(-1);
272 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
274 if (dos_mode(cnum,fname,st) == dosmode) return(0);
276 unixmode = unix_mode(cnum,dosmode);
278 /* preserve the s bits */
279 mask |= (S_ISUID | S_ISGID);
281 /* preserve the t bit */
282 #ifdef S_ISVTX
283 mask |= S_ISVTX;
284 #endif
286 /* possibly preserve the x bits */
287 if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
288 if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
289 if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
291 unixmode |= (st->st_mode & mask);
293 /* if we previously had any r bits set then leave them alone */
294 if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
295 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
296 unixmode |= tmp;
299 /* if we previously had any w bits set then leave them alone
300 if the new mode is not rdonly */
301 if (!IS_DOS_READONLY(dosmode) &&
302 (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
303 unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
304 unixmode |= tmp;
307 return(sys_chmod(fname,unixmode));
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
312 than POSIX.
313 *******************************************************************/
315 int file_utime(int cnum, char *fname, struct utimbuf *times)
317 extern struct current_user current_user;
318 struct stat sb;
319 int ret = -1;
321 errno = 0;
323 if(sys_utime(fname, times) == 0)
324 return 0;
326 if((errno != EPERM) && (errno != EACCES))
327 return -1;
329 if(!lp_dos_filetimes(SNUM(cnum)))
330 return -1;
332 /* We have permission (given by the Samba admin) to
333 break POSIX semantics and allow a user to change
334 the time on a file they don't own but can write to
335 (as DOS does).
338 if(sys_stat(fname,&sb) != 0)
339 return -1;
341 /* Check if we have write access. */
342 if (CAN_WRITE(cnum)) {
343 if (((sb.st_mode & S_IWOTH) ||
344 Connections[cnum].admin_user ||
345 ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
346 ((sb.st_mode & S_IWGRP) &&
347 in_group(sb.st_gid,current_user.gid,
348 current_user.ngroups,current_user.igroups)))) {
349 /* We are allowed to become root and change the filetime. */
350 become_root(False);
351 ret = sys_utime(fname, times);
352 unbecome_root(False);
356 return ret;
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
363 BOOL set_filetime(int cnum, char *fname, time_t mtime)
365 struct utimbuf times;
367 if (null_mtime(mtime)) return(True);
369 times.modtime = times.actime = mtime;
371 if (file_utime(cnum, fname, &times)) {
372 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
375 return(True);
378 /****************************************************************************
379 check if two filenames are equal
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL fname_equal(char *name1, char *name2)
385 int l1 = strlen(name1);
386 int l2 = strlen(name2);
388 /* handle filenames ending in a single dot */
389 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
391 BOOL ret;
392 name1[l1-1] = 0;
393 ret = fname_equal(name1,name2);
394 name1[l1-1] = '.';
395 return(ret);
398 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
400 BOOL ret;
401 name2[l2-1] = 0;
402 ret = fname_equal(name1,name2);
403 name2[l2-1] = '.';
404 return(ret);
407 /* now normal filename handling */
408 if (case_sensitive)
409 return(strcmp(name1,name2) == 0);
411 return(strequal(name1,name2));
415 /****************************************************************************
416 mangle the 2nd name and check if it is then equal to the first name
417 ****************************************************************************/
418 static BOOL mangled_equal(char *name1, char *name2)
420 pstring tmpname;
422 if (is_8_3(name2, True))
423 return(False);
425 strcpy(tmpname,name2);
426 mangle_name_83(tmpname);
428 return(strequal(name1,tmpname));
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
435 If the name looks like a mangled name then try via the mangling functions
436 ****************************************************************************/
437 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
439 void *cur_dir;
440 char *dname;
441 BOOL mangled;
442 pstring name2;
444 mangled = is_mangled(name);
446 /* handle null paths */
447 if (*path == 0)
448 path = ".";
450 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
451 strcpy(name, dname);
452 return(True);
455 if (mangled)
456 check_mangled_stack(name);
458 /* open the directory */
459 if (!(cur_dir = OpenDir(cnum, path, True)))
461 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
462 return(False);
465 /* now scan for matching names */
466 while ((dname = ReadDirName(cur_dir)))
468 if (*dname == '.' &&
469 (strequal(dname,".") || strequal(dname,"..")))
470 continue;
472 pstrcpy(name2,dname);
473 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
475 if ((mangled && mangled_equal(name,name2))
476 || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
478 /* we've found the file, change it's name and return */
479 if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
480 strcpy(name, dname);
481 CloseDir(cur_dir);
482 return(True);
486 CloseDir(cur_dir);
487 return(False);
490 /****************************************************************************
491 This routine is called to convert names from the dos namespace to unix
492 namespace. It needs to handle any case conversions, mangling, format
493 changes etc.
495 We assume that we have already done a chdir() to the right "root" directory
496 for this service.
498 The function will return False if some part of the name except for the last
499 part cannot be resolved
501 If the saved_last_component != 0, then the unmodified last component
502 of the pathname is returned there. This is used in an exceptional
503 case in reply_mv (so far). If saved_last_component == 0 then nothing
504 is returned there.
506 The bad_path arg is set to True if the filename walk failed. This is
507 used to pick the correct error code to return between ENOENT and ENOTDIR
508 as Windows applications depend on ERRbadpath being returned if a component
509 of a pathname does not exist.
510 ****************************************************************************/
511 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
513 struct stat st;
514 char *start, *end;
515 pstring dirpath;
516 int saved_errno;
518 *dirpath = 0;
519 *bad_path = False;
521 if(saved_last_component)
522 *saved_last_component = 0;
524 /* convert to basic unix format - removing \ chars and cleaning it up */
525 unix_format(name);
526 unix_clean_name(name);
528 /* names must be relative to the root of the service - trim any leading /.
529 also trim trailing /'s */
530 trim_string(name,"/","/");
533 * Ensure saved_last_component is valid even if file exists.
535 if(saved_last_component) {
536 end = strrchr(name, '/');
537 if(end)
538 strcpy(saved_last_component, end + 1);
539 else
540 strcpy(saved_last_component, name);
543 if (!case_sensitive &&
544 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
545 strnorm(name);
547 /* check if it's a printer file */
548 if (Connections[cnum].printer)
550 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
552 char *s;
553 fstring name2;
554 sprintf(name2,"%.6s.XXXXXX",remote_machine);
555 /* sanitise the name */
556 for (s=name2 ; *s ; s++)
557 if (!issafe(*s)) *s = '_';
558 strcpy(name,(char *)mktemp(name2));
560 return(True);
563 /* stat the name - if it exists then we are all done! */
564 if (sys_stat(name,&st) == 0)
565 return(True);
567 saved_errno = errno;
569 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
571 /* a special case - if we don't have any mangling chars and are case
572 sensitive then searching won't help */
573 if (case_sensitive && !is_mangled(name) &&
574 !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
575 return(False);
577 /* now we need to recursively match the name against the real
578 directory structure */
580 start = name;
581 while (strncmp(start,"./",2) == 0)
582 start += 2;
584 /* now match each part of the path name separately, trying the names
585 as is first, then trying to scan the directory for matching names */
586 for (;start;start = (end?end+1:(char *)NULL))
588 /* pinpoint the end of this section of the filename */
589 end = strchr(start, '/');
591 /* chop the name at this point */
592 if (end) *end = 0;
594 if(saved_last_component != 0)
595 strcpy(saved_last_component, end ? end + 1 : start);
597 /* check if the name exists up to this point */
598 if (sys_stat(name, &st) == 0)
600 /* it exists. it must either be a directory or this must be
601 the last part of the path for it to be OK */
602 if (end && !(st.st_mode & S_IFDIR))
604 /* an intermediate part of the name isn't a directory */
605 DEBUG(5,("Not a dir %s\n",start));
606 *end = '/';
607 return(False);
610 else
612 pstring rest;
614 *rest = 0;
616 /* remember the rest of the pathname so it can be restored
617 later */
618 if (end) pstrcpy(rest,end+1);
620 /* try to find this part of the path in the directory */
621 if (strchr(start,'?') || strchr(start,'*') ||
622 !scan_directory(dirpath, start, cnum, end?True:False))
624 if (end)
626 /* an intermediate part of the name can't be found */
627 DEBUG(5,("Intermediate not found %s\n",start));
628 *end = '/';
629 /* We need to return the fact that the intermediate
630 name resolution failed. This is used to return an
631 error of ERRbadpath rather than ERRbadfile. Some
632 Windows applications depend on the difference between
633 these two errors.
635 *bad_path = True;
636 return(False);
639 /* just the last part of the name doesn't exist */
640 /* we may need to strupper() or strlower() it in case
641 this conversion is being used for file creation
642 purposes */
643 /* if the filename is of mixed case then don't normalise it */
644 if (!case_preserve &&
645 (!strhasupper(start) || !strhaslower(start)))
646 strnorm(start);
648 /* check on the mangled stack to see if we can recover the
649 base of the filename */
650 if (is_mangled(start))
651 check_mangled_stack(start);
653 DEBUG(5,("New file %s\n",start));
654 return(True);
657 /* restore the rest of the string */
658 if (end)
660 strcpy(start+strlen(start)+1,rest);
661 end = start + strlen(start);
665 /* add to the dirpath that we have resolved so far */
666 if (*dirpath) strcat(dirpath,"/");
667 strcat(dirpath,start);
669 /* restore the / that we wiped out earlier */
670 if (end) *end = '/';
673 /* the name has been resolved */
674 DEBUG(5,("conversion finished %s\n",name));
675 return(True);
679 /****************************************************************************
680 normalise for DOS usage
681 ****************************************************************************/
682 static void disk_norm(int *bsize,int *dfree,int *dsize)
684 /* check if the disk is beyond the max disk size */
685 int maxdisksize = lp_maxdisksize();
686 if (maxdisksize) {
687 /* convert to blocks - and don't overflow */
688 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
689 if (*dsize > maxdisksize) *dsize = maxdisksize;
690 if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
691 applications getting
692 div by 0 errors */
695 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
697 *dfree /= 2;
698 *dsize /= 2;
699 *bsize *= 2;
700 if (*bsize > WORDMAX )
702 *bsize = WORDMAX;
703 if (*dsize > WORDMAX)
704 *dsize = WORDMAX;
705 if (*dfree > WORDMAX)
706 *dfree = WORDMAX;
707 break;
712 /****************************************************************************
713 return number of 1K blocks available on a path and total number
714 ****************************************************************************/
715 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
717 char *df_command = lp_dfree_command();
718 int dfree_retval;
719 #ifdef QUOTAS
720 int dfreeq_retval;
721 int dfreeq = 0;
722 int bsizeq = *bsize;
723 int dsizeq = *dsize;
724 #endif
726 #ifndef NO_STATFS
727 #ifdef USE_STATVFS
728 struct statvfs fs;
729 #else
730 #ifdef ULTRIX
731 struct fs_data fs;
732 #else
733 struct statfs fs;
734 #endif
735 #endif
736 #endif
738 /* possibly use system() to get the result */
739 if (df_command && *df_command)
741 int ret;
742 pstring syscmd;
743 pstring outfile;
745 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
746 sprintf(syscmd,"%s %s",df_command,path);
747 standard_sub_basic(syscmd);
749 ret = smbrun(syscmd,outfile,False);
750 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
753 FILE *f = fopen(outfile,"r");
754 *dsize = 0;
755 *dfree = 0;
756 *bsize = 1024;
757 if (f)
759 fscanf(f,"%d %d %d",dsize,dfree,bsize);
760 fclose(f);
762 else
763 DEBUG(0,("Can't open %s\n",outfile));
766 unlink(outfile);
767 disk_norm(bsize,dfree,dsize);
768 dfree_retval = ((*bsize)/1024)*(*dfree);
769 #ifdef QUOTAS
770 /* Ensure we return the min value between the users quota and
771 what's free on the disk. Thanks to Albrecht Gebhardt
772 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
774 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
776 disk_norm(&bsizeq, &dfreeq, &dsizeq);
777 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
778 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
779 dfree_retval : dfreeq_retval ;
780 /* maybe dfree and dfreeq are calculated using different bsizes
781 so convert dfree from bsize into bsizeq */
782 /* avoid overflows due to multiplication, so do not:
783 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
784 bsize and bsizeq are powers of 2 so its better to
785 to divide them getting a multiplication or division factor
786 for dfree. Rene Nieuwenhuizen (07-10-1997) */
787 if (*bsize >= bsizeq)
788 *dfree = *dfree * (*bsize / bsizeq);
789 else
790 *dfree = *dfree / (bsizeq / *bsize);
791 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
792 *bsize = bsizeq;
793 *dsize = dsizeq;
795 #endif
796 return(dfree_retval);
799 #ifdef NO_STATFS
800 DEBUG(1,("Warning - no statfs function\n"));
801 return(1);
802 #else
803 #ifdef STATFS4
804 if (statfs(path,&fs,sizeof(fs),0) != 0)
805 #else
806 #ifdef USE_STATVFS
807 if (statvfs(path, &fs))
808 #else
809 #ifdef STATFS3
810 if (statfs(path,&fs,sizeof(fs)) == -1)
811 #else
812 if (statfs(path,&fs) == -1)
813 #endif /* STATFS3 */
814 #endif /* USE_STATVFS */
815 #endif /* STATFS4 */
817 DEBUG(3,("dfree call failed code errno=%d\n",errno));
818 *bsize = 1024;
819 *dfree = 1;
820 *dsize = 1;
821 return(((*bsize)/1024)*(*dfree));
824 #ifdef ULTRIX
825 *bsize = 1024;
826 *dfree = fs.fd_req.bfree;
827 *dsize = fs.fd_req.btot;
828 #else
829 #ifdef USE_STATVFS
830 *bsize = fs.f_frsize;
831 #else
832 #ifdef USE_F_FSIZE
833 /* eg: osf1 has f_fsize = fundamental filesystem block size,
834 f_bsize = optimal transfer block size (MX: 94-04-19) */
835 *bsize = fs.f_fsize;
836 #else
837 *bsize = fs.f_bsize;
838 #endif /* STATFS3 */
839 #endif /* USE_STATVFS */
841 #ifdef STATFS4
842 *dfree = fs.f_bfree;
843 #else
844 *dfree = fs.f_bavail;
845 #endif /* STATFS4 */
846 *dsize = fs.f_blocks;
847 #endif /* ULTRIX */
849 #if defined(SCO) || defined(ISC) || defined(MIPS)
850 *bsize = 512;
851 #endif
853 /* handle rediculous bsize values - some OSes are broken */
854 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
856 disk_norm(bsize,dfree,dsize);
858 if (*bsize < 256)
859 *bsize = 512;
860 if ((*dsize)<1)
862 DEBUG(0,("dfree seems to be broken on your system\n"));
863 *dsize = 20*1024*1024/(*bsize);
864 *dfree = MAX(1,*dfree);
866 dfree_retval = ((*bsize)/1024)*(*dfree);
867 #ifdef QUOTAS
868 /* Ensure we return the min value between the users quota and
869 what's free on the disk. Thanks to Albrecht Gebhardt
870 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
872 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
874 disk_norm(&bsizeq, &dfreeq, &dsizeq);
875 dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
876 dfree_retval = ( dfree_retval < dfreeq_retval ) ?
877 dfree_retval : dfreeq_retval ;
878 /* maybe dfree and dfreeq are calculated using different bsizes
879 so convert dfree from bsize into bsizeq */
880 /* avoid overflows due to multiplication, so do not:
881 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
882 bsize and bsizeq are powers of 2 so its better to
883 to divide them getting a multiplication or division factor
884 for dfree. Rene Nieuwenhuizen (07-10-1997) */
885 if (*bsize >= bsizeq)
886 *dfree = *dfree * (*bsize / bsizeq);
887 else
888 *dfree = *dfree / (bsizeq / *bsize);
889 *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
890 *bsize = bsizeq;
891 *dsize = dsizeq;
893 #endif
894 return(dfree_retval);
895 #endif
899 /****************************************************************************
900 wrap it to get filenames right
901 ****************************************************************************/
902 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
904 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
909 /****************************************************************************
910 check a filename - possibly caling reducename
912 This is called by every routine before it allows an operation on a filename.
913 It does any final confirmation necessary to ensure that the filename is
914 a valid one for the user to access.
915 ****************************************************************************/
916 BOOL check_name(char *name,int cnum)
918 BOOL ret;
920 errno = 0;
922 if( IS_VETO_PATH(cnum, name))
924 DEBUG(5,("file path name %s vetoed\n",name));
925 return(0);
928 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
930 /* Check if we are allowing users to follow symlinks */
931 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
932 University of Geneva */
934 #ifdef S_ISLNK
935 if (!lp_symlinks(SNUM(cnum)))
937 struct stat statbuf;
938 if ( (sys_lstat(name,&statbuf) != -1) &&
939 (S_ISLNK(statbuf.st_mode)) )
941 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
942 ret=0;
945 #endif
947 if (!ret)
948 DEBUG(5,("check_name on %s failed\n",name));
950 return(ret);
953 /****************************************************************************
954 check a filename - possibly caling reducename
955 ****************************************************************************/
956 static void check_for_pipe(char *fname)
958 /* special case of pipe opens */
959 char s[10];
960 StrnCpy(s,fname,9);
961 strlower(s);
962 if (strstr(s,"pipe/"))
964 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
965 unix_ERR_class = ERRSRV;
966 unix_ERR_code = ERRaccess;
970 /****************************************************************************
971 fd support routines - attempt to do a sys_open
972 ****************************************************************************/
973 static int fd_attempt_open(char *fname, int flags, int mode)
975 int fd = sys_open(fname,flags,mode);
977 /* Fix for files ending in '.' */
978 if((fd == -1) && (errno == ENOENT) &&
979 (strchr(fname,'.')==NULL))
981 strcat(fname,".");
982 fd = sys_open(fname,flags,mode);
985 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
986 if ((fd == -1) && (errno == ENAMETOOLONG))
988 int max_len;
989 char *p = strrchr(fname, '/');
991 if (p == fname) /* name is "/xxx" */
993 max_len = pathconf("/", _PC_NAME_MAX);
994 p++;
996 else if ((p == NULL) || (p == fname))
998 p = fname;
999 max_len = pathconf(".", _PC_NAME_MAX);
1001 else
1003 *p = '\0';
1004 max_len = pathconf(fname, _PC_NAME_MAX);
1005 *p = '/';
1006 p++;
1008 if (strlen(p) > max_len)
1010 char tmp = p[max_len];
1012 p[max_len] = '\0';
1013 if ((fd = sys_open(fname,flags,mode)) == -1)
1014 p[max_len] = tmp;
1017 #endif
1018 return fd;
1021 /****************************************************************************
1022 fd support routines - attempt to find an already open file by dev
1023 and inode - increments the ref_count of the returned file_fd_struct *.
1024 ****************************************************************************/
1025 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1027 int i;
1028 file_fd_struct *fd_ptr;
1030 if(sbuf == 0)
1031 return 0;
1033 for(i = 0; i <= max_file_fd_used; i++) {
1034 fd_ptr = &FileFd[i];
1035 if((fd_ptr->ref_count > 0) &&
1036 (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1037 (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1038 fd_ptr->ref_count++;
1039 DEBUG(3,
1040 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1041 i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1042 return fd_ptr;
1045 return 0;
1048 /****************************************************************************
1049 fd support routines - attempt to find a empty slot in the FileFd array.
1050 Increments the ref_count of the returned entry.
1051 ****************************************************************************/
1052 static file_fd_struct *fd_get_new()
1054 int i;
1055 file_fd_struct *fd_ptr;
1057 for(i = 0; i < MAX_OPEN_FILES; i++) {
1058 fd_ptr = &FileFd[i];
1059 if(fd_ptr->ref_count == 0) {
1060 fd_ptr->dev = (uint32)-1;
1061 fd_ptr->inode = (uint32)-1;
1062 fd_ptr->fd = -1;
1063 fd_ptr->fd_readonly = -1;
1064 fd_ptr->fd_writeonly = -1;
1065 fd_ptr->real_open_flags = -1;
1066 fd_ptr->ref_count++;
1067 /* Increment max used counter if neccessary, cuts down
1068 on search time when re-using */
1069 if(i > max_file_fd_used)
1070 max_file_fd_used = i;
1071 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1072 i, fd_ptr->dev, fd_ptr->inode));
1073 return fd_ptr;
1076 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1077 n"));
1078 return 0;
1081 /****************************************************************************
1082 fd support routines - attempt to re-open an already open fd as O_RDWR.
1083 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1084 ****************************************************************************/
1085 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1087 int fd = sys_open( fname, O_RDWR, mode);
1089 if(fd == -1)
1090 return;
1092 if(fd_ptr->real_open_flags == O_RDONLY)
1093 fd_ptr->fd_readonly = fd_ptr->fd;
1094 if(fd_ptr->real_open_flags == O_WRONLY)
1095 fd_ptr->fd_writeonly = fd_ptr->fd;
1097 fd_ptr->fd = fd;
1098 fd_ptr->real_open_flags = O_RDWR;
1101 /****************************************************************************
1102 fd support routines - attempt to close the file referenced by this fd.
1103 Decrements the ref_count and returns it.
1104 ****************************************************************************/
1105 static int fd_attempt_close(file_fd_struct *fd_ptr)
1107 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1108 fd_ptr - &FileFd[0],
1109 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1110 fd_ptr->real_open_flags,
1111 fd_ptr->ref_count));
1112 if(fd_ptr->ref_count > 0) {
1113 fd_ptr->ref_count--;
1114 if(fd_ptr->ref_count == 0) {
1115 if(fd_ptr->fd != -1)
1116 close(fd_ptr->fd);
1117 if(fd_ptr->fd_readonly != -1)
1118 close(fd_ptr->fd_readonly);
1119 if(fd_ptr->fd_writeonly != -1)
1120 close(fd_ptr->fd_writeonly);
1121 fd_ptr->fd = -1;
1122 fd_ptr->fd_readonly = -1;
1123 fd_ptr->fd_writeonly = -1;
1124 fd_ptr->real_open_flags = -1;
1125 fd_ptr->dev = (uint32)-1;
1126 fd_ptr->inode = (uint32)-1;
1129 return fd_ptr->ref_count;
1132 /****************************************************************************
1133 open a file
1134 ****************************************************************************/
1135 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1137 extern struct current_user current_user;
1138 pstring fname;
1139 struct stat statbuf;
1140 file_fd_struct *fd_ptr;
1141 files_struct *fsp = &Files[fnum];
1143 fsp->open = False;
1144 fsp->fd_ptr = 0;
1145 fsp->granted_oplock = False;
1146 errno = EPERM;
1148 pstrcpy(fname,fname1);
1150 /* check permissions */
1151 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1153 DEBUG(3,("Permission denied opening %s\n",fname));
1154 check_for_pipe(fname);
1155 return;
1158 /* this handles a bug in Win95 - it doesn't say to create the file when it
1159 should */
1160 if (Connections[cnum].printer)
1161 flags |= O_CREAT;
1164 if (flags == O_WRONLY)
1165 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1169 * Ensure we have a valid struct stat so we can search the
1170 * open fd table.
1172 if(sbuf == 0) {
1173 if(stat(fname, &statbuf) < 0) {
1174 if(errno != ENOENT) {
1175 DEBUG(3,("Error doing stat on file %s (%s)\n",
1176 fname,strerror(errno)));
1178 check_for_pipe(fname);
1179 return;
1181 sbuf = 0;
1182 } else {
1183 sbuf = &statbuf;
1188 * Check to see if we have this file already
1189 * open. If we do, just use the already open fd and increment the
1190 * reference count (fd_get_already_open increments the ref_count).
1192 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1194 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1196 /* File was already open. */
1197 if((flags & O_CREAT) && (flags & O_EXCL)) {
1198 fd_ptr->ref_count--;
1199 errno = EEXIST;
1200 return;
1204 * If not opened O_RDWR try
1205 * and do that here - a chmod may have been done
1206 * between the last open and now.
1208 if(fd_ptr->real_open_flags != O_RDWR)
1209 fd_attempt_reopen(fname, mode, fd_ptr);
1212 * Ensure that if we wanted write access
1213 * it has been opened for write, and if we wanted read it
1214 * was open for read.
1216 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1217 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1218 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1219 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1220 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1221 check_for_pipe(fname);
1222 fd_ptr->ref_count--;
1223 return;
1226 } else {
1227 int open_flags;
1228 /* We need to allocate a new file_fd_struct (this increments the
1229 ref_count). */
1230 if((fd_ptr = fd_get_new()) == 0)
1231 return;
1233 * Whatever the requested flags, attempt read/write access,
1234 * as we don't know what flags future file opens may require.
1235 * If this fails, try again with the required flags.
1236 * Even if we open read/write when only read access was
1237 * requested the setting of the can_write flag in
1238 * the file_struct will protect us from errant
1239 * write requests. We never need to worry about O_APPEND
1240 * as this is not set anywhere in Samba.
1242 fd_ptr->real_open_flags = O_RDWR;
1243 /* Set the flags as needed without the read/write modes. */
1244 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1245 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1247 * On some systems opening a file for R/W access on a read only
1248 * filesystems sets errno to EROFS.
1250 #ifdef EROFS
1251 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1252 #else /* No EROFS */
1253 if((fd_ptr->fd == -1) && (errno == EACCES)) {
1254 #endif /* EROFS */
1255 if(flags & O_WRONLY) {
1256 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1257 fd_ptr->real_open_flags = O_WRONLY;
1258 } else {
1259 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1260 fd_ptr->real_open_flags = O_RDONLY;
1265 if ((fd_ptr->fd >=0) &&
1266 Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1267 pstring dname;
1268 int dum1,dum2,dum3;
1269 char *p;
1270 pstrcpy(dname,fname);
1271 p = strrchr(dname,'/');
1272 if (p) *p = 0;
1273 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
1274 lp_minprintspace(SNUM(cnum))) {
1275 fd_attempt_close(fd_ptr);
1276 fsp->fd_ptr = 0;
1277 if(fd_ptr->ref_count == 0)
1278 sys_unlink(fname);
1279 errno = ENOSPC;
1280 return;
1284 if (fd_ptr->fd < 0)
1286 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1287 fname,strerror(errno),flags));
1288 /* Ensure the ref_count is decremented. */
1289 fd_attempt_close(fd_ptr);
1290 check_for_pipe(fname);
1291 return;
1294 if (fd_ptr->fd >= 0)
1296 if(sbuf == 0) {
1297 /* Do the fstat */
1298 if(fstat(fd_ptr->fd, &statbuf) == -1) {
1299 /* Error - backout !! */
1300 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1301 fd_ptr->fd, fname,strerror(errno)));
1302 /* Ensure the ref_count is decremented. */
1303 fd_attempt_close(fd_ptr);
1304 return;
1306 sbuf = &statbuf;
1308 /* Set the correct entries in fd_ptr. */
1309 fd_ptr->dev = (uint32)sbuf->st_dev;
1310 fd_ptr->inode = (uint32)sbuf->st_ino;
1312 fsp->fd_ptr = fd_ptr;
1313 Connections[cnum].num_files_open++;
1314 fsp->mode = sbuf->st_mode;
1315 GetTimeOfDay(&fsp->open_time);
1316 fsp->uid = current_user.id;
1317 fsp->size = 0;
1318 fsp->pos = -1;
1319 fsp->open = True;
1320 fsp->mmap_ptr = NULL;
1321 fsp->mmap_size = 0;
1322 fsp->can_lock = True;
1323 fsp->can_read = ((flags & O_WRONLY)==0);
1324 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1325 fsp->share_mode = 0;
1326 fsp->print_file = Connections[cnum].printer;
1327 fsp->modified = False;
1328 fsp->granted_oplock = False;
1329 fsp->cnum = cnum;
1330 string_set(&fsp->name,dos_to_unix(fname,False));
1331 fsp->wbmpx_ptr = NULL;
1334 * If the printer is marked as postscript output a leading
1335 * file identifier to ensure the file is treated as a raw
1336 * postscript file.
1337 * This has a similar effect as CtrlD=0 in WIN.INI file.
1338 * tim@fsg.com 09/06/94
1340 if (fsp->print_file && POSTSCRIPT(cnum) &&
1341 fsp->can_write)
1343 DEBUG(3,("Writing postscript line\n"));
1344 write_file(fnum,"%!\n",3);
1347 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1348 timestring(),Connections[cnum].user,fname,
1349 BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1350 Connections[cnum].num_files_open,fnum));
1354 #if USE_MMAP
1355 /* mmap it if read-only */
1356 if (!fsp->can_write)
1358 fsp->mmap_size = file_size(fname);
1359 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1360 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1362 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1364 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1365 fsp->mmap_ptr = NULL;
1368 #endif
1371 /*******************************************************************
1372 sync a file
1373 ********************************************************************/
1374 void sync_file(int fnum)
1376 #ifndef NO_FSYNC
1377 fsync(Files[fnum].fd_ptr->fd);
1378 #endif
1381 /****************************************************************************
1382 run a file if it is a magic script
1383 ****************************************************************************/
1384 static void check_magic(int fnum,int cnum)
1386 if (!*lp_magicscript(SNUM(cnum)))
1387 return;
1389 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1392 char *p;
1393 if (!(p = strrchr(Files[fnum].name,'/')))
1394 p = Files[fnum].name;
1395 else
1396 p++;
1398 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1399 return;
1403 int ret;
1404 pstring magic_output;
1405 pstring fname;
1406 pstrcpy(fname,Files[fnum].name);
1408 if (*lp_magicoutput(SNUM(cnum)))
1409 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1410 else
1411 sprintf(magic_output,"%s.out",fname);
1413 chmod(fname,0755);
1414 ret = smbrun(fname,magic_output,False);
1415 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1416 unlink(fname);
1421 /****************************************************************************
1422 close a file - possibly invalidating the read prediction
1424 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1425 operation otherwise it came as the result of some other operation such as
1426 the closing of the connection. In the latter case printing and
1427 magic scripts are not run
1428 ****************************************************************************/
1429 void close_file(int fnum, BOOL normal_close)
1431 files_struct *fs_p = &Files[fnum];
1432 int cnum = fs_p->cnum;
1433 uint32 dev = fs_p->fd_ptr->dev;
1434 uint32 inode = fs_p->fd_ptr->inode;
1435 int token;
1437 #if USE_READ_PREDICTION
1438 invalidate_read_prediction(fs_p->fd_ptr->fd);
1439 #endif
1441 fs_p->open = False;
1442 Connections[cnum].num_files_open--;
1443 if(fs_p->wbmpx_ptr)
1445 free((char *)fs_p->wbmpx_ptr);
1446 fs_p->wbmpx_ptr = NULL;
1449 #if USE_MMAP
1450 if(fs_p->mmap_ptr)
1452 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1453 fs_p->mmap_ptr = NULL;
1455 #endif
1457 if (lp_share_modes(SNUM(cnum)))
1459 lock_share_entry( cnum, dev, inode, &token);
1460 del_share_mode(token, fnum);
1463 fd_attempt_close(fs_p->fd_ptr);
1465 if (lp_share_modes(SNUM(cnum)))
1466 unlock_share_entry( cnum, dev, inode, token);
1468 /* NT uses smbclose to start a print - weird */
1469 if (normal_close && fs_p->print_file)
1470 print_file(fnum);
1472 /* check for magic scripts */
1473 if (normal_close)
1474 check_magic(fnum,cnum);
1476 if(fs_p->granted_oplock == True)
1477 global_oplocks_open--;
1479 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1480 timestring(),Connections[cnum].user,fs_p->name,
1481 Connections[cnum].num_files_open));
1484 enum {AFAIL,AREAD,AWRITE,AALL};
1486 /*******************************************************************
1487 reproduce the share mode access table
1488 ********************************************************************/
1489 static int access_table(int new_deny,int old_deny,int old_mode,
1490 int share_pid,char *fname)
1492 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1494 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1495 int pid = getpid();
1496 if (old_deny == new_deny && share_pid == pid)
1497 return(AALL);
1499 if (old_mode == 0) return(AREAD);
1501 /* the new smbpub.zip spec says that if the file extension is
1502 .com, .dll, .exe or .sym then allow the open. I will force
1503 it to read-only as this seems sensible although the spec is
1504 a little unclear on this. */
1505 if ((fname = strrchr(fname,'.'))) {
1506 if (strequal(fname,".com") ||
1507 strequal(fname,".dll") ||
1508 strequal(fname,".exe") ||
1509 strequal(fname,".sym"))
1510 return(AREAD);
1513 return(AFAIL);
1516 switch (new_deny)
1518 case DENY_WRITE:
1519 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1520 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1521 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1522 return(AFAIL);
1523 case DENY_READ:
1524 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1525 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1526 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1527 return(AFAIL);
1528 case DENY_NONE:
1529 if (old_deny==DENY_WRITE) return(AREAD);
1530 if (old_deny==DENY_READ) return(AWRITE);
1531 if (old_deny==DENY_NONE) return(AALL);
1532 return(AFAIL);
1534 return(AFAIL);
1537 /*******************************************************************
1538 check if the share mode on a file allows it to be deleted or unlinked
1539 return True if sharing doesn't prevent the operation
1540 ********************************************************************/
1541 BOOL check_file_sharing(int cnum,char *fname)
1543 int i;
1544 int ret = False;
1545 share_mode_entry *old_shares = 0;
1546 int num_share_modes;
1547 struct stat sbuf;
1548 int token;
1549 int pid = getpid();
1550 uint32 dev, inode;
1552 if(!lp_share_modes(SNUM(cnum)))
1553 return True;
1555 if (stat(fname,&sbuf) == -1) return(True);
1557 dev = (uint32)sbuf.st_dev;
1558 inode = (uint32)sbuf.st_ino;
1560 lock_share_entry(cnum, dev, inode, &token);
1561 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1564 * Check if the share modes will give us access.
1567 if(num_share_modes != 0)
1569 BOOL broke_oplock;
1574 broke_oplock = False;
1575 for(i = 0; i < num_share_modes; i++)
1577 share_mode_entry *share_entry = &old_shares[i];
1580 * Break oplocks before checking share modes. See comment in
1581 * open_file_shared for details.
1582 * Check if someone has an oplock on this file. If so we must
1583 * break it before continuing.
1585 if(share_entry->op_type & BATCH_OPLOCK)
1588 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1589 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1591 /* Oplock break.... */
1592 unlock_share_entry(cnum, dev, inode, token);
1593 if(request_oplock_break(share_entry, dev, inode) == False)
1595 free((char *)old_shares);
1596 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1597 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1598 return False;
1600 lock_share_entry(cnum, dev, inode, &token);
1601 broke_oplock = True;
1602 break;
1605 /* someone else has a share lock on it, check to see
1606 if we can too */
1607 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1608 goto free_and_exit;
1610 } /* end for */
1612 if(broke_oplock)
1614 free((char *)old_shares);
1615 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1617 } while(broke_oplock);
1620 /* XXXX exactly what share mode combinations should be allowed for
1621 deleting/renaming? */
1622 /* If we got here then either there were no share modes or
1623 all share modes were DENY_DOS and the pid == getpid() */
1624 ret = True;
1626 free_and_exit:
1628 unlock_share_entry(cnum, dev, inode, token);
1629 if(old_shares != NULL)
1630 free((char *)old_shares);
1631 return(ret);
1634 /****************************************************************************
1635 C. Hoch 11/22/95
1636 Helper for open_file_shared.
1637 Truncate a file after checking locking; close file if locked.
1638 **************************************************************************/
1639 static void truncate_unless_locked(int fnum, int cnum, int token,
1640 BOOL *share_locked)
1642 if (Files[fnum].can_write){
1643 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1644 /* If share modes are in force for this connection we
1645 have the share entry locked. Unlock it before closing. */
1646 if (*share_locked && lp_share_modes(SNUM(cnum)))
1647 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1648 Files[fnum].fd_ptr->inode, token);
1649 close_file(fnum,False);
1650 /* Share mode no longer locked. */
1651 *share_locked = False;
1652 errno = EACCES;
1653 unix_ERR_class = ERRDOS;
1654 unix_ERR_code = ERRlock;
1656 else
1657 ftruncate(Files[fnum].fd_ptr->fd,0);
1661 /****************************************************************************
1662 check if we can open a file with a share mode
1663 ****************************************************************************/
1664 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1665 BOOL fcbopen, int *flags)
1667 int old_open_mode = share->share_mode &0xF;
1668 int old_deny_mode = (share->share_mode >>4)&7;
1670 if (old_deny_mode > 4 || old_open_mode > 2)
1672 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1673 deny_mode,old_deny_mode,old_open_mode,fname));
1674 return False;
1678 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1679 share->pid,fname);
1681 if ((access_allowed == AFAIL) ||
1682 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1683 (access_allowed == AREAD && *flags == O_WRONLY) ||
1684 (access_allowed == AWRITE && *flags == O_RDONLY))
1686 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1687 deny_mode,old_deny_mode,old_open_mode,
1688 share->pid,fname, fcbopen, *flags, access_allowed));
1689 return False;
1692 if (access_allowed == AREAD)
1693 *flags = O_RDONLY;
1695 if (access_allowed == AWRITE)
1696 *flags = O_WRONLY;
1699 return True;
1702 /****************************************************************************
1703 open a file with a share mode
1704 ****************************************************************************/
1705 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1706 int mode,int oplock_request, int *Access,int *action)
1708 files_struct *fs_p = &Files[fnum];
1709 int flags=0;
1710 int flags2=0;
1711 int deny_mode = (share_mode>>4)&7;
1712 struct stat sbuf;
1713 BOOL file_existed = file_exist(fname,&sbuf);
1714 BOOL share_locked = False;
1715 BOOL fcbopen = False;
1716 int token;
1717 uint32 dev = 0;
1718 uint32 inode = 0;
1719 int num_share_modes = 0;
1721 fs_p->open = False;
1722 fs_p->fd_ptr = 0;
1724 /* this is for OS/2 EAs - try and say we don't support them */
1725 if (strstr(fname,".+,;=[]."))
1727 unix_ERR_class = ERRDOS;
1728 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1729 #ifdef OS2_WPS_FIX
1730 unix_ERR_code = ERRcannotopen;
1731 #else /* OS2_WPS_FIX */
1732 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1733 #endif /* OS2_WPS_FIX */
1735 return;
1738 if ((ofun & 0x3) == 0 && file_existed)
1740 errno = EEXIST;
1741 return;
1744 if (ofun & 0x10)
1745 flags2 |= O_CREAT;
1746 if ((ofun & 0x3) == 2)
1747 flags2 |= O_TRUNC;
1749 /* note that we ignore the append flag as
1750 append does not mean the same thing under dos and unix */
1752 switch (share_mode&0xF)
1754 case 1:
1755 flags = O_WRONLY;
1756 break;
1757 case 0xF:
1758 fcbopen = True;
1759 flags = O_RDWR;
1760 break;
1761 case 2:
1762 flags = O_RDWR;
1763 break;
1764 default:
1765 flags = O_RDONLY;
1766 break;
1769 if (flags != O_RDONLY && file_existed &&
1770 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1772 if (!fcbopen)
1774 errno = EACCES;
1775 return;
1777 flags = O_RDONLY;
1780 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1782 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1783 errno = EINVAL;
1784 return;
1787 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1789 if (lp_share_modes(SNUM(cnum)))
1791 int i;
1792 share_mode_entry *old_shares = 0;
1794 if (file_existed)
1796 dev = (uint32)sbuf.st_dev;
1797 inode = (uint32)sbuf.st_ino;
1798 lock_share_entry(cnum, dev, inode, &token);
1799 share_locked = True;
1800 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1804 * Check if the share modes will give us access.
1807 if(share_locked && (num_share_modes != 0))
1809 BOOL broke_oplock;
1814 broke_oplock = False;
1815 for(i = 0; i < num_share_modes; i++)
1817 share_mode_entry *share_entry = &old_shares[i];
1820 * By observation of NetBench, oplocks are broken *before* share
1821 * modes are checked. This allows a file to be closed by the client
1822 * if the share mode would deny access and the client has an oplock.
1823 * Check if someone has an oplock on this file. If so we must break
1824 * it before continuing.
1826 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1829 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1830 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1832 /* Oplock break.... */
1833 unlock_share_entry(cnum, dev, inode, token);
1834 if(request_oplock_break(share_entry, dev, inode) == False)
1836 free((char *)old_shares);
1837 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1838 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1839 errno = EACCES;
1840 unix_ERR_class = ERRDOS;
1841 unix_ERR_code = ERRbadshare;
1842 return;
1844 lock_share_entry(cnum, dev, inode, &token);
1845 broke_oplock = True;
1846 break;
1849 /* someone else has a share lock on it, check to see
1850 if we can too */
1851 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1853 free((char *)old_shares);
1854 unlock_share_entry(cnum, dev, inode, token);
1855 errno = EACCES;
1856 unix_ERR_class = ERRDOS;
1857 unix_ERR_code = ERRbadshare;
1858 return;
1861 } /* end for */
1863 if(broke_oplock)
1865 free((char *)old_shares);
1866 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1868 } while(broke_oplock);
1871 if(old_shares != 0)
1872 free((char *)old_shares);
1875 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1876 flags,flags2,mode));
1878 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1879 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1881 flags = O_RDONLY;
1882 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1885 if (fs_p->open)
1887 int open_mode=0;
1889 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1891 /* We created the file - thus we must now lock the share entry before creating it. */
1892 dev = fs_p->fd_ptr->dev;
1893 inode = fs_p->fd_ptr->inode;
1894 lock_share_entry(cnum, dev, inode, &token);
1895 share_locked = True;
1898 switch (flags)
1900 case O_RDONLY:
1901 open_mode = 0;
1902 break;
1903 case O_RDWR:
1904 open_mode = 2;
1905 break;
1906 case O_WRONLY:
1907 open_mode = 1;
1908 break;
1911 fs_p->share_mode = (deny_mode<<4) | open_mode;
1913 if (Access)
1914 (*Access) = open_mode;
1916 if (action)
1918 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1919 if (!file_existed) *action = 2;
1920 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1922 /* We must create the share mode entry before truncate as
1923 truncate can fail due to locking and have to close the
1924 file (which expects the share_mode_entry to be there).
1926 if (lp_share_modes(SNUM(cnum)))
1928 uint16 port = 0;
1929 /* JRA. Currently this only services Exlcusive and batch
1930 oplocks (no other opens on this file). This needs to
1931 be extended to level II oplocks (multiple reader
1932 oplocks). */
1934 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) &&
1935 !IS_VETO_OPLOCK_PATH(cnum,fname))
1937 fs_p->granted_oplock = True;
1938 global_oplocks_open++;
1939 port = oplock_port;
1941 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1942 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1945 else
1947 port = 0;
1948 oplock_request = 0;
1950 set_share_mode(token, fnum, port, oplock_request);
1953 if ((flags2&O_TRUNC) && file_existed)
1954 truncate_unless_locked(fnum,cnum,token,&share_locked);
1957 if (share_locked && lp_share_modes(SNUM(cnum)))
1958 unlock_share_entry( cnum, dev, inode, token);
1961 /****************************************************************************
1962 seek a file. Try to avoid the seek if possible
1963 ****************************************************************************/
1964 int seek_file(int fnum,uint32 pos)
1966 uint32 offset = 0;
1967 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1968 offset = 3;
1970 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1971 - offset);
1972 return(Files[fnum].pos);
1975 /****************************************************************************
1976 read from a file
1977 ****************************************************************************/
1978 int read_file(int fnum,char *data,uint32 pos,int n)
1980 int ret=0,readret;
1982 #if USE_READ_PREDICTION
1983 if (!Files[fnum].can_write)
1985 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1987 data += ret;
1988 n -= ret;
1989 pos += ret;
1991 #endif
1993 #if USE_MMAP
1994 if (Files[fnum].mmap_ptr)
1996 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1997 if (num > 0)
1999 memcpy(data,Files[fnum].mmap_ptr+pos,num);
2000 data += num;
2001 pos += num;
2002 n -= num;
2003 ret += num;
2006 #endif
2008 if (n <= 0)
2009 return(ret);
2011 if (seek_file(fnum,pos) != pos)
2013 DEBUG(3,("Failed to seek to %d\n",pos));
2014 return(ret);
2017 if (n > 0) {
2018 readret = read(Files[fnum].fd_ptr->fd,data,n);
2019 if (readret > 0) ret += readret;
2022 return(ret);
2026 /****************************************************************************
2027 write to a file
2028 ****************************************************************************/
2029 int write_file(int fnum,char *data,int n)
2031 if (!Files[fnum].can_write) {
2032 errno = EPERM;
2033 return(0);
2036 if (!Files[fnum].modified) {
2037 struct stat st;
2038 Files[fnum].modified = True;
2039 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2040 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2041 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2042 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2047 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2051 /****************************************************************************
2052 load parameters specific to a connection/service
2053 ****************************************************************************/
2054 BOOL become_service(int cnum,BOOL do_chdir)
2056 extern char magic_char;
2057 static int last_cnum = -1;
2058 int snum;
2060 if (!OPEN_CNUM(cnum))
2062 last_cnum = -1;
2063 return(False);
2066 Connections[cnum].lastused = smb_last_time;
2068 snum = SNUM(cnum);
2070 if (do_chdir &&
2071 ChDir(Connections[cnum].connectpath) != 0 &&
2072 ChDir(Connections[cnum].origpath) != 0)
2074 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2075 Connections[cnum].connectpath,cnum));
2076 return(False);
2079 if (cnum == last_cnum)
2080 return(True);
2082 last_cnum = cnum;
2084 case_default = lp_defaultcase(snum);
2085 case_preserve = lp_preservecase(snum);
2086 short_case_preserve = lp_shortpreservecase(snum);
2087 case_mangle = lp_casemangle(snum);
2088 case_sensitive = lp_casesensitive(snum);
2089 magic_char = lp_magicchar(snum);
2090 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2091 return(True);
2095 /****************************************************************************
2096 find a service entry
2097 ****************************************************************************/
2098 int find_service(char *service)
2100 int iService;
2102 string_sub(service,"\\","/");
2104 iService = lp_servicenumber(service);
2106 /* now handle the special case of a home directory */
2107 if (iService < 0)
2109 char *phome_dir = get_home_dir(service);
2110 DEBUG(3,("checking for home directory %s gave %s\n",service,
2111 phome_dir?phome_dir:"(NULL)"));
2112 if (phome_dir)
2114 int iHomeService;
2115 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2117 lp_add_home(service,iHomeService,phome_dir);
2118 iService = lp_servicenumber(service);
2123 /* If we still don't have a service, attempt to add it as a printer. */
2124 if (iService < 0)
2126 int iPrinterService;
2128 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2130 char *pszTemp;
2132 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2133 pszTemp = PRINTCAP;
2134 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2136 DEBUG(3,("%s is a valid printer name\n", service));
2137 DEBUG(3,("adding %s as a printer service\n", service));
2138 lp_add_printer(service,iPrinterService);
2139 iService = lp_servicenumber(service);
2140 if (iService < 0)
2141 DEBUG(0,("failed to add %s as a printer service!\n", service));
2143 else
2144 DEBUG(3,("%s is not a valid printer name\n", service));
2148 /* just possibly it's a default service? */
2149 if (iService < 0)
2151 char *defservice = lp_defaultservice();
2152 if (defservice && *defservice && !strequal(defservice,service)) {
2153 iService = find_service(defservice);
2154 if (iService >= 0) {
2155 string_sub(service,"_","/");
2156 iService = lp_add_service(service,iService);
2161 if (iService >= 0)
2162 if (!VALID_SNUM(iService))
2164 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2165 iService = -1;
2168 if (iService < 0)
2169 DEBUG(3,("find_service() failed to find service %s\n", service));
2171 return (iService);
2175 /****************************************************************************
2176 create an error packet from a cached error.
2177 ****************************************************************************/
2178 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2180 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2182 int32 eclass = wbmpx->wr_errclass;
2183 int32 err = wbmpx->wr_error;
2185 /* We can now delete the auxiliary struct */
2186 free((char *)wbmpx);
2187 Files[fnum].wbmpx_ptr = NULL;
2188 return error_packet(inbuf,outbuf,eclass,err,line);
2192 struct
2194 int unixerror;
2195 int smbclass;
2196 int smbcode;
2197 } unix_smb_errmap[] =
2199 {EPERM,ERRDOS,ERRnoaccess},
2200 {EACCES,ERRDOS,ERRnoaccess},
2201 {ENOENT,ERRDOS,ERRbadfile},
2202 {ENOTDIR,ERRDOS,ERRbadpath},
2203 {EIO,ERRHRD,ERRgeneral},
2204 {EBADF,ERRSRV,ERRsrverror},
2205 {EINVAL,ERRSRV,ERRsrverror},
2206 {EEXIST,ERRDOS,ERRfilexists},
2207 {ENFILE,ERRDOS,ERRnofids},
2208 {EMFILE,ERRDOS,ERRnofids},
2209 {ENOSPC,ERRHRD,ERRdiskfull},
2210 #ifdef EDQUOT
2211 {EDQUOT,ERRHRD,ERRdiskfull},
2212 #endif
2213 #ifdef ENOTEMPTY
2214 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2215 #endif
2216 #ifdef EXDEV
2217 {EXDEV,ERRDOS,ERRdiffdevice},
2218 #endif
2219 {EROFS,ERRHRD,ERRnowrite},
2220 {0,0,0}
2223 /****************************************************************************
2224 create an error packet from errno
2225 ****************************************************************************/
2226 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2228 int eclass=def_class;
2229 int ecode=def_code;
2230 int i=0;
2232 if (unix_ERR_class != SUCCESS)
2234 eclass = unix_ERR_class;
2235 ecode = unix_ERR_code;
2236 unix_ERR_class = SUCCESS;
2237 unix_ERR_code = 0;
2239 else
2241 while (unix_smb_errmap[i].smbclass != 0)
2243 if (unix_smb_errmap[i].unixerror == errno)
2245 eclass = unix_smb_errmap[i].smbclass;
2246 ecode = unix_smb_errmap[i].smbcode;
2247 break;
2249 i++;
2253 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2257 /****************************************************************************
2258 create an error packet. Normally called using the ERROR() macro
2259 ****************************************************************************/
2260 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2262 int outsize = set_message(outbuf,0,0,True);
2263 int cmd;
2264 cmd = CVAL(inbuf,smb_com);
2266 CVAL(outbuf,smb_rcls) = error_class;
2267 SSVAL(outbuf,smb_err,error_code);
2269 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2270 timestring(),
2271 line,
2272 (int)CVAL(inbuf,smb_com),
2273 smb_fn_name(CVAL(inbuf,smb_com)),
2274 error_class,
2275 error_code));
2277 if (errno != 0)
2278 DEBUG(3,("error string = %s\n",strerror(errno)));
2280 return(outsize);
2284 #ifndef SIGCLD_IGNORE
2285 /****************************************************************************
2286 this prevents zombie child processes
2287 ****************************************************************************/
2288 static int sig_cld()
2290 static int depth = 0;
2291 if (depth != 0)
2293 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2294 depth=0;
2295 return(0);
2297 depth++;
2299 BlockSignals(True,SIGCLD);
2300 DEBUG(5,("got SIGCLD\n"));
2302 #ifdef USE_WAITPID
2303 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2304 #endif
2306 /* Stop zombies */
2307 /* Stevens, Adv. Unix Prog. says that on system V you must call
2308 wait before reinstalling the signal handler, because the kernel
2309 calls the handler from within the signal-call when there is a
2310 child that has exited. This would lead to an infinite recursion
2311 if done vice versa. */
2313 #ifndef DONT_REINSTALL_SIG
2314 #ifdef SIGCLD_IGNORE
2315 signal(SIGCLD, SIG_IGN);
2316 #else
2317 signal(SIGCLD, SIGNAL_CAST sig_cld);
2318 #endif
2319 #endif
2321 #ifndef USE_WAITPID
2322 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2323 #endif
2324 depth--;
2325 BlockSignals(False,SIGCLD);
2326 return 0;
2328 #endif
2330 /****************************************************************************
2331 this is called when the client exits abruptly
2332 **************************************************************************/
2333 static int sig_pipe()
2335 struct cli_state *cli;
2336 BlockSignals(True,SIGPIPE);
2338 if ((cli = server_client()) && cli->initialised) {
2339 DEBUG(3,("lost connection to password server\n"));
2340 cli_shutdown(cli);
2341 #ifndef DONT_REINSTALL_SIG
2342 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2343 #endif
2344 BlockSignals(False,SIGPIPE);
2345 return 0;
2348 exit_server("Got sigpipe\n");
2349 return(0);
2352 /****************************************************************************
2353 open the socket communication
2354 ****************************************************************************/
2355 static BOOL open_sockets(BOOL is_daemon,int port)
2357 extern int Client;
2359 if (is_daemon)
2361 int num_interfaces = iface_count();
2362 int fd_listenset[FD_SETSIZE];
2363 fd_set listen_set;
2364 int s;
2365 int i;
2367 /* Stop zombies */
2368 #ifdef SIGCLD_IGNORE
2369 signal(SIGCLD, SIG_IGN);
2370 #else
2371 signal(SIGCLD, SIGNAL_CAST sig_cld);
2372 #endif
2374 if(atexit_set == 0)
2375 atexit(killkids);
2377 FD_ZERO(&listen_set);
2379 if(lp_interfaces() && lp_bind_interfaces_only())
2381 /* We have been given an interfaces line, and been
2382 told to only bind to those interfaces. Create a
2383 socket per interface and bind to only these.
2386 if(num_interfaces > FD_SETSIZE)
2388 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2389 max can be %d\n", num_interfaces, FD_SETSIZE));
2390 return False;
2393 /* Now open a listen socket for each of the interfaces. */
2394 for(i = 0; i < num_interfaces; i++)
2396 struct in_addr *ifip = iface_n_ip(i);
2398 if(ifip == NULL)
2400 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2401 continue;
2403 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2404 if(s == -1)
2405 return False;
2406 /* ready to listen */
2407 if (listen(s, 5) == -1)
2409 DEBUG(0,("listen: %s\n",strerror(errno)));
2410 close(s);
2411 return False;
2413 FD_SET(s,&listen_set);
2416 else
2418 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2419 num_interfaces = 1;
2421 /* open an incoming socket */
2422 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2423 if (s == -1)
2424 return(False);
2426 /* ready to listen */
2427 if (listen(s, 5) == -1)
2429 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2430 close(s);
2431 return False;
2434 fd_listenset[0] = s;
2435 FD_SET(s,&listen_set);
2438 /* now accept incoming connections - forking a new process
2439 for each incoming connection */
2440 DEBUG(2,("waiting for a connection\n"));
2441 while (1)
2443 fd_set lfds;
2444 int num;
2446 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2448 num = sys_select(&lfds,NULL);
2450 if (num == -1 && errno == EINTR)
2451 continue;
2453 /* Find the sockets that are read-ready - accept on these. */
2454 for( ; num > 0; num--)
2456 struct sockaddr addr;
2457 int in_addrlen = sizeof(addr);
2459 s = -1;
2460 for(i = 0; i < num_interfaces; i++)
2462 if(FD_ISSET(fd_listenset[i],&lfds))
2464 s = fd_listenset[i];
2465 /* Clear this so we don't look at it again. */
2466 FD_CLR(fd_listenset[i],&lfds);
2467 break;
2471 Client = accept(s,&addr,&in_addrlen);
2473 if (Client == -1 && errno == EINTR)
2474 continue;
2476 if (Client == -1)
2478 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2479 continue;
2482 #ifdef NO_FORK_DEBUG
2483 #ifndef NO_SIGNAL_TEST
2484 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2485 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2486 #endif /* NO_SIGNAL_TEST */
2487 return True;
2488 #else /* NO_FORK_DEBUG */
2489 if (Client != -1 && fork()==0)
2491 /* Child code ... */
2493 #ifndef NO_SIGNAL_TEST
2494 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2495 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2496 #endif /* NO_SIGNAL_TEST */
2497 /* close the listening socket(s) */
2498 for(i = 0; i < num_interfaces; i++)
2499 close(fd_listenset[i]);
2501 /* close our standard file descriptors */
2502 close_low_fds();
2503 am_parent = 0;
2505 set_socket_options(Client,"SO_KEEPALIVE");
2506 set_socket_options(Client,user_socket_options);
2508 /* Reset global variables in util.c so that
2509 client substitutions will be done correctly
2510 in the process.
2512 reset_globals_after_fork();
2513 return True;
2515 close(Client); /* The parent doesn't need this socket */
2516 #endif /NO_FORK_DEBUG */
2517 } /* end for num */
2518 } /* end while 1 */
2519 } /* end if is_daemon */
2520 else
2522 /* Started from inetd. fd 0 is the socket. */
2523 /* We will abort gracefully when the client or remote system
2524 goes away */
2525 #ifndef NO_SIGNAL_TEST
2526 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2527 #endif
2528 Client = dup(0);
2530 /* close our standard file descriptors */
2531 close_low_fds();
2533 set_socket_options(Client,"SO_KEEPALIVE");
2534 set_socket_options(Client,user_socket_options);
2537 return True;
2540 /****************************************************************************
2541 process an smb from the client - split out from the process() code so
2542 it can be used by the oplock break code.
2543 ****************************************************************************/
2545 static void process_smb(char *inbuf, char *outbuf)
2547 extern int Client;
2548 static int trans_num;
2549 int msg_type = CVAL(inbuf,0);
2550 int32 len = smb_len(inbuf);
2551 int nread = len + 4;
2553 if (trans_num == 0) {
2554 /* on the first packet, check the global hosts allow/ hosts
2555 deny parameters before doing any parsing of the packet
2556 passed to us by the client. This prevents attacks on our
2557 parsing code from hosts not in the hosts allow list */
2558 if (!check_access(-1)) {
2559 /* send a negative session response "not listining on calling
2560 name" */
2561 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2562 DEBUG(1,("%s Connection denied from %s\n",
2563 timestring(),client_addr()));
2564 send_smb(Client,(char *)buf);
2565 exit_server("connection denied");
2569 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2570 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2572 #ifdef WITH_VTP
2573 if(trans_num == 1 && VT_Check(inbuf))
2575 VT_Process();
2576 return;
2578 #endif
2580 if (msg_type == 0)
2581 show_msg(inbuf);
2583 nread = construct_reply(inbuf,outbuf,nread,max_send);
2585 if(nread > 0)
2587 if (CVAL(outbuf,0) == 0)
2588 show_msg(outbuf);
2590 if (nread != smb_len(outbuf) + 4)
2592 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2593 nread, smb_len(outbuf)));
2595 else
2596 send_smb(Client,outbuf);
2598 trans_num++;
2601 /****************************************************************************
2602 open the oplock IPC socket communication
2603 ****************************************************************************/
2604 static BOOL open_oplock_ipc()
2606 struct sockaddr_in sock_name;
2607 int len = sizeof(sock_name);
2609 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2611 /* Open a lookback UDP socket on a random port. */
2612 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2613 if (oplock_sock == -1)
2615 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2616 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2617 oplock_port = 0;
2618 return(False);
2621 /* Find out the transient UDP port we have been allocated. */
2622 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2624 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2625 strerror(errno)));
2626 close(oplock_sock);
2627 oplock_sock = -1;
2628 oplock_port = 0;
2629 return False;
2631 oplock_port = ntohs(sock_name.sin_port);
2633 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2634 getpid(), oplock_port));
2636 return True;
2639 /****************************************************************************
2640 process an oplock break message.
2641 ****************************************************************************/
2642 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2644 int32 msg_len;
2645 uint16 from_port;
2646 char *msg_start;
2648 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2649 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2651 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2653 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2654 msg_len, from_port));
2656 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2657 only valid request. */
2659 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2661 case OPLOCK_BREAK_CMD:
2662 /* Ensure that the msg length is correct. */
2663 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2665 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2666 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2667 return False;
2670 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2671 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2672 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2673 struct timeval tval;
2674 struct sockaddr_in toaddr;
2676 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2677 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2679 DEBUG(5,("process_local_message: oplock break request from \
2680 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2683 * If we have no record of any currently open oplocks,
2684 * it's not an error, as a close command may have
2685 * just been issued on the file that was oplocked.
2686 * Just return success in this case.
2689 if(global_oplocks_open != 0)
2691 if(oplock_break(dev, inode, &tval) == False)
2693 DEBUG(0,("process_local_message: oplock break failed - \
2694 not returning udp message.\n"));
2695 return False;
2698 else
2700 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2701 oplocks. Returning success.\n"));
2704 /* Send the message back after OR'ing in the 'REPLY' bit. */
2705 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2707 bzero((char *)&toaddr,sizeof(toaddr));
2708 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2709 toaddr.sin_port = htons(from_port);
2710 toaddr.sin_family = AF_INET;
2712 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2713 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2715 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2716 remotepid, strerror(errno)));
2717 return False;
2720 DEBUG(5,("process_local_message: oplock break reply sent to \
2721 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2722 from_port, dev, inode));
2725 break;
2727 * Keep this as a debug case - eventually we can remove it.
2729 case 0x8001:
2730 DEBUG(0,("process_local_message: Received unsolicited break \
2731 reply - dumping info.\n"));
2733 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2735 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2736 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2737 return False;
2741 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2742 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2743 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2745 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2746 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2749 return False;
2751 default:
2752 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2753 (unsigned int)SVAL(msg_start,0)));
2754 return False;
2756 return True;
2759 /****************************************************************************
2760 Process an oplock break directly.
2761 ****************************************************************************/
2762 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2764 extern int Client;
2765 static char *inbuf = NULL;
2766 static char *outbuf = NULL;
2767 files_struct *fsp = NULL;
2768 int fnum;
2769 time_t start_time;
2770 BOOL shutdown_server = False;
2772 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2773 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2775 if(inbuf == NULL)
2777 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2778 if(inbuf == NULL) {
2779 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2780 return False;
2782 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2783 if(outbuf == NULL) {
2784 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2785 free(inbuf);
2786 inbuf = NULL;
2787 return False;
2791 /* We need to search the file open table for the
2792 entry containing this dev and inode, and ensure
2793 we have an oplock on it. */
2794 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2796 if(OPEN_FNUM(fnum))
2798 fsp = &Files[fnum];
2799 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2800 (fsp->open_time.tv_sec == tval->tv_sec) &&
2801 (fsp->open_time.tv_usec == tval->tv_usec))
2802 break;
2806 if(fsp == NULL)
2808 /* The file could have been closed in the meantime - return success. */
2809 DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2810 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2811 return True;
2814 /* Ensure we have an oplock on the file */
2816 /* There is a potential race condition in that an oplock could
2817 have been broken due to another udp request, and yet there are
2818 still oplock break messages being sent in the udp message
2819 queue for this file. So return true if we don't have an oplock,
2820 as we may have just freed it.
2823 if(!fsp->granted_oplock)
2825 DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2826 Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2827 return True;
2830 /* Now comes the horrid part. We must send an oplock break to the client,
2831 and then process incoming messages until we get a close or oplock release.
2834 /* Prepare the SMBlockingX message. */
2835 bzero(outbuf,smb_size);
2836 set_message(outbuf,8,0,True);
2838 SCVAL(outbuf,smb_com,SMBlockingX);
2839 SSVAL(outbuf,smb_tid,fsp->cnum);
2840 SSVAL(outbuf,smb_pid,0xFFFF);
2841 SSVAL(outbuf,smb_uid,0);
2842 SSVAL(outbuf,smb_mid,0xFFFF);
2843 SCVAL(outbuf,smb_vwv0,0xFF);
2844 SSVAL(outbuf,smb_vwv2,fnum);
2845 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2846 /* Change this when we have level II oplocks. */
2847 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2849 send_smb(Client, outbuf);
2851 /* We need this in case a readraw crosses on the wire. */
2852 global_oplock_break = True;
2854 /* Process incoming messages. */
2856 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2857 seconds we should just die.... */
2859 start_time = time(NULL);
2861 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2863 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2866 * Die if we got an error.
2869 if (smb_read_error == READ_EOF)
2870 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2872 if (smb_read_error == READ_ERROR)
2873 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2874 timestring(), strerror(errno)));
2876 if (smb_read_error == READ_TIMEOUT)
2877 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2878 timestring(), OPLOCK_BREAK_TIMEOUT));
2880 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2881 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2882 shutdown_server = True;
2883 break;
2885 process_smb(inbuf, outbuf);
2888 * Die if we go over the time limit.
2891 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2893 DEBUG(0,("%s oplock_break: no break received from client within \
2894 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2895 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2896 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2897 shutdown_server = True;
2898 break;
2902 /* We need this in case a readraw crossed on the wire. */
2903 if(global_oplock_break)
2904 global_oplock_break = False;
2907 * If the client did not respond we must die.
2910 if(shutdown_server)
2912 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2913 timestring()));
2914 close_sockets();
2915 close(oplock_sock);
2916 exit_server("oplock break failure");
2919 if(OPEN_FNUM(fnum))
2921 /* The lockingX reply will have removed the oplock flag
2922 from the sharemode. */
2923 /* Paranoia.... */
2924 fsp->granted_oplock = False;
2925 global_oplocks_open--;
2928 /* Santity check - remove this later. JRA */
2929 if(global_oplocks_open < 0)
2931 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2932 global_oplocks_open));
2933 exit_server("oplock_break: global_oplocks_open < 0");
2936 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2937 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2939 return True;
2942 /****************************************************************************
2943 Send an oplock break message to another smbd process. If the oplock is held
2944 by the local smbd then call the oplock break function directly.
2945 ****************************************************************************/
2947 BOOL request_oplock_break(share_mode_entry *share_entry,
2948 uint32 dev, uint32 inode)
2950 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2951 struct sockaddr_in addr_out;
2952 int pid = getpid();
2954 if(pid == share_entry->pid)
2956 /* We are breaking our own oplock, make sure it's us. */
2957 if(share_entry->op_port != oplock_port)
2959 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2960 should be %d\n", pid, share_entry->op_port, oplock_port));
2961 return False;
2964 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2966 /* Call oplock break direct. */
2967 return oplock_break(dev, inode, &share_entry->time);
2970 /* We need to send a OPLOCK_BREAK_CMD message to the
2971 port in the share mode entry. */
2973 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2974 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2975 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2976 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2977 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2978 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2980 /* set the address and port */
2981 bzero((char *)&addr_out,sizeof(addr_out));
2982 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2983 addr_out.sin_port = htons( share_entry->op_port );
2984 addr_out.sin_family = AF_INET;
2986 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2987 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
2989 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2990 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2992 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2993 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2994 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
2995 strerror(errno)));
2996 return False;
3000 * Now we must await the oplock broken message coming back
3001 * from the target smbd process. Timeout if it fails to
3002 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3003 * While we get messages that aren't ours, loop.
3006 while(1)
3008 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3009 int32 reply_msg_len;
3010 uint16 reply_from_port;
3011 char *reply_msg_start;
3013 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3014 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3016 if(smb_read_error == READ_TIMEOUT)
3018 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3019 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3020 share_entry->op_port, dev, inode));
3022 * This is a hack to make handling of failing clients more robust.
3023 * If a oplock break response message is not received in the timeout
3024 * period we may assume that the smbd servicing that client holding
3025 * the oplock has died and the client changes were lost anyway, so
3026 * we should continue to try and open the file.
3028 break;
3030 else
3031 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3032 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3033 share_entry->op_port, dev, inode, strerror(errno)));
3034 return False;
3038 * If the response we got was not an answer to our message, but
3039 * was a completely different request, push it onto the pending
3040 * udp message stack so that we can deal with it in the main loop.
3041 * It may be another oplock break request to us.
3045 * Local note from JRA. There exists the possibility of a denial
3046 * of service attack here by allowing non-root processes running
3047 * on a local machine sending many of these pending messages to
3048 * a smbd port. Currently I'm not sure how to restrict the messages
3049 * I will queue (although I could add a limit to the queue) to
3050 * those received by root processes only. There should be a
3051 * way to make this bulletproof....
3054 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3055 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3057 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3059 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3061 /* Ignore it. */
3062 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3063 timestring()));
3064 continue;
3067 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3068 (reply_from_port != share_entry->op_port) ||
3069 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3070 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3071 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3073 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3074 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3075 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3076 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3077 return False;
3078 continue;
3081 break;
3084 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3086 return True;
3089 /****************************************************************************
3090 Get the next SMB packet, doing the local message processing automatically.
3091 ****************************************************************************/
3093 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3095 BOOL got_smb = False;
3096 BOOL ret;
3100 ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3101 timeout,&got_smb);
3103 if(ret && !got_smb)
3105 /* Deal with oplock break requests from other smbd's. */
3106 process_local_message(oplock_sock, inbuf, bufsize);
3107 continue;
3110 while(ret && !got_smb);
3112 return ret;
3115 /****************************************************************************
3116 check if a snum is in use
3117 ****************************************************************************/
3118 BOOL snum_used(int snum)
3120 int i;
3121 for (i=0;i<MAX_CONNECTIONS;i++)
3122 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3123 return(True);
3124 return(False);
3127 /****************************************************************************
3128 reload the services file
3129 **************************************************************************/
3130 BOOL reload_services(BOOL test)
3132 BOOL ret;
3134 if (lp_loaded())
3136 pstring fname;
3137 pstrcpy(fname,lp_configfile());
3138 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3140 pstrcpy(servicesf,fname);
3141 test = False;
3145 reopen_logs();
3147 if (test && !lp_file_list_changed())
3148 return(True);
3150 lp_killunused(snum_used);
3152 ret = lp_load(servicesf,False);
3154 /* perhaps the config filename is now set */
3155 if (!test)
3156 reload_services(True);
3158 reopen_logs();
3160 load_interfaces();
3163 extern int Client;
3164 if (Client != -1) {
3165 set_socket_options(Client,"SO_KEEPALIVE");
3166 set_socket_options(Client,user_socket_options);
3170 reset_mangled_stack( lp_mangledstack() );
3172 /* this forces service parameters to be flushed */
3173 become_service(-1,True);
3175 return(ret);
3180 /****************************************************************************
3181 this prevents zombie child processes
3182 ****************************************************************************/
3183 static int sig_hup()
3185 BlockSignals(True,SIGHUP);
3186 DEBUG(0,("Got SIGHUP\n"));
3187 reload_services(False);
3188 #ifndef DONT_REINSTALL_SIG
3189 signal(SIGHUP,SIGNAL_CAST sig_hup);
3190 #endif
3191 BlockSignals(False,SIGHUP);
3192 return(0);
3195 /****************************************************************************
3196 Setup the groups a user belongs to.
3197 ****************************************************************************/
3198 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3199 int **p_igroups, gid_t **p_groups,
3200 int **p_attrs)
3202 if (-1 == initgroups(user,gid))
3204 if (getuid() == 0)
3206 DEBUG(0,("Unable to initgroups!\n"));
3207 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3208 DEBUG(0,("This is probably a problem with the account %s\n",user));
3211 else
3213 int i,ngroups;
3214 int *igroups;
3215 int *attrs;
3216 gid_t grp = 0;
3217 ngroups = getgroups(0,&grp);
3218 if (ngroups <= 0)
3219 ngroups = 32;
3220 igroups = (int *)malloc(sizeof(int)*ngroups);
3221 attrs = (int *)malloc(sizeof(int)*ngroups);
3222 for (i=0;i<ngroups;i++)
3224 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3225 igroups[i] = 0x42424242;
3227 ngroups = getgroups(ngroups,(gid_t *)igroups);
3229 if (igroups[0] == 0x42424242)
3230 ngroups = 0;
3232 *p_ngroups = ngroups;
3233 *p_attrs = attrs;
3235 /* The following bit of code is very strange. It is due to the
3236 fact that some OSes use int* and some use gid_t* for
3237 getgroups, and some (like SunOS) use both, one in prototypes,
3238 and one in man pages and the actual code. Thus we detect it
3239 dynamically using some very ugly code */
3240 if (ngroups > 0)
3242 /* does getgroups return ints or gid_t ?? */
3243 static BOOL groups_use_ints = True;
3245 if (groups_use_ints &&
3246 ngroups == 1 &&
3247 SVAL(igroups,2) == 0x4242)
3248 groups_use_ints = False;
3250 for (i=0;groups_use_ints && i<ngroups;i++)
3251 if (igroups[i] == 0x42424242)
3252 groups_use_ints = False;
3254 if (groups_use_ints)
3256 *p_igroups = igroups;
3257 *p_groups = (gid_t *)igroups;
3259 else
3261 gid_t *groups = (gid_t *)igroups;
3262 igroups = (int *)malloc(sizeof(int)*ngroups);
3263 for (i=0;i<ngroups;i++)
3265 igroups[i] = groups[i];
3267 *p_igroups = igroups;
3268 *p_groups = (gid_t *)groups;
3271 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3272 for (i=0;i<ngroups;i++)
3273 DEBUG(3,("%d ",igroups[i]));
3274 DEBUG(3,("\n"));
3276 return 0;
3279 /****************************************************************************
3280 make a connection to a service
3281 ****************************************************************************/
3282 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3284 int cnum;
3285 int snum;
3286 struct passwd *pass = NULL;
3287 connection_struct *pcon;
3288 BOOL guest = False;
3289 BOOL force = False;
3290 static BOOL first_connection = True;
3292 strlower(service);
3294 snum = find_service(service);
3295 if (snum < 0)
3297 if (strequal(service,"IPC$"))
3299 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3300 return(-3);
3303 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3304 return(-2);
3307 if (strequal(service,HOMES_NAME))
3309 if (*user && Get_Pwnam(user,True))
3310 return(make_connection(user,user,password,pwlen,dev,vuid));
3312 if (validated_username(vuid))
3314 strcpy(user,validated_username(vuid));
3315 return(make_connection(user,user,password,pwlen,dev,vuid));
3319 if (!lp_snum_ok(snum) || !check_access(snum)) {
3320 return(-4);
3323 /* you can only connect to the IPC$ service as an ipc device */
3324 if (strequal(service,"IPC$"))
3325 strcpy(dev,"IPC");
3327 if (*dev == '?' || !*dev)
3329 if (lp_print_ok(snum))
3330 strcpy(dev,"LPT1:");
3331 else
3332 strcpy(dev,"A:");
3335 /* if the request is as a printer and you can't print then refuse */
3336 strupper(dev);
3337 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3338 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3339 return(-6);
3342 /* lowercase the user name */
3343 strlower(user);
3345 /* add it as a possible user name */
3346 add_session_user(service);
3348 /* shall we let them in? */
3349 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3351 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3352 return(-1);
3355 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3356 if (cnum < 0)
3358 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3359 return(-1);
3362 pcon = &Connections[cnum];
3363 bzero((char *)pcon,sizeof(*pcon));
3365 /* find out some info about the user */
3366 pass = Get_Pwnam(user,True);
3368 if (pass == NULL)
3370 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3371 return(-7);
3374 pcon->read_only = lp_readonly(snum);
3377 pstring list;
3378 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3379 string_sub(list,"%S",service);
3381 if (user_in_list(user,list))
3382 pcon->read_only = True;
3384 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3385 string_sub(list,"%S",service);
3387 if (user_in_list(user,list))
3388 pcon->read_only = False;
3391 /* admin user check */
3393 /* JRA - original code denied admin user if the share was
3394 marked read_only. Changed as I don't think this is needed,
3395 but old code left in case there is a problem here.
3397 if (user_in_list(user,lp_admin_users(snum))
3398 #if 0
3399 && !pcon->read_only)
3400 #else
3402 #endif
3404 pcon->admin_user = True;
3405 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3407 else
3408 pcon->admin_user = False;
3410 pcon->force_user = force;
3411 pcon->vuid = vuid;
3412 pcon->uid = pass->pw_uid;
3413 pcon->gid = pass->pw_gid;
3414 pcon->num_files_open = 0;
3415 pcon->lastused = time(NULL);
3416 pcon->service = snum;
3417 pcon->used = True;
3418 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3419 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3420 pcon->dirptr = NULL;
3421 pcon->veto_list = NULL;
3422 pcon->hide_list = NULL;
3423 pcon->veto_oplock_list = NULL;
3424 string_set(&pcon->dirpath,"");
3425 string_set(&pcon->user,user);
3427 #if HAVE_GETGRNAM
3428 if (*lp_force_group(snum))
3430 struct group *gptr;
3431 pstring gname;
3433 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3434 /* default service may be a group name */
3435 string_sub(gname,"%S",service);
3436 gptr = (struct group *)getgrnam(gname);
3438 if (gptr)
3440 pcon->gid = gptr->gr_gid;
3441 DEBUG(3,("Forced group %s\n",gname));
3443 else
3444 DEBUG(1,("Couldn't find group %s\n",gname));
3446 #endif
3448 if (*lp_force_user(snum))
3450 struct passwd *pass2;
3451 fstring fuser;
3452 fstrcpy(fuser,lp_force_user(snum));
3453 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3454 if (pass2)
3456 pcon->uid = pass2->pw_uid;
3457 string_set(&pcon->user,fuser);
3458 fstrcpy(user,fuser);
3459 pcon->force_user = True;
3460 DEBUG(3,("Forced user %s\n",fuser));
3462 else
3463 DEBUG(1,("Couldn't find user %s\n",fuser));
3467 pstring s;
3468 pstrcpy(s,lp_pathname(snum));
3469 standard_sub(cnum,s);
3470 string_set(&pcon->connectpath,s);
3471 DEBUG(3,("Connect path is %s\n",s));
3474 /* groups stuff added by ih */
3475 pcon->ngroups = 0;
3476 pcon->igroups = NULL;
3477 pcon->groups = NULL;
3478 pcon->attrs = NULL;
3480 if (!IS_IPC(cnum))
3482 /* Find all the groups this uid is in and store them. Used by become_user() */
3483 setup_groups(pcon->user,pcon->uid,pcon->gid,
3484 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3486 /* check number of connections */
3487 if (!claim_connection(cnum,
3488 lp_servicename(SNUM(cnum)),
3489 lp_max_connections(SNUM(cnum)),False))
3491 DEBUG(1,("too many connections - rejected\n"));
3492 return(-8);
3495 if (lp_status(SNUM(cnum)))
3496 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3498 first_connection = False;
3499 } /* IS_IPC */
3501 pcon->open = True;
3503 /* execute any "root preexec = " line */
3504 if (*lp_rootpreexec(SNUM(cnum)))
3506 pstring cmd;
3507 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3508 standard_sub(cnum,cmd);
3509 DEBUG(5,("cmd=%s\n",cmd));
3510 smbrun(cmd,NULL,False);
3513 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3515 DEBUG(0,("Can't become connected user!\n"));
3516 pcon->open = False;
3517 if (!IS_IPC(cnum)) {
3518 yield_connection(cnum,
3519 lp_servicename(SNUM(cnum)),
3520 lp_max_connections(SNUM(cnum)));
3521 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3523 return(-1);
3526 if (ChDir(pcon->connectpath) != 0)
3528 DEBUG(0,("Can't change directory to %s (%s)\n",
3529 pcon->connectpath,strerror(errno)));
3530 pcon->open = False;
3531 unbecome_user();
3532 if (!IS_IPC(cnum)) {
3533 yield_connection(cnum,
3534 lp_servicename(SNUM(cnum)),
3535 lp_max_connections(SNUM(cnum)));
3536 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3538 return(-5);
3541 string_set(&pcon->origpath,pcon->connectpath);
3543 #if SOFTLINK_OPTIMISATION
3544 /* resolve any soft links early */
3546 pstring s;
3547 pstrcpy(s,pcon->connectpath);
3548 GetWd(s);
3549 string_set(&pcon->connectpath,s);
3550 ChDir(pcon->connectpath);
3552 #endif
3554 num_connections_open++;
3555 add_session_user(user);
3557 /* execute any "preexec = " line */
3558 if (*lp_preexec(SNUM(cnum)))
3560 pstring cmd;
3561 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3562 standard_sub(cnum,cmd);
3563 smbrun(cmd,NULL,False);
3566 /* we've finished with the sensitive stuff */
3567 unbecome_user();
3569 /* Add veto/hide lists */
3570 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3572 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3573 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3574 set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3578 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3579 timestring(),
3580 remote_machine,
3581 client_addr(),
3582 lp_servicename(SNUM(cnum)),user,
3583 pcon->uid,
3584 pcon->gid,
3585 (int)getpid()));
3588 return(cnum);
3592 /****************************************************************************
3593 find first available file slot
3594 ****************************************************************************/
3595 int find_free_file(void )
3597 int i;
3598 /* we start at 1 here for an obscure reason I can't now remember,
3599 but I think is important :-) */
3600 for (i=1;i<MAX_OPEN_FILES;i++)
3601 if (!Files[i].open)
3602 return(i);
3603 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3604 return(-1);
3607 /****************************************************************************
3608 find first available connection slot, starting from a random position.
3609 The randomisation stops problems with the server dieing and clients
3610 thinking the server is still available.
3611 ****************************************************************************/
3612 static int find_free_connection(int hash )
3614 int i;
3615 BOOL used=False;
3616 hash = (hash % (MAX_CONNECTIONS-2))+1;
3618 again:
3620 for (i=hash+1;i!=hash;)
3622 if (!Connections[i].open && Connections[i].used == used)
3624 DEBUG(3,("found free connection number %d\n",i));
3625 return(i);
3627 i++;
3628 if (i == MAX_CONNECTIONS)
3629 i = 1;
3632 if (!used)
3634 used = !used;
3635 goto again;
3638 DEBUG(1,("ERROR! Out of connection structures\n"));
3639 return(-1);
3643 /****************************************************************************
3644 reply for the core protocol
3645 ****************************************************************************/
3646 int reply_corep(char *outbuf)
3648 int outsize = set_message(outbuf,1,0,True);
3650 Protocol = PROTOCOL_CORE;
3652 return outsize;
3656 /****************************************************************************
3657 reply for the coreplus protocol
3658 ****************************************************************************/
3659 int reply_coreplus(char *outbuf)
3661 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3662 int outsize = set_message(outbuf,13,0,True);
3663 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3664 readbraw and writebraw (possibly) */
3665 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3666 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3668 Protocol = PROTOCOL_COREPLUS;
3670 return outsize;
3674 /****************************************************************************
3675 reply for the lanman 1.0 protocol
3676 ****************************************************************************/
3677 int reply_lanman1(char *outbuf)
3679 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3680 int secword=0;
3681 BOOL doencrypt = SMBENCRYPT();
3682 time_t t = time(NULL);
3684 if (lp_security()>=SEC_USER) secword |= 1;
3685 if (doencrypt) secword |= 2;
3687 set_message(outbuf,13,doencrypt?8:0,True);
3688 SSVAL(outbuf,smb_vwv1,secword);
3689 /* Create a token value and add it to the outgoing packet. */
3690 if (doencrypt)
3691 generate_next_challenge(smb_buf(outbuf));
3693 Protocol = PROTOCOL_LANMAN1;
3695 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3696 SSVAL(outbuf,smb_vwv2,max_recv);
3697 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3698 SSVAL(outbuf,smb_vwv4,1);
3699 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3700 readbraw writebraw (possibly) */
3701 SIVAL(outbuf,smb_vwv6,getpid());
3702 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3704 put_dos_date(outbuf,smb_vwv8,t);
3706 return (smb_len(outbuf)+4);
3710 /****************************************************************************
3711 reply for the lanman 2.0 protocol
3712 ****************************************************************************/
3713 int reply_lanman2(char *outbuf)
3715 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3716 int secword=0;
3717 BOOL doencrypt = SMBENCRYPT();
3718 time_t t = time(NULL);
3719 struct cli_state *cli = NULL;
3720 char cryptkey[8];
3721 char crypt_len = 0;
3723 if (lp_security() == SEC_SERVER) {
3724 cli = server_cryptkey();
3727 if (cli) {
3728 DEBUG(3,("using password server validation\n"));
3729 doencrypt = ((cli->sec_mode & 2) != 0);
3732 if (lp_security()>=SEC_USER) secword |= 1;
3733 if (doencrypt) secword |= 2;
3735 if (doencrypt) {
3736 crypt_len = 8;
3737 if (!cli) {
3738 generate_next_challenge(cryptkey);
3739 } else {
3740 memcpy(cryptkey, cli->cryptkey, 8);
3741 set_challenge(cli->cryptkey);
3745 set_message(outbuf,13,crypt_len,True);
3746 SSVAL(outbuf,smb_vwv1,secword);
3747 SIVAL(outbuf,smb_vwv6,getpid());
3748 if (doencrypt)
3749 memcpy(smb_buf(outbuf), cryptkey, 8);
3751 Protocol = PROTOCOL_LANMAN2;
3753 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3754 SSVAL(outbuf,smb_vwv2,max_recv);
3755 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3756 SSVAL(outbuf,smb_vwv4,1);
3757 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3758 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3759 put_dos_date(outbuf,smb_vwv8,t);
3761 return (smb_len(outbuf)+4);
3765 /****************************************************************************
3766 reply for the nt protocol
3767 ****************************************************************************/
3768 int reply_nt1(char *outbuf)
3770 /* dual names + lock_and_read + nt SMBs + remote API calls */
3771 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3773 other valid capabilities which we may support at some time...
3774 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3775 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3778 int secword=0;
3779 BOOL doencrypt = SMBENCRYPT();
3780 time_t t = time(NULL);
3781 int data_len;
3782 struct cli_state *cli = NULL;
3783 char cryptkey[8];
3784 char crypt_len = 0;
3786 if (lp_security() == SEC_SERVER) {
3787 cli = server_cryptkey();
3790 if (cli) {
3791 DEBUG(3,("using password server validation\n"));
3792 doencrypt = ((cli->sec_mode & 2) != 0);
3795 if (doencrypt) {
3796 crypt_len = 8;
3797 if (!cli) {
3798 generate_next_challenge(cryptkey);
3799 } else {
3800 memcpy(cryptkey, cli->cryptkey, 8);
3801 set_challenge(cli->cryptkey);
3805 if (lp_readraw() && lp_writeraw()) {
3806 capabilities |= CAP_RAW_MODE;
3809 if (lp_security() >= SEC_USER) secword |= 1;
3810 if (doencrypt) secword |= 2;
3812 /* decide where (if) to put the encryption challenge, and
3813 follow it with the OEM'd domain name
3815 data_len = crypt_len + strlen(myworkgroup) + 1;
3817 set_message(outbuf,17,data_len,True);
3818 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3820 CVAL(outbuf,smb_vwv1) = secword;
3821 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3822 if (doencrypt)
3823 memcpy(smb_buf(outbuf), cryptkey, 8);
3825 Protocol = PROTOCOL_NT1;
3827 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3828 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3829 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3830 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3831 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3832 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3833 put_long_date(outbuf+smb_vwv11+1,t);
3834 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3835 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3837 return (smb_len(outbuf)+4);
3840 /* these are the protocol lists used for auto architecture detection:
3842 WinNT 3.51:
3843 protocol [PC NETWORK PROGRAM 1.0]
3844 protocol [XENIX CORE]
3845 protocol [MICROSOFT NETWORKS 1.03]
3846 protocol [LANMAN1.0]
3847 protocol [Windows for Workgroups 3.1a]
3848 protocol [LM1.2X002]
3849 protocol [LANMAN2.1]
3850 protocol [NT LM 0.12]
3852 Win95:
3853 protocol [PC NETWORK PROGRAM 1.0]
3854 protocol [XENIX CORE]
3855 protocol [MICROSOFT NETWORKS 1.03]
3856 protocol [LANMAN1.0]
3857 protocol [Windows for Workgroups 3.1a]
3858 protocol [LM1.2X002]
3859 protocol [LANMAN2.1]
3860 protocol [NT LM 0.12]
3862 OS/2:
3863 protocol [PC NETWORK PROGRAM 1.0]
3864 protocol [XENIX CORE]
3865 protocol [LANMAN1.0]
3866 protocol [LM1.2X002]
3867 protocol [LANMAN2.1]
3871 * Modified to recognize the architecture of the remote machine better.
3873 * This appears to be the matrix of which protocol is used by which
3874 * MS product.
3875 Protocol WfWg Win95 WinNT OS/2
3876 PC NETWORK PROGRAM 1.0 1 1 1 1
3877 XENIX CORE 2 2
3878 MICROSOFT NETWORKS 3.0 2 2
3879 DOS LM1.2X002 3 3
3880 MICROSOFT NETWORKS 1.03 3
3881 DOS LANMAN2.1 4 4
3882 LANMAN1.0 4 3
3883 Windows for Workgroups 3.1a 5 5 5
3884 LM1.2X002 6 4
3885 LANMAN2.1 7 5
3886 NT LM 0.12 6 8
3888 * tim@fsg.com 09/29/95
3891 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3892 #define ARCH_WIN95 0x2
3893 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3894 #define ARCH_WINNT 0x8
3895 #define ARCH_SAMBA 0x10
3897 #define ARCH_ALL 0x1F
3899 /* List of supported protocols, most desired first */
3900 struct {
3901 char *proto_name;
3902 char *short_name;
3903 int (*proto_reply_fn)(char *);
3904 int protocol_level;
3905 } supported_protocols[] = {
3906 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3907 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3908 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3909 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3910 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3911 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3912 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3913 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3914 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3915 {NULL,NULL},
3919 /****************************************************************************
3920 reply to a negprot
3921 ****************************************************************************/
3922 static int reply_negprot(char *inbuf,char *outbuf)
3924 int outsize = set_message(outbuf,1,0,True);
3925 int Index=0;
3926 int choice= -1;
3927 int protocol;
3928 char *p;
3929 int bcc = SVAL(smb_buf(inbuf),-2);
3930 int arch = ARCH_ALL;
3932 p = smb_buf(inbuf)+1;
3933 while (p < (smb_buf(inbuf) + bcc))
3935 Index++;
3936 DEBUG(3,("Requested protocol [%s]\n",p));
3937 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3938 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3939 else if (strcsequal(p,"DOS LM1.2X002"))
3940 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3941 else if (strcsequal(p,"DOS LANMAN2.1"))
3942 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3943 else if (strcsequal(p,"NT LM 0.12"))
3944 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3945 else if (strcsequal(p,"LANMAN2.1"))
3946 arch &= ( ARCH_WINNT | ARCH_OS2 );
3947 else if (strcsequal(p,"LM1.2X002"))
3948 arch &= ( ARCH_WINNT | ARCH_OS2 );
3949 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3950 arch &= ARCH_WINNT;
3951 else if (strcsequal(p,"XENIX CORE"))
3952 arch &= ( ARCH_WINNT | ARCH_OS2 );
3953 else if (strcsequal(p,"Samba")) {
3954 arch = ARCH_SAMBA;
3955 break;
3958 p += strlen(p) + 2;
3961 switch ( arch ) {
3962 case ARCH_SAMBA:
3963 set_remote_arch(RA_SAMBA);
3964 break;
3965 case ARCH_WFWG:
3966 set_remote_arch(RA_WFWG);
3967 break;
3968 case ARCH_WIN95:
3969 set_remote_arch(RA_WIN95);
3970 break;
3971 case ARCH_WINNT:
3972 set_remote_arch(RA_WINNT);
3973 break;
3974 case ARCH_OS2:
3975 set_remote_arch(RA_OS2);
3976 break;
3977 default:
3978 set_remote_arch(RA_UNKNOWN);
3979 break;
3982 /* possibly reload - change of architecture */
3983 reload_services(True);
3985 /* a special case to stop password server loops */
3986 if (Index == 1 && strequal(remote_machine,myhostname) &&
3987 lp_security()==SEC_SERVER)
3988 exit_server("Password server loop!");
3990 /* Check for protocols, most desirable first */
3991 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3993 p = smb_buf(inbuf)+1;
3994 Index = 0;
3995 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3996 while (p < (smb_buf(inbuf) + bcc))
3998 if (strequal(p,supported_protocols[protocol].proto_name))
3999 choice = Index;
4000 Index++;
4001 p += strlen(p) + 2;
4003 if(choice != -1)
4004 break;
4007 SSVAL(outbuf,smb_vwv0,choice);
4008 if(choice != -1) {
4009 extern fstring remote_proto;
4010 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4011 reload_services(True);
4012 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4013 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4015 else {
4016 DEBUG(0,("No protocol supported !\n"));
4018 SSVAL(outbuf,smb_vwv0,choice);
4020 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4022 return(outsize);
4026 /****************************************************************************
4027 close all open files for a connection
4028 ****************************************************************************/
4029 static void close_open_files(int cnum)
4031 int i;
4032 for (i=0;i<MAX_OPEN_FILES;i++)
4033 if( Files[i].cnum == cnum && Files[i].open) {
4034 close_file(i,False);
4040 /****************************************************************************
4041 close a cnum
4042 ****************************************************************************/
4043 void close_cnum(int cnum, uint16 vuid)
4045 DirCacheFlush(SNUM(cnum));
4047 unbecome_user();
4049 if (!OPEN_CNUM(cnum))
4051 DEBUG(0,("Can't close cnum %d\n",cnum));
4052 return;
4055 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4056 timestring(),
4057 remote_machine,client_addr(),
4058 lp_servicename(SNUM(cnum))));
4060 yield_connection(cnum,
4061 lp_servicename(SNUM(cnum)),
4062 lp_max_connections(SNUM(cnum)));
4064 if (lp_status(SNUM(cnum)))
4065 yield_connection(cnum,"STATUS.",MAXSTATUS);
4067 close_open_files(cnum);
4068 dptr_closecnum(cnum);
4070 /* execute any "postexec = " line */
4071 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4073 pstring cmd;
4074 strcpy(cmd,lp_postexec(SNUM(cnum)));
4075 standard_sub(cnum,cmd);
4076 smbrun(cmd,NULL,False);
4077 unbecome_user();
4080 unbecome_user();
4081 /* execute any "root postexec = " line */
4082 if (*lp_rootpostexec(SNUM(cnum)))
4084 pstring cmd;
4085 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4086 standard_sub(cnum,cmd);
4087 smbrun(cmd,NULL,False);
4090 Connections[cnum].open = False;
4091 num_connections_open--;
4092 if (Connections[cnum].ngroups && Connections[cnum].groups)
4094 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4095 free(Connections[cnum].groups);
4096 free(Connections[cnum].igroups);
4097 Connections[cnum].groups = NULL;
4098 Connections[cnum].igroups = NULL;
4099 Connections[cnum].ngroups = 0;
4102 free_namearray(Connections[cnum].veto_list);
4103 free_namearray(Connections[cnum].hide_list);
4104 free_namearray(Connections[cnum].veto_oplock_list);
4106 string_set(&Connections[cnum].user,"");
4107 string_set(&Connections[cnum].dirpath,"");
4108 string_set(&Connections[cnum].connectpath,"");
4112 /****************************************************************************
4113 simple routines to do connection counting
4114 ****************************************************************************/
4115 BOOL yield_connection(int cnum,char *name,int max_connections)
4117 struct connect_record crec;
4118 pstring fname;
4119 FILE *f;
4120 int mypid = getpid();
4121 int i;
4123 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4125 if (max_connections <= 0)
4126 return(True);
4128 bzero(&crec,sizeof(crec));
4130 pstrcpy(fname,lp_lockdir());
4131 standard_sub(cnum,fname);
4132 trim_string(fname,"","/");
4134 strcat(fname,"/");
4135 strcat(fname,name);
4136 strcat(fname,".LCK");
4138 f = fopen(fname,"r+");
4139 if (!f)
4141 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4142 return(False);
4145 fseek(f,0,SEEK_SET);
4147 /* find a free spot */
4148 for (i=0;i<max_connections;i++)
4150 if (fread(&crec,sizeof(crec),1,f) != 1)
4152 DEBUG(2,("Entry not found in lock file %s\n",fname));
4153 fclose(f);
4154 return(False);
4156 if (crec.pid == mypid && crec.cnum == cnum)
4157 break;
4160 if (crec.pid != mypid || crec.cnum != cnum)
4162 fclose(f);
4163 DEBUG(2,("Entry not found in lock file %s\n",fname));
4164 return(False);
4167 bzero((void *)&crec,sizeof(crec));
4169 /* remove our mark */
4170 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4171 fwrite(&crec,sizeof(crec),1,f) != 1)
4173 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4174 fclose(f);
4175 return(False);
4178 DEBUG(3,("Yield successful\n"));
4180 fclose(f);
4181 return(True);
4185 /****************************************************************************
4186 simple routines to do connection counting
4187 ****************************************************************************/
4188 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4190 struct connect_record crec;
4191 pstring fname;
4192 FILE *f;
4193 int snum = SNUM(cnum);
4194 int i,foundi= -1;
4195 int total_recs;
4197 if (max_connections <= 0)
4198 return(True);
4200 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4202 pstrcpy(fname,lp_lockdir());
4203 standard_sub(cnum,fname);
4204 trim_string(fname,"","/");
4206 if (!directory_exist(fname,NULL))
4207 mkdir(fname,0755);
4209 strcat(fname,"/");
4210 strcat(fname,name);
4211 strcat(fname,".LCK");
4213 if (!file_exist(fname,NULL))
4215 int oldmask = umask(022);
4216 f = fopen(fname,"w");
4217 if (f) fclose(f);
4218 umask(oldmask);
4221 total_recs = file_size(fname) / sizeof(crec);
4223 f = fopen(fname,"r+");
4225 if (!f)
4227 DEBUG(1,("couldn't open lock file %s\n",fname));
4228 return(False);
4231 /* find a free spot */
4232 for (i=0;i<max_connections;i++)
4235 if (i>=total_recs ||
4236 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4237 fread(&crec,sizeof(crec),1,f) != 1)
4239 if (foundi < 0) foundi = i;
4240 break;
4243 if (Clear && crec.pid && !process_exists(crec.pid))
4245 fseek(f,i*sizeof(crec),SEEK_SET);
4246 bzero((void *)&crec,sizeof(crec));
4247 fwrite(&crec,sizeof(crec),1,f);
4248 if (foundi < 0) foundi = i;
4249 continue;
4251 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4253 foundi=i;
4254 if (!Clear) break;
4258 if (foundi < 0)
4260 DEBUG(3,("no free locks in %s\n",fname));
4261 fclose(f);
4262 return(False);
4265 /* fill in the crec */
4266 bzero((void *)&crec,sizeof(crec));
4267 crec.magic = 0x280267;
4268 crec.pid = getpid();
4269 crec.cnum = cnum;
4270 crec.uid = Connections[cnum].uid;
4271 crec.gid = Connections[cnum].gid;
4272 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4273 crec.start = time(NULL);
4275 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4276 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4278 /* make our mark */
4279 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4280 fwrite(&crec,sizeof(crec),1,f) != 1)
4282 fclose(f);
4283 return(False);
4286 fclose(f);
4287 return(True);
4290 #if DUMP_CORE
4291 /*******************************************************************
4292 prepare to dump a core file - carefully!
4293 ********************************************************************/
4294 static BOOL dump_core(void)
4296 char *p;
4297 pstring dname;
4298 pstrcpy(dname,debugf);
4299 if ((p=strrchr(dname,'/'))) *p=0;
4300 strcat(dname,"/corefiles");
4301 mkdir(dname,0700);
4302 sys_chown(dname,getuid(),getgid());
4303 chmod(dname,0700);
4304 if (chdir(dname)) return(False);
4305 umask(~(0700));
4307 #ifndef NO_GETRLIMIT
4308 #ifdef RLIMIT_CORE
4310 struct rlimit rlp;
4311 getrlimit(RLIMIT_CORE, &rlp);
4312 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4313 setrlimit(RLIMIT_CORE, &rlp);
4314 getrlimit(RLIMIT_CORE, &rlp);
4315 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4317 #endif
4318 #endif
4321 DEBUG(0,("Dumping core in %s\n",dname));
4322 return(True);
4324 #endif
4326 /****************************************************************************
4327 exit the server
4328 ****************************************************************************/
4329 void exit_server(char *reason)
4331 static int firsttime=1;
4332 int i;
4334 if (!firsttime) exit(0);
4335 firsttime = 0;
4337 unbecome_user();
4338 DEBUG(2,("Closing connections\n"));
4339 for (i=0;i<MAX_CONNECTIONS;i++)
4340 if (Connections[i].open)
4341 close_cnum(i,(uint16)-1);
4342 #ifdef DFS_AUTH
4343 if (dcelogin_atmost_once)
4344 dfs_unlogin();
4345 #endif
4346 if (!reason) {
4347 int oldlevel = DEBUGLEVEL;
4348 DEBUGLEVEL = 10;
4349 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4350 if (last_inbuf)
4351 show_msg(last_inbuf);
4352 DEBUGLEVEL = oldlevel;
4353 DEBUG(0,("===============================================================\n"));
4354 #if DUMP_CORE
4355 if (dump_core()) return;
4356 #endif
4359 locking_end();
4361 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4362 exit(0);
4365 /****************************************************************************
4366 do some standard substitutions in a string
4367 ****************************************************************************/
4368 void standard_sub(int cnum,char *str)
4370 if (VALID_CNUM(cnum)) {
4371 char *p, *s, *home;
4373 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4374 switch (*(p+1)) {
4375 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4376 string_sub(p,"%H",home);
4377 else
4378 p += 2;
4379 break;
4380 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4381 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4382 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4383 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4384 case '\0' : p++; break; /* don't run off the end of the string */
4385 default : p+=2; break;
4389 standard_sub_basic(str);
4393 These flags determine some of the permissions required to do an operation
4395 Note that I don't set NEED_WRITE on some write operations because they
4396 are used by some brain-dead clients when printing, and I don't want to
4397 force write permissions on print services.
4399 #define AS_USER (1<<0)
4400 #define NEED_WRITE (1<<1)
4401 #define TIME_INIT (1<<2)
4402 #define CAN_IPC (1<<3)
4403 #define AS_GUEST (1<<5)
4407 define a list of possible SMB messages and their corresponding
4408 functions. Any message that has a NULL function is unimplemented -
4409 please feel free to contribute implementations!
4411 struct smb_message_struct
4413 int code;
4414 char *name;
4415 int (*fn)();
4416 int flags;
4417 #if PROFILING
4418 unsigned long time;
4419 #endif
4421 smb_messages[] = {
4423 /* CORE PROTOCOL */
4425 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4426 {SMBtcon,"SMBtcon",reply_tcon,0},
4427 {SMBtdis,"SMBtdis",reply_tdis,0},
4428 {SMBexit,"SMBexit",reply_exit,0},
4429 {SMBioctl,"SMBioctl",reply_ioctl,0},
4430 {SMBecho,"SMBecho",reply_echo,0},
4431 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4432 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4433 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4434 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4435 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4436 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4437 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4438 {SMBopen,"SMBopen",reply_open,AS_USER},
4440 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4441 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4442 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4444 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4445 {SMBread,"SMBread",reply_read,AS_USER},
4446 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4447 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4448 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4449 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4450 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4451 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4453 /* this is a Pathworks specific call, allowing the
4454 changing of the root path */
4455 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4457 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4458 {SMBflush,"SMBflush",reply_flush,AS_USER},
4459 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4460 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4461 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4462 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4463 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4464 {SMBlock,"SMBlock",reply_lock,AS_USER},
4465 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4467 /* CORE+ PROTOCOL FOLLOWS */
4469 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4470 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4471 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4472 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4473 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4475 /* LANMAN1.0 PROTOCOL FOLLOWS */
4477 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4478 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4479 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4480 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4481 {SMBwritec,"SMBwritec",NULL,AS_USER},
4482 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4483 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4484 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4485 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4486 {SMBioctls,"SMBioctls",NULL,AS_USER},
4487 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4488 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4490 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4491 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4492 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4493 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4495 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4496 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4497 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4499 /* LANMAN2.0 PROTOCOL FOLLOWS */
4500 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4501 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4502 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4503 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4505 /* messaging routines */
4506 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4507 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4508 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4509 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4511 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4513 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4514 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4515 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4516 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4519 /****************************************************************************
4520 return a string containing the function name of a SMB command
4521 ****************************************************************************/
4522 char *smb_fn_name(int type)
4524 static char *unknown_name = "SMBunknown";
4525 static int num_smb_messages =
4526 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4527 int match;
4529 for (match=0;match<num_smb_messages;match++)
4530 if (smb_messages[match].code == type)
4531 break;
4533 if (match == num_smb_messages)
4534 return(unknown_name);
4536 return(smb_messages[match].name);
4540 /****************************************************************************
4541 do a switch on the message type, and return the response size
4542 ****************************************************************************/
4543 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4545 static int pid= -1;
4546 int outsize = 0;
4547 static int num_smb_messages =
4548 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4549 int match;
4551 #if PROFILING
4552 struct timeval msg_start_time;
4553 struct timeval msg_end_time;
4554 static unsigned long total_time = 0;
4556 GetTimeOfDay(&msg_start_time);
4557 #endif
4559 if (pid == -1)
4560 pid = getpid();
4562 errno = 0;
4563 last_message = type;
4565 /* make sure this is an SMB packet */
4566 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4568 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4569 return(-1);
4572 for (match=0;match<num_smb_messages;match++)
4573 if (smb_messages[match].code == type)
4574 break;
4576 if (match == num_smb_messages)
4578 DEBUG(0,("Unknown message type %d!\n",type));
4579 outsize = reply_unknown(inbuf,outbuf);
4581 else
4583 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4584 if (smb_messages[match].fn)
4586 int cnum = SVAL(inbuf,smb_tid);
4587 int flags = smb_messages[match].flags;
4588 uint16 session_tag = SVAL(inbuf,smb_uid);
4590 /* does this protocol need to be run as root? */
4591 if (!(flags & AS_USER))
4592 unbecome_user();
4594 /* does this protocol need to be run as the connected user? */
4595 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4596 if (flags & AS_GUEST)
4597 flags &= ~AS_USER;
4598 else
4599 return(ERROR(ERRSRV,ERRinvnid));
4601 /* this code is to work around a bug is MS client 3 without
4602 introducing a security hole - it needs to be able to do
4603 print queue checks as guest if it isn't logged in properly */
4604 if (flags & AS_USER)
4605 flags &= ~AS_GUEST;
4607 /* does it need write permission? */
4608 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4609 return(ERROR(ERRSRV,ERRaccess));
4611 /* ipc services are limited */
4612 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4613 return(ERROR(ERRSRV,ERRaccess));
4615 /* load service specific parameters */
4616 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4617 return(ERROR(ERRSRV,ERRaccess));
4619 /* does this protocol need to be run as guest? */
4620 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4621 return(ERROR(ERRSRV,ERRaccess));
4623 last_inbuf = inbuf;
4625 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4627 else
4629 outsize = reply_unknown(inbuf,outbuf);
4633 #if PROFILING
4634 GetTimeOfDay(&msg_end_time);
4635 if (!(smb_messages[match].flags & TIME_INIT))
4637 smb_messages[match].time = 0;
4638 smb_messages[match].flags |= TIME_INIT;
4641 unsigned long this_time =
4642 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4643 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4644 smb_messages[match].time += this_time;
4645 total_time += this_time;
4647 DEBUG(2,("TIME %s %d usecs %g pct\n",
4648 smb_fn_name(type),smb_messages[match].time,
4649 (100.0*smb_messages[match].time) / total_time));
4650 #endif
4652 return(outsize);
4656 /****************************************************************************
4657 construct a chained reply and add it to the already made reply
4658 **************************************************************************/
4659 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4661 static char *orig_inbuf;
4662 static char *orig_outbuf;
4663 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4664 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4665 char *inbuf2, *outbuf2;
4666 int outsize2;
4667 char inbuf_saved[smb_wct];
4668 char outbuf_saved[smb_wct];
4669 extern int chain_size;
4670 int wct = CVAL(outbuf,smb_wct);
4671 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4673 /* maybe its not chained */
4674 if (smb_com2 == 0xFF) {
4675 CVAL(outbuf,smb_vwv0) = 0xFF;
4676 return outsize;
4679 if (chain_size == 0) {
4680 /* this is the first part of the chain */
4681 orig_inbuf = inbuf;
4682 orig_outbuf = outbuf;
4685 /* we need to tell the client where the next part of the reply will be */
4686 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4687 CVAL(outbuf,smb_vwv0) = smb_com2;
4689 /* remember how much the caller added to the chain, only counting stuff
4690 after the parameter words */
4691 chain_size += outsize - smb_wct;
4693 /* work out pointers into the original packets. The
4694 headers on these need to be filled in */
4695 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4696 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4698 /* remember the original command type */
4699 smb_com1 = CVAL(orig_inbuf,smb_com);
4701 /* save the data which will be overwritten by the new headers */
4702 memcpy(inbuf_saved,inbuf2,smb_wct);
4703 memcpy(outbuf_saved,outbuf2,smb_wct);
4705 /* give the new packet the same header as the last part of the SMB */
4706 memmove(inbuf2,inbuf,smb_wct);
4708 /* create the in buffer */
4709 CVAL(inbuf2,smb_com) = smb_com2;
4711 /* create the out buffer */
4712 bzero(outbuf2,smb_size);
4713 set_message(outbuf2,0,0,True);
4714 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4716 memcpy(outbuf2+4,inbuf2+4,4);
4717 CVAL(outbuf2,smb_rcls) = SUCCESS;
4718 CVAL(outbuf2,smb_reh) = 0;
4719 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4720 means a reply */
4721 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4722 SSVAL(outbuf2,smb_err,SUCCESS);
4723 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4724 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4725 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4726 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4728 DEBUG(3,("Chained message\n"));
4729 show_msg(inbuf2);
4731 /* process the request */
4732 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4733 bufsize-chain_size);
4735 /* copy the new reply and request headers over the old ones, but
4736 preserve the smb_com field */
4737 memmove(orig_outbuf,outbuf2,smb_wct);
4738 CVAL(orig_outbuf,smb_com) = smb_com1;
4740 /* restore the saved data, being careful not to overwrite any
4741 data from the reply header */
4742 memcpy(inbuf2,inbuf_saved,smb_wct);
4744 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4745 if (ofs < 0) ofs = 0;
4746 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4749 return outsize2;
4754 /****************************************************************************
4755 construct a reply to the incoming packet
4756 ****************************************************************************/
4757 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4759 int type = CVAL(inbuf,smb_com);
4760 int outsize = 0;
4761 int msg_type = CVAL(inbuf,0);
4762 extern int chain_size;
4764 smb_last_time = time(NULL);
4766 chain_size = 0;
4767 chain_fnum = -1;
4768 reset_chain_pnum();
4770 bzero(outbuf,smb_size);
4772 if (msg_type != 0)
4773 return(reply_special(inbuf,outbuf));
4775 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4776 set_message(outbuf,0,0,True);
4778 memcpy(outbuf+4,inbuf+4,4);
4779 CVAL(outbuf,smb_rcls) = SUCCESS;
4780 CVAL(outbuf,smb_reh) = 0;
4781 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4782 means a reply */
4783 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4784 SSVAL(outbuf,smb_err,SUCCESS);
4785 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4786 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4787 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4788 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4790 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4792 outsize += chain_size;
4794 if(outsize > 4)
4795 smb_setlen(outbuf,outsize - 4);
4796 return(outsize);
4799 /****************************************************************************
4800 process commands from the client
4801 ****************************************************************************/
4802 static void process(void)
4804 extern int Client;
4806 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4807 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4808 if ((InBuffer == NULL) || (OutBuffer == NULL))
4809 return;
4811 InBuffer += SMB_ALIGNMENT;
4812 OutBuffer += SMB_ALIGNMENT;
4814 #if PRIME_NMBD
4815 DEBUG(3,("priming nmbd\n"));
4817 struct in_addr ip;
4818 ip = *interpret_addr2("localhost");
4819 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4820 *OutBuffer = 0;
4821 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4823 #endif
4825 /* re-initialise the timezone */
4826 TimeInit();
4828 while (True)
4830 int deadtime = lp_deadtime()*60;
4831 int counter;
4832 int last_keepalive=0;
4833 int service_load_counter = 0;
4834 BOOL got_smb = False;
4836 if (deadtime <= 0)
4837 deadtime = DEFAULT_SMBD_TIMEOUT;
4839 #if USE_READ_PREDICTION
4840 if (lp_readprediction())
4841 do_read_prediction();
4842 #endif
4844 errno = 0;
4846 for (counter=SMBD_SELECT_LOOP;
4847 !receive_message_or_smb(Client,oplock_sock,
4848 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4849 counter += SMBD_SELECT_LOOP)
4851 int i;
4852 time_t t;
4853 BOOL allidle = True;
4854 extern int keepalive;
4856 if (counter > 365 * 3600) /* big number of seconds. */
4858 counter = 0;
4859 service_load_counter = 0;
4862 if (smb_read_error == READ_EOF)
4864 DEBUG(3,("end of file from client\n"));
4865 return;
4868 if (smb_read_error == READ_ERROR)
4870 DEBUG(3,("receive_smb error (%s) exiting\n",
4871 strerror(errno)));
4872 return;
4875 t = time(NULL);
4877 /* become root again if waiting */
4878 unbecome_user();
4880 /* check for smb.conf reload */
4881 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4883 service_load_counter = counter;
4885 /* reload services, if files have changed. */
4886 reload_services(True);
4889 /* automatic timeout if all connections are closed */
4890 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4892 DEBUG(2,("%s Closing idle connection\n",timestring()));
4893 return;
4896 if (keepalive && (counter-last_keepalive)>keepalive)
4898 struct cli_state *cli = server_client();
4899 if (!send_keepalive(Client)) {
4900 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4901 return;
4903 /* also send a keepalive to the password server if its still
4904 connected */
4905 if (cli && cli->initialised)
4906 send_keepalive(cli->fd);
4907 last_keepalive = counter;
4910 /* check for connection timeouts */
4911 for (i=0;i<MAX_CONNECTIONS;i++)
4912 if (Connections[i].open)
4914 /* close dirptrs on connections that are idle */
4915 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4916 dptr_idlecnum(i);
4918 if (Connections[i].num_files_open > 0 ||
4919 (t-Connections[i].lastused)<deadtime)
4920 allidle = False;
4923 if (allidle && num_connections_open>0)
4925 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4926 return;
4930 if(got_smb)
4931 process_smb(InBuffer, OutBuffer);
4932 else
4933 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4938 /****************************************************************************
4939 initialise connect, service and file structs
4940 ****************************************************************************/
4941 static void init_structs(void )
4943 int i;
4944 get_myname(myhostname,NULL);
4946 for (i=0;i<MAX_CONNECTIONS;i++)
4948 Connections[i].open = False;
4949 Connections[i].num_files_open=0;
4950 Connections[i].lastused=0;
4951 Connections[i].used=False;
4952 string_init(&Connections[i].user,"");
4953 string_init(&Connections[i].dirpath,"");
4954 string_init(&Connections[i].connectpath,"");
4955 string_init(&Connections[i].origpath,"");
4958 for (i=0;i<MAX_OPEN_FILES;i++)
4960 Files[i].open = False;
4961 string_init(&Files[i].name,"");
4965 for (i=0;i<MAX_OPEN_FILES;i++)
4967 file_fd_struct *fd_ptr = &FileFd[i];
4968 fd_ptr->ref_count = 0;
4969 fd_ptr->dev = (int32)-1;
4970 fd_ptr->inode = (int32)-1;
4971 fd_ptr->fd = -1;
4972 fd_ptr->fd_readonly = -1;
4973 fd_ptr->fd_writeonly = -1;
4974 fd_ptr->real_open_flags = -1;
4977 /* for RPC pipes */
4978 init_rpc_pipe_hnd();
4980 #ifdef NTDOMAIN
4981 /* for LSA handles */
4982 init_lsa_policy_hnd();
4983 #endif
4985 init_dptrs();
4988 /****************************************************************************
4989 usage on the program
4990 ****************************************************************************/
4991 static void usage(char *pname)
4993 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4995 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4996 printf("Version %s\n",VERSION);
4997 printf("\t-D become a daemon\n");
4998 printf("\t-p port listen on the specified port\n");
4999 printf("\t-d debuglevel set the debuglevel\n");
5000 printf("\t-l log basename. Basename for log/debug files\n");
5001 printf("\t-s services file. Filename of services file\n");
5002 printf("\t-P passive only\n");
5003 printf("\t-a overwrite log file, don't append\n");
5004 printf("\n");
5008 /****************************************************************************
5009 main program
5010 ****************************************************************************/
5011 int main(int argc,char *argv[])
5013 extern BOOL append_log;
5014 /* shall I run as a daemon */
5015 BOOL is_daemon = False;
5016 int port = SMB_PORT;
5017 int opt;
5018 extern char *optarg;
5019 char pidFile[100] = { 0 };
5021 #ifdef NEED_AUTH_PARAMETERS
5022 set_auth_parameters(argc,argv);
5023 #endif
5025 #ifdef SecureWare
5026 setluid(0);
5027 #endif
5029 append_log = True;
5031 TimeInit();
5033 strcpy(debugf,SMBLOGFILE);
5035 setup_logging(argv[0],False);
5037 charset_initialise();
5039 /* make absolutely sure we run as root - to handle cases whre people
5040 are crazy enough to have it setuid */
5041 #ifdef USE_SETRES
5042 setresuid(0,0,0);
5043 #else
5044 setuid(0);
5045 seteuid(0);
5046 setuid(0);
5047 seteuid(0);
5048 #endif
5050 fault_setup(exit_server);
5051 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5053 /* we want total control over the permissions on created files,
5054 so set our umask to 0 */
5055 umask(0);
5057 GetWd(OriginalDir);
5059 init_uid();
5061 /* this is for people who can't start the program correctly */
5062 while (argc > 1 && (*argv[1] != '-'))
5064 argv++;
5065 argc--;
5068 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5069 switch (opt)
5071 case 'f':
5072 strncpy(pidFile, optarg, sizeof(pidFile));
5073 break;
5074 case 'O':
5075 strcpy(user_socket_options,optarg);
5076 break;
5077 case 'i':
5078 strcpy(scope,optarg);
5079 break;
5080 case 'P':
5082 extern BOOL passive;
5083 passive = True;
5085 break;
5086 case 's':
5087 strcpy(servicesf,optarg);
5088 break;
5089 case 'l':
5090 strcpy(debugf,optarg);
5091 break;
5092 case 'a':
5094 extern BOOL append_log;
5095 append_log = !append_log;
5097 break;
5098 case 'D':
5099 is_daemon = True;
5100 break;
5101 case 'd':
5102 if (*optarg == 'A')
5103 DEBUGLEVEL = 10000;
5104 else
5105 DEBUGLEVEL = atoi(optarg);
5106 break;
5107 case 'p':
5108 port = atoi(optarg);
5109 break;
5110 case 'h':
5111 usage(argv[0]);
5112 exit(0);
5113 break;
5114 default:
5115 usage(argv[0]);
5116 exit(1);
5119 reopen_logs();
5121 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5122 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5124 #ifndef NO_GETRLIMIT
5125 #ifdef RLIMIT_NOFILE
5127 struct rlimit rlp;
5128 getrlimit(RLIMIT_NOFILE, &rlp);
5129 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5130 setrlimit(RLIMIT_NOFILE, &rlp);
5131 getrlimit(RLIMIT_NOFILE, &rlp);
5132 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5134 #endif
5135 #endif
5138 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5139 getuid(),getgid(),geteuid(),getegid()));
5141 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5143 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5144 exit(1);
5147 init_structs();
5149 if (!reload_services(False))
5150 return(-1);
5152 codepage_initialise(lp_client_code_page());
5154 strcpy(myworkgroup, lp_workgroup());
5156 #ifndef NO_SIGNAL_TEST
5157 signal(SIGHUP,SIGNAL_CAST sig_hup);
5158 #endif
5160 DEBUG(3,("%s loaded services\n",timestring()));
5162 if (!is_daemon && !is_a_socket(0))
5164 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5165 is_daemon = True;
5168 if (is_daemon)
5170 DEBUG(3,("%s becoming a daemon\n",timestring()));
5171 become_daemon();
5174 if (!directory_exist(lp_lockdir(), NULL)) {
5175 mkdir(lp_lockdir(), 0755);
5178 if (*pidFile)
5180 int fd;
5181 char buf[20];
5183 if ((fd = open(pidFile,
5184 #ifdef O_NONBLOCK
5185 O_NONBLOCK |
5186 #endif
5187 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5189 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5190 exit(1);
5192 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5194 DEBUG(0,("ERROR: smbd is already running\n"));
5195 exit(1);
5197 sprintf(buf, "%u\n", (unsigned int) getpid());
5198 if (write(fd, buf, strlen(buf)) < 0)
5200 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5201 exit(1);
5203 /* Leave pid file open & locked for the duration... */
5206 if (!open_sockets(is_daemon,port))
5207 exit(1);
5209 if (!locking_init(0))
5210 exit(1);
5212 /* possibly reload the services file. */
5213 reload_services(True);
5215 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5217 if (*lp_rootdir())
5219 if (sys_chroot(lp_rootdir()) == 0)
5220 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5223 /* Setup the oplock IPC socket. */
5224 if(!open_oplock_ipc())
5225 exit(1);
5227 process();
5228 close_sockets();
5230 exit_server("normal exit");
5231 return(0);