server.c: Added fix where, if all the file entries are being
[samba.git] / source / smbd / server.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Main SMB server routines
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23 #include "trans2.h"
24
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
29
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
33
34 int am_parent = 1;
35 int atexit_set = 0;
36
37 /* the last message the was processed */
38 int last_message = -1;
39
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
42
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;
52
53 extern int smb_read_error;
54
55 extern pstring user_socket_options;
56
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
59
60 /*
61  * Indirection for file fd's. Needed as POSIX locking
62  * is based on file/process, not fd/process.
63  */
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
66
67 extern int Protocol;
68
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.
73  */
74 int max_send = BUFFER_SIZE;
75 /*
76  * Size of the data we can receive. Set by us.
77  * Can be modified by the max xmit parameter.
78  */
79 int max_recv = BUFFER_SIZE;
80
81 /* a fnum to use when chaining */
82 int chain_fnum = -1;
83
84 /* number of open connections */
85 static int num_connections_open = 0;
86
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;
92
93 BOOL global_oplock_break = False;
94
95 extern fstring remote_machine;
96
97 extern pstring OriginalDir;
98
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;
102
103
104 extern int extra_time_offset;
105
106 extern pstring myhostname;
107
108 static int find_free_connection(int hash);
109
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)
116
117 /****************************************************************************
118   when exiting, take the whole family
119 ****************************************************************************/
120 void  *dflt_sig(void)
121 {
122   exit_server("caught signal");
123   return 0; /* Keep -Wall happy :-) */
124 }
125 /****************************************************************************
126   Send a SIGTERM to our process group.
127 *****************************************************************************/
128 void  killkids(void)
129 {
130   if(am_parent) kill(0,SIGTERM);
131 }
132
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)
149 {
150   mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
151
152   if ( !IS_DOS_READONLY(dosmode) )
153     result |= (S_IWUSR | S_IWGRP | S_IWOTH);
154  
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;
166
167     if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
168       result |= S_IXGRP;
169  
170     if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
171       result |= S_IXOTH;  
172  
173     /* Apply mode mask */
174     result &= lp_create_mode(SNUM(cnum));
175     /* Add in force bits */
176     result |= lp_force_create_mode(SNUM(cnum));
177   }
178   return(result);
179 }
180
181
182 /****************************************************************************
183   change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
186 {
187   int result = 0;
188   extern struct current_user current_user;
189
190   DEBUG(8,("dos_mode: %d %s\n", cnum, path));
191
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;
203   }
204
205   if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
206     result |= aARCH;
207
208   if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
209     result |= aSYSTEM;
210
211   if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
212     result |= aHIDDEN;   
213   
214   if (S_ISDIR(sbuf->st_mode))
215     result = aDIR | (result & aRONLY);
216
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
223
224   /* hide files with a name starting with a . */
225   if (lp_hide_dot_files(SNUM(cnum)))
226     {
227       char *p = strrchr(path,'/');
228       if (p)
229         p++;
230       else
231         p = path;
232       
233       if (p[0] == '.' && p[1] != '.' && p[1] != 0)
234         result |= aHIDDEN;
235     }
236
237   /* Optimization : Only call is_hidden_path if it's not already
238      hidden. */
239   if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
240   {
241     result |= aHIDDEN;
242   }
243
244   DEBUG(8,("dos_mode returning "));
245
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"));
251
252   DEBUG(8,("\n"));
253
254   return(result);
255 }
256
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
261 {
262   struct stat st1;
263   int mask=0;
264   int tmp;
265   int unixmode;
266
267   if (!st) {
268     st = &st1;
269     if (sys_stat(fname,st)) return(-1);
270   }
271
272   if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
273
274   if (dos_mode(cnum,fname,st) == dosmode) return(0);
275
276   unixmode = unix_mode(cnum,dosmode);
277
278   /* preserve the s bits */
279   mask |= (S_ISUID | S_ISGID);
280
281   /* preserve the t bit */
282 #ifdef S_ISVTX
283   mask |= S_ISVTX;
284 #endif
285
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;
290
291   unixmode |= (st->st_mode & mask);
292
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;
297   }
298
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;
305   }
306
307   return(sys_chmod(fname,unixmode));
308 }
309
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
312 than POSIX.
313 *******************************************************************/
314
315 int file_utime(int cnum, char *fname, struct utimbuf *times)
316 {
317   extern struct current_user current_user;
318   struct stat sb;
319   int ret = -1;
320
321   errno = 0;
322
323   if(sys_utime(fname, times) == 0)
324     return 0;
325
326   if((errno != EPERM) && (errno != EACCES))
327     return -1;
328
329   if(!lp_dos_filetimes(SNUM(cnum)))
330     return -1;
331
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).
336    */
337
338   if(sys_stat(fname,&sb) != 0)
339     return -1;
340
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);
353           }
354   }
355
356   return ret;
357 }
358   
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
362
363 BOOL set_filetime(int cnum, char *fname, time_t mtime)
364 {
365   struct utimbuf times;
366
367   if (null_mtime(mtime)) return(True);
368
369   times.modtime = times.actime = mtime;
370
371   if (file_utime(cnum, fname, &times)) {
372     DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
373   }
374   
375   return(True);
376
377
378 /****************************************************************************
379 check if two filenames are equal
380
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL fname_equal(char *name1, char *name2)
384 {
385   int l1 = strlen(name1);
386   int l2 = strlen(name2);
387
388   /* handle filenames ending in a single dot */
389   if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
390     {
391       BOOL ret;
392       name1[l1-1] = 0;
393       ret = fname_equal(name1,name2);
394       name1[l1-1] = '.';
395       return(ret);
396     }
397
398   if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
399     {
400       BOOL ret;
401       name2[l2-1] = 0;
402       ret = fname_equal(name1,name2);
403       name2[l2-1] = '.';
404       return(ret);
405     }
406
407   /* now normal filename handling */
408   if (case_sensitive)
409     return(strcmp(name1,name2) == 0);
410
411   return(strequal(name1,name2));
412 }
413
414
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)
419 {
420   pstring tmpname;
421
422   if (is_8_3(name2, True))
423     return(False);
424
425   strcpy(tmpname,name2);
426   mangle_name_83(tmpname);
427
428   return(strequal(name1,tmpname));
429 }
430
431
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
434
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)
438 {
439   void *cur_dir;
440   char *dname;
441   BOOL mangled;
442   pstring name2;
443
444   mangled = is_mangled(name);
445
446   /* handle null paths */
447   if (*path == 0)
448     path = ".";
449
450   if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
451     strcpy(name, dname);        
452     return(True);
453   }      
454
455 #if 0 
456   /* 
457    * This code I believe is incorrect - and commenting it out
458    * is the correct fix for the bug mentioned below in the
459    * comment 'name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra)'.
460    * The incoming name can be mangled, and if we de-mangle it
461    * here it will not compare correctly against the filename (name2)
462    * read from the directory and then mangled by the name_map_mangle()
463    * call. We need to mangle both names or neither.
464    * (JRA).
465    */
466   if (mangled)
467     check_mangled_stack(name);
468 #endif 
469
470   /* open the directory */
471   if (!(cur_dir = OpenDir(cnum, path, True))) 
472     {
473       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
474       return(False);
475     }
476
477   /* now scan for matching names */
478   while ((dname = ReadDirName(cur_dir))) 
479     {
480       if (*dname == '.' &&
481           (strequal(dname,".") || strequal(dname,"..")))
482         continue;
483
484       pstrcpy(name2,dname);
485       if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
486
487       if ((mangled && mangled_equal(name,name2))
488           || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
489         {
490           /* we've found the file, change it's name and return */
491           if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
492           strcpy(name, dname);
493           CloseDir(cur_dir);
494           return(True);
495         }
496     }
497
498   CloseDir(cur_dir);
499   return(False);
500 }
501
502 /****************************************************************************
503 This routine is called to convert names from the dos namespace to unix
504 namespace. It needs to handle any case conversions, mangling, format
505 changes etc.
506
507 We assume that we have already done a chdir() to the right "root" directory
508 for this service.
509
510 The function will return False if some part of the name except for the last
511 part cannot be resolved
512
513 If the saved_last_component != 0, then the unmodified last component
514 of the pathname is returned there. This is used in an exceptional
515 case in reply_mv (so far). If saved_last_component == 0 then nothing
516 is returned there.
517
518 The bad_path arg is set to True if the filename walk failed. This is
519 used to pick the correct error code to return between ENOENT and ENOTDIR
520 as Windows applications depend on ERRbadpath being returned if a component
521 of a pathname does not exist.
522 ****************************************************************************/
523 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
524 {
525   struct stat st;
526   char *start, *end;
527   pstring dirpath;
528   int saved_errno;
529
530   *dirpath = 0;
531   *bad_path = False;
532
533   if(saved_last_component)
534     *saved_last_component = 0;
535
536   /* convert to basic unix format - removing \ chars and cleaning it up */
537   unix_format(name);
538   unix_clean_name(name);
539
540   /* names must be relative to the root of the service - trim any leading /.
541    also trim trailing /'s */
542   trim_string(name,"/","/");
543
544   /*
545    * Ensure saved_last_component is valid even if file exists.
546    */
547   if(saved_last_component) {
548     end = strrchr(name, '/');
549     if(end)
550       strcpy(saved_last_component, end + 1);
551     else
552       strcpy(saved_last_component, name);
553   }
554
555   if (!case_sensitive && 
556       (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
557     strnorm(name);
558
559   /* check if it's a printer file */
560   if (Connections[cnum].printer)
561     {
562       if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
563         {
564           char *s;
565           fstring name2;
566           sprintf(name2,"%.6s.XXXXXX",remote_machine);
567           /* sanitise the name */
568           for (s=name2 ; *s ; s++)
569             if (!issafe(*s)) *s = '_';
570           strcpy(name,(char *)mktemp(name2));     
571         }      
572       return(True);
573     }
574
575   /* stat the name - if it exists then we are all done! */
576   if (sys_stat(name,&st) == 0)
577     return(True);
578
579   saved_errno = errno;
580
581   DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
582
583   /* a special case - if we don't have any mangling chars and are case
584      sensitive then searching won't help */
585   if (case_sensitive && !is_mangled(name) && 
586       !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
587     return(False);
588
589   /* now we need to recursively match the name against the real 
590      directory structure */
591
592   start = name;
593   while (strncmp(start,"./",2) == 0)
594     start += 2;
595
596   /* now match each part of the path name separately, trying the names
597      as is first, then trying to scan the directory for matching names */
598   for (;start;start = (end?end+1:(char *)NULL)) 
599     {
600       /* pinpoint the end of this section of the filename */
601       end = strchr(start, '/');
602
603       /* chop the name at this point */
604       if (end)  *end = 0;
605
606       if(saved_last_component != 0)
607         strcpy(saved_last_component, end ? end + 1 : start);
608
609       /* check if the name exists up to this point */
610       if (sys_stat(name, &st) == 0) 
611         {
612           /* it exists. it must either be a directory or this must be
613              the last part of the path for it to be OK */
614           if (end && !(st.st_mode & S_IFDIR)) 
615             {
616               /* an intermediate part of the name isn't a directory */
617               DEBUG(5,("Not a dir %s\n",start));
618               *end = '/';
619               return(False);
620             }
621         }
622       else 
623         {
624           pstring rest;
625
626           *rest = 0;
627
628           /* remember the rest of the pathname so it can be restored
629              later */
630           if (end) pstrcpy(rest,end+1);
631
632           /* try to find this part of the path in the directory */
633           if (strchr(start,'?') || strchr(start,'*') ||
634               !scan_directory(dirpath, start, cnum, end?True:False))
635             {
636               if (end) 
637                 {
638                   /* an intermediate part of the name can't be found */
639                   DEBUG(5,("Intermediate not found %s\n",start));
640                   *end = '/';
641                   /* We need to return the fact that the intermediate
642                      name resolution failed. This is used to return an
643                      error of ERRbadpath rather than ERRbadfile. Some
644                      Windows applications depend on the difference between
645                      these two errors.
646                    */
647                   *bad_path = True;
648                   return(False);
649                 }
650               
651               /* just the last part of the name doesn't exist */
652               /* we may need to strupper() or strlower() it in case
653                  this conversion is being used for file creation 
654                  purposes */
655               /* if the filename is of mixed case then don't normalise it */
656               if (!case_preserve && 
657                   (!strhasupper(start) || !strhaslower(start)))         
658                 strnorm(start);
659
660               /* check on the mangled stack to see if we can recover the 
661                  base of the filename */
662               if (is_mangled(start))
663                 check_mangled_stack(start);
664
665               DEBUG(5,("New file %s\n",start));
666               return(True); 
667             }
668
669           /* restore the rest of the string */
670           if (end) 
671             {
672               strcpy(start+strlen(start)+1,rest);
673               end = start + strlen(start);
674             }
675         }
676
677       /* add to the dirpath that we have resolved so far */
678       if (*dirpath) strcat(dirpath,"/");
679       strcat(dirpath,start);
680
681       /* restore the / that we wiped out earlier */
682       if (end) *end = '/';
683     }
684   
685   /* the name has been resolved */
686   DEBUG(5,("conversion finished %s\n",name));
687   return(True);
688 }
689
690
691 /****************************************************************************
692 normalise for DOS usage 
693 ****************************************************************************/
694 static void disk_norm(int *bsize,int *dfree,int *dsize)
695 {
696   /* check if the disk is beyond the max disk size */
697   int maxdisksize = lp_maxdisksize();
698   if (maxdisksize) {
699     /* convert to blocks - and don't overflow */
700     maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
701     if (*dsize > maxdisksize) *dsize = maxdisksize;
702     if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop 
703                                                          applications getting 
704                                                          div by 0 errors */
705   }  
706
707   while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) 
708     {
709       *dfree /= 2;
710       *dsize /= 2;
711       *bsize *= 2;
712       if (*bsize > WORDMAX )
713         {
714           *bsize = WORDMAX;
715           if (*dsize > WORDMAX)
716             *dsize = WORDMAX;
717           if (*dfree >  WORDMAX)
718             *dfree = WORDMAX;
719           break;
720         }
721     }
722 }
723
724 /****************************************************************************
725   return number of 1K blocks available on a path and total number 
726 ****************************************************************************/
727 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
728 {
729   char *df_command = lp_dfree_command();
730   int dfree_retval;
731 #ifdef QUOTAS
732   int dfreeq_retval;
733   int dfreeq = 0;
734   int bsizeq = *bsize;
735   int dsizeq = *dsize;
736 #endif
737
738 #ifndef NO_STATFS
739 #ifdef USE_STATVFS
740   struct statvfs fs;
741 #else
742 #ifdef ULTRIX
743   struct fs_data fs;
744 #else
745   struct statfs fs;
746 #endif
747 #endif
748 #endif
749
750   /* possibly use system() to get the result */
751   if (df_command && *df_command)
752     {
753       int ret;
754       pstring syscmd;
755       pstring outfile;
756           
757       sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
758       sprintf(syscmd,"%s %s",df_command,path);
759       standard_sub_basic(syscmd);
760
761       ret = smbrun(syscmd,outfile,False);
762       DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
763           
764       {
765         FILE *f = fopen(outfile,"r");   
766         *dsize = 0;
767         *dfree = 0;
768         *bsize = 1024;
769         if (f)
770           {
771             fscanf(f,"%d %d %d",dsize,dfree,bsize);
772             fclose(f);
773           }
774         else
775           DEBUG(0,("Can't open %s\n",outfile));
776       }
777           
778       unlink(outfile);
779       disk_norm(bsize,dfree,dsize);
780       dfree_retval = ((*bsize)/1024)*(*dfree);
781 #ifdef QUOTAS
782       /* Ensure we return the min value between the users quota and
783          what's free on the disk. Thanks to Albrecht Gebhardt 
784          <albrecht.gebhardt@uni-klu.ac.at> for this fix.
785       */
786       if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
787         {
788           disk_norm(&bsizeq, &dfreeq, &dsizeq);
789           dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
790           dfree_retval =  ( dfree_retval < dfreeq_retval ) ? 
791                            dfree_retval : dfreeq_retval ;
792           /* maybe dfree and dfreeq are calculated using different bsizes 
793              so convert dfree from bsize into bsizeq */
794           /* avoid overflows due to multiplication, so do not:
795                 *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
796              bsize and bsizeq are powers of 2 so its better to
797              to divide them getting a multiplication or division factor
798              for dfree. Rene Nieuwenhuizen (07-10-1997) */
799           if (*bsize >= bsizeq) 
800             *dfree = *dfree * (*bsize / bsizeq);
801           else 
802             *dfree = *dfree / (bsizeq / *bsize);
803           *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; 
804           *bsize = bsizeq;
805           *dsize = dsizeq;
806         }
807 #endif
808       return(dfree_retval);
809     }
810
811 #ifdef NO_STATFS
812   DEBUG(1,("Warning - no statfs function\n"));
813   return(1);
814 #else
815 #ifdef STATFS4
816   if (statfs(path,&fs,sizeof(fs),0) != 0)
817 #else
818 #ifdef USE_STATVFS
819     if (statvfs(path, &fs))
820 #else
821 #ifdef STATFS3
822       if (statfs(path,&fs,sizeof(fs)) == -1)     
823 #else
824         if (statfs(path,&fs) == -1)
825 #endif /* STATFS3 */
826 #endif /* USE_STATVFS */
827 #endif /* STATFS4 */
828           {
829             DEBUG(3,("dfree call failed code errno=%d\n",errno));
830             *bsize = 1024;
831             *dfree = 1;
832             *dsize = 1;
833             return(((*bsize)/1024)*(*dfree));
834           }
835
836 #ifdef ULTRIX
837   *bsize = 1024;
838   *dfree = fs.fd_req.bfree;
839   *dsize = fs.fd_req.btot;
840 #else
841 #ifdef USE_STATVFS
842   *bsize = fs.f_frsize;
843 #else
844 #ifdef USE_F_FSIZE
845   /* eg: osf1 has f_fsize = fundamental filesystem block size, 
846      f_bsize = optimal transfer block size (MX: 94-04-19) */
847   *bsize = fs.f_fsize;
848 #else
849   *bsize = fs.f_bsize;
850 #endif /* STATFS3 */
851 #endif /* USE_STATVFS */
852
853 #ifdef STATFS4
854   *dfree = fs.f_bfree;
855 #else
856   *dfree = fs.f_bavail;
857 #endif /* STATFS4 */
858   *dsize = fs.f_blocks;
859 #endif /* ULTRIX */
860
861 #if defined(SCO) || defined(ISC) || defined(MIPS)
862   *bsize = 512;
863 #endif
864
865 /* handle rediculous bsize values - some OSes are broken */
866 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
867
868   disk_norm(bsize,dfree,dsize);
869
870   if (*bsize < 256)
871     *bsize = 512;
872   if ((*dsize)<1)
873     {
874       DEBUG(0,("dfree seems to be broken on your system\n"));
875       *dsize = 20*1024*1024/(*bsize);
876       *dfree = MAX(1,*dfree);
877     }
878   dfree_retval = ((*bsize)/1024)*(*dfree);
879 #ifdef QUOTAS
880   /* Ensure we return the min value between the users quota and
881      what's free on the disk. Thanks to Albrecht Gebhardt 
882      <albrecht.gebhardt@uni-klu.ac.at> for this fix.
883   */
884   if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
885     {
886       disk_norm(&bsizeq, &dfreeq, &dsizeq);
887       dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
888       dfree_retval = ( dfree_retval < dfreeq_retval ) ? 
889                        dfree_retval : dfreeq_retval ;
890       /* maybe dfree and dfreeq are calculated using different bsizes 
891          so convert dfree from bsize into bsizeq */
892       /* avoid overflows due to multiplication, so do not:
893               *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
894        bsize and bsizeq are powers of 2 so its better to
895        to divide them getting a multiplication or division factor
896        for dfree. Rene Nieuwenhuizen (07-10-1997) */
897       if (*bsize >= bsizeq)
898         *dfree = *dfree * (*bsize / bsizeq);
899       else
900         *dfree = *dfree / (bsizeq / *bsize);
901       *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
902       *bsize = bsizeq;
903       *dsize = dsizeq;
904     }
905 #endif
906   return(dfree_retval);
907 #endif
908 }
909
910
911 /****************************************************************************
912 wrap it to get filenames right
913 ****************************************************************************/
914 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
915 {
916   return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
917 }
918
919
920
921 /****************************************************************************
922 check a filename - possibly caling reducename
923
924 This is called by every routine before it allows an operation on a filename.
925 It does any final confirmation necessary to ensure that the filename is
926 a valid one for the user to access.
927 ****************************************************************************/
928 BOOL check_name(char *name,int cnum)
929 {
930   BOOL ret;
931
932   errno = 0;
933
934   if( IS_VETO_PATH(cnum, name)) 
935     {
936       DEBUG(5,("file path name %s vetoed\n",name));
937       return(0);
938     }
939
940   ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
941
942   /* Check if we are allowing users to follow symlinks */
943   /* Patch from David Clerc <David.Clerc@cui.unige.ch>
944      University of Geneva */
945
946 #ifdef S_ISLNK
947   if (!lp_symlinks(SNUM(cnum)))
948     {
949       struct stat statbuf;
950       if ( (sys_lstat(name,&statbuf) != -1) &&
951           (S_ISLNK(statbuf.st_mode)) )
952         {
953           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
954           ret=0; 
955         }
956     }
957 #endif
958
959   if (!ret)
960     DEBUG(5,("check_name on %s failed\n",name));
961
962   return(ret);
963 }
964
965 /****************************************************************************
966 check a filename - possibly caling reducename
967 ****************************************************************************/
968 static void check_for_pipe(char *fname)
969 {
970   /* special case of pipe opens */
971   char s[10];
972   StrnCpy(s,fname,9);
973   strlower(s);
974   if (strstr(s,"pipe/"))
975     {
976       DEBUG(3,("Rejecting named pipe open for %s\n",fname));
977       unix_ERR_class = ERRSRV;
978       unix_ERR_code = ERRaccess;
979     }
980 }
981
982 /****************************************************************************
983 fd support routines - attempt to do a sys_open
984 ****************************************************************************/
985 static int fd_attempt_open(char *fname, int flags, int mode)
986 {
987   int fd = sys_open(fname,flags,mode);
988
989   /* Fix for files ending in '.' */
990   if((fd == -1) && (errno == ENOENT) &&
991      (strchr(fname,'.')==NULL))
992     {
993       strcat(fname,".");
994       fd = sys_open(fname,flags,mode);
995     }
996
997 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
998   if ((fd == -1) && (errno == ENAMETOOLONG))
999     {
1000       int max_len;
1001       char *p = strrchr(fname, '/');
1002
1003       if (p == fname)   /* name is "/xxx" */
1004         {
1005           max_len = pathconf("/", _PC_NAME_MAX);
1006           p++;
1007         }
1008       else if ((p == NULL) || (p == fname))
1009         {
1010           p = fname;
1011           max_len = pathconf(".", _PC_NAME_MAX);
1012         }
1013       else
1014         {
1015           *p = '\0';
1016           max_len = pathconf(fname, _PC_NAME_MAX);
1017           *p = '/';
1018           p++;
1019         }
1020       if (strlen(p) > max_len)
1021         {
1022           char tmp = p[max_len];
1023
1024           p[max_len] = '\0';
1025           if ((fd = sys_open(fname,flags,mode)) == -1)
1026             p[max_len] = tmp;
1027         }
1028     }
1029 #endif
1030   return fd;
1031 }
1032
1033 /****************************************************************************
1034 fd support routines - attempt to find an already open file by dev
1035 and inode - increments the ref_count of the returned file_fd_struct *.
1036 ****************************************************************************/
1037 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1038 {
1039   int i;
1040   file_fd_struct *fd_ptr;
1041
1042   if(sbuf == 0)
1043     return 0;
1044
1045   for(i = 0; i <= max_file_fd_used; i++) {
1046     fd_ptr = &FileFd[i];
1047     if((fd_ptr->ref_count > 0) &&
1048        (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1049        (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1050       fd_ptr->ref_count++;
1051       DEBUG(3,
1052        ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1053         i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1054       return fd_ptr;
1055     }
1056   }
1057   return 0;
1058 }
1059
1060 /****************************************************************************
1061 fd support routines - attempt to find a empty slot in the FileFd array.
1062 Increments the ref_count of the returned entry.
1063 ****************************************************************************/
1064 static file_fd_struct *fd_get_new()
1065 {
1066   int i;
1067   file_fd_struct *fd_ptr;
1068
1069   for(i = 0; i < MAX_OPEN_FILES; i++) {
1070     fd_ptr = &FileFd[i];
1071     if(fd_ptr->ref_count == 0) {
1072       fd_ptr->dev = (uint32)-1;
1073       fd_ptr->inode = (uint32)-1;
1074       fd_ptr->fd = -1;
1075       fd_ptr->fd_readonly = -1;
1076       fd_ptr->fd_writeonly = -1;
1077       fd_ptr->real_open_flags = -1;
1078       fd_ptr->ref_count++;
1079       /* Increment max used counter if neccessary, cuts down
1080          on search time when re-using */
1081       if(i > max_file_fd_used)
1082         max_file_fd_used = i;
1083       DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1084                i, fd_ptr->dev, fd_ptr->inode));
1085       return fd_ptr;
1086     }
1087   }
1088   DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1089 n"));
1090   return 0;
1091 }
1092
1093 /****************************************************************************
1094 fd support routines - attempt to re-open an already open fd as O_RDWR.
1095 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1096 ****************************************************************************/
1097 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1098 {
1099   int fd = sys_open( fname, O_RDWR, mode);
1100
1101   if(fd == -1)
1102     return;
1103
1104   if(fd_ptr->real_open_flags == O_RDONLY)
1105     fd_ptr->fd_readonly = fd_ptr->fd;
1106   if(fd_ptr->real_open_flags == O_WRONLY)
1107     fd_ptr->fd_writeonly = fd_ptr->fd;
1108
1109   fd_ptr->fd = fd;
1110   fd_ptr->real_open_flags = O_RDWR;
1111 }
1112
1113 /****************************************************************************
1114 fd support routines - attempt to close the file referenced by this fd.
1115 Decrements the ref_count and returns it.
1116 ****************************************************************************/
1117 static int fd_attempt_close(file_fd_struct *fd_ptr)
1118 {
1119   DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1120            fd_ptr - &FileFd[0],
1121            fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1122            fd_ptr->real_open_flags,
1123            fd_ptr->ref_count));
1124   if(fd_ptr->ref_count > 0) {
1125     fd_ptr->ref_count--;
1126     if(fd_ptr->ref_count == 0) {
1127       if(fd_ptr->fd != -1)
1128         close(fd_ptr->fd);
1129       if(fd_ptr->fd_readonly != -1)
1130         close(fd_ptr->fd_readonly);
1131       if(fd_ptr->fd_writeonly != -1)
1132         close(fd_ptr->fd_writeonly);
1133       fd_ptr->fd = -1;
1134       fd_ptr->fd_readonly = -1;
1135       fd_ptr->fd_writeonly = -1;
1136       fd_ptr->real_open_flags = -1;
1137       fd_ptr->dev = (uint32)-1;
1138       fd_ptr->inode = (uint32)-1;
1139     }
1140   } 
1141  return fd_ptr->ref_count;
1142 }
1143
1144 /****************************************************************************
1145 open a file
1146 ****************************************************************************/
1147 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1148 {
1149   extern struct current_user current_user;
1150   pstring fname;
1151   struct stat statbuf;
1152   file_fd_struct *fd_ptr;
1153   files_struct *fsp = &Files[fnum];
1154   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1155
1156   fsp->open = False;
1157   fsp->fd_ptr = 0;
1158   fsp->granted_oplock = False;
1159   errno = EPERM;
1160
1161   pstrcpy(fname,fname1);
1162
1163   /* check permissions */
1164
1165   /*
1166    * This code was changed after seeing a client open request 
1167    * containing the open mode of (DENY_WRITE/read-only) with
1168    * the 'create if not exist' bit set. The previous code
1169    * would fail to open the file read only on a read-only share
1170    * as it was checking the flags parameter  directly against O_RDONLY,
1171    * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1172    * JRA.
1173    */
1174
1175   if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1176     /* It's a read-only share - fail if we wanted to write. */
1177     if(accmode != O_RDONLY) {
1178       DEBUG(3,("Permission denied opening %s\n",fname));
1179       check_for_pipe(fname);
1180       return;
1181     }
1182     else if(flags & O_CREAT) {
1183       /* We don't want to write - but we must make sure that O_CREAT
1184          doesn't create the file if we have write access into the
1185          directory.
1186        */
1187       flags &= ~O_CREAT;
1188     }
1189   }
1190
1191   /* this handles a bug in Win95 - it doesn't say to create the file when it 
1192      should */
1193   if (Connections[cnum].printer)
1194     flags |= O_CREAT;
1195
1196 /*
1197   if (flags == O_WRONLY)
1198     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1199 */
1200
1201   /*
1202    * Ensure we have a valid struct stat so we can search the
1203    * open fd table.
1204    */
1205   if(sbuf == 0) {
1206     if(stat(fname, &statbuf) < 0) {
1207       if(errno != ENOENT) {
1208         DEBUG(3,("Error doing stat on file %s (%s)\n",
1209                  fname,strerror(errno)));
1210
1211         check_for_pipe(fname);
1212         return;
1213       }
1214       sbuf = 0;
1215     } else {
1216       sbuf = &statbuf;
1217     }
1218   }
1219
1220   /*
1221    * Check to see if we have this file already
1222    * open. If we do, just use the already open fd and increment the
1223    * reference count (fd_get_already_open increments the ref_count).
1224    */
1225   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1226
1227     /* File was already open. */
1228     if((flags & O_CREAT) && (flags & O_EXCL)) {
1229       fd_ptr->ref_count--;
1230       errno = EEXIST;
1231       return;
1232     }
1233
1234     /* 
1235      * If not opened O_RDWR try
1236      * and do that here - a chmod may have been done
1237      * between the last open and now. 
1238      */
1239     if(fd_ptr->real_open_flags != O_RDWR)
1240       fd_attempt_reopen(fname, mode, fd_ptr);
1241
1242     /*
1243      * Ensure that if we wanted write access
1244      * it has been opened for write, and if we wanted read it
1245      * was open for read. 
1246      */
1247     if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1248        ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1249        ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1250       DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1251                fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1252       check_for_pipe(fname);
1253       fd_ptr->ref_count--;
1254       return;
1255     }
1256
1257   } else {
1258     int open_flags;
1259     /* We need to allocate a new file_fd_struct (this increments the
1260        ref_count). */
1261     if((fd_ptr = fd_get_new()) == 0)
1262       return;
1263     /*
1264      * Whatever the requested flags, attempt read/write access,
1265      * as we don't know what flags future file opens may require.
1266      * If this fails, try again with the required flags. 
1267      * Even if we open read/write when only read access was 
1268      * requested the setting of the can_write flag in
1269      * the file_struct will protect us from errant
1270      * write requests. We never need to worry about O_APPEND
1271      * as this is not set anywhere in Samba.
1272      */
1273     fd_ptr->real_open_flags = O_RDWR;
1274     /* Set the flags as needed without the read/write modes. */
1275     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1276     fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1277     /*
1278      * On some systems opening a file for R/W access on a read only
1279      * filesystems sets errno to EROFS.
1280      */
1281 #ifdef EROFS
1282     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1283 #else /* No EROFS */
1284     if((fd_ptr->fd == -1) && (errno == EACCES)) {
1285 #endif /* EROFS */
1286       if(flags & O_WRONLY) {
1287         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1288         fd_ptr->real_open_flags = O_WRONLY;
1289       } else {
1290         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1291         fd_ptr->real_open_flags = O_RDONLY;
1292       }
1293     }
1294   }
1295
1296   if ((fd_ptr->fd >=0) && 
1297       Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1298     pstring dname;
1299     int dum1,dum2,dum3;
1300     char *p;
1301     pstrcpy(dname,fname);
1302     p = strrchr(dname,'/');
1303     if (p) *p = 0;
1304     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
1305         lp_minprintspace(SNUM(cnum))) {
1306       fd_attempt_close(fd_ptr);
1307       fsp->fd_ptr = 0;
1308       if(fd_ptr->ref_count == 0)
1309         sys_unlink(fname);
1310       errno = ENOSPC;
1311       return;
1312     }
1313   }
1314     
1315   if (fd_ptr->fd < 0)
1316     {
1317       DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1318                fname,strerror(errno),flags));
1319       /* Ensure the ref_count is decremented. */
1320       fd_attempt_close(fd_ptr);
1321       check_for_pipe(fname);
1322       return;
1323     }
1324
1325   if (fd_ptr->fd >= 0)
1326     {
1327       if(sbuf == 0) {
1328         /* Do the fstat */
1329         if(fstat(fd_ptr->fd, &statbuf) == -1) {
1330           /* Error - backout !! */
1331           DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1332                    fd_ptr->fd, fname,strerror(errno)));
1333           /* Ensure the ref_count is decremented. */
1334           fd_attempt_close(fd_ptr);
1335           return;
1336         }
1337         sbuf = &statbuf;
1338       }
1339       /* Set the correct entries in fd_ptr. */
1340       fd_ptr->dev = (uint32)sbuf->st_dev;
1341       fd_ptr->inode = (uint32)sbuf->st_ino;
1342
1343       fsp->fd_ptr = fd_ptr;
1344       Connections[cnum].num_files_open++;
1345       fsp->mode = sbuf->st_mode;
1346       GetTimeOfDay(&fsp->open_time);
1347       fsp->uid = current_user.id;
1348       fsp->size = 0;
1349       fsp->pos = -1;
1350       fsp->open = True;
1351       fsp->mmap_ptr = NULL;
1352       fsp->mmap_size = 0;
1353       fsp->can_lock = True;
1354       fsp->can_read = ((flags & O_WRONLY)==0);
1355       fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1356       fsp->share_mode = 0;
1357       fsp->print_file = Connections[cnum].printer;
1358       fsp->modified = False;
1359       fsp->granted_oplock = False;
1360       fsp->sent_oplock_break = False;
1361       fsp->cnum = cnum;
1362       string_set(&fsp->name,dos_to_unix(fname,False));
1363       fsp->wbmpx_ptr = NULL;      
1364
1365       /*
1366        * If the printer is marked as postscript output a leading
1367        * file identifier to ensure the file is treated as a raw
1368        * postscript file.
1369        * This has a similar effect as CtrlD=0 in WIN.INI file.
1370        * tim@fsg.com 09/06/94
1371        */
1372       if (fsp->print_file && POSTSCRIPT(cnum) && 
1373           fsp->can_write) 
1374         {
1375           DEBUG(3,("Writing postscript line\n"));
1376           write_file(fnum,"%!\n",3);
1377         }
1378       
1379       DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1380                timestring(),Connections[cnum].user,fname,
1381                BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1382                Connections[cnum].num_files_open,fnum));
1383
1384     }
1385
1386 #if USE_MMAP
1387   /* mmap it if read-only */
1388   if (!fsp->can_write)
1389     {
1390       fsp->mmap_size = file_size(fname);
1391       fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1392                                           PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1393
1394       if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1395         {
1396           DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1397           fsp->mmap_ptr = NULL;
1398         }
1399     }
1400 #endif
1401 }
1402
1403 /*******************************************************************
1404 sync a file
1405 ********************************************************************/
1406 void sync_file(int fnum)
1407 {
1408 #ifndef NO_FSYNC
1409   fsync(Files[fnum].fd_ptr->fd);
1410 #endif
1411 }
1412
1413 /****************************************************************************
1414 run a file if it is a magic script
1415 ****************************************************************************/
1416 static void check_magic(int fnum,int cnum)
1417 {
1418   if (!*lp_magicscript(SNUM(cnum)))
1419     return;
1420
1421   DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1422
1423   {
1424     char *p;
1425     if (!(p = strrchr(Files[fnum].name,'/')))
1426       p = Files[fnum].name;
1427     else
1428       p++;
1429
1430     if (!strequal(lp_magicscript(SNUM(cnum)),p))
1431       return;
1432   }
1433
1434   {
1435     int ret;
1436     pstring magic_output;
1437     pstring fname;
1438     pstrcpy(fname,Files[fnum].name);
1439
1440     if (*lp_magicoutput(SNUM(cnum)))
1441       pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1442     else
1443       sprintf(magic_output,"%s.out",fname);
1444
1445     chmod(fname,0755);
1446     ret = smbrun(fname,magic_output,False);
1447     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1448     unlink(fname);
1449   }
1450 }
1451
1452
1453 /****************************************************************************
1454 close a file - possibly invalidating the read prediction
1455
1456 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1457 operation otherwise it came as the result of some other operation such as
1458 the closing of the connection. In the latter case printing and
1459 magic scripts are not run
1460 ****************************************************************************/
1461 void close_file(int fnum, BOOL normal_close)
1462 {
1463   files_struct *fs_p = &Files[fnum];
1464   int cnum = fs_p->cnum;
1465   uint32 dev = fs_p->fd_ptr->dev;
1466   uint32 inode = fs_p->fd_ptr->inode;
1467   int token;
1468
1469   Files[fnum].reserved = False;
1470
1471 #if USE_READ_PREDICTION
1472   invalidate_read_prediction(fs_p->fd_ptr->fd);
1473 #endif
1474
1475   fs_p->open = False;
1476   Connections[cnum].num_files_open--;
1477   if(fs_p->wbmpx_ptr) 
1478   {
1479     free((char *)fs_p->wbmpx_ptr);
1480     fs_p->wbmpx_ptr = NULL;
1481   }
1482
1483 #if USE_MMAP
1484   if(fs_p->mmap_ptr) 
1485   {
1486     munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1487     fs_p->mmap_ptr = NULL;
1488   }
1489 #endif
1490
1491   if (lp_share_modes(SNUM(cnum)))
1492   {
1493     lock_share_entry( cnum, dev, inode, &token);
1494     del_share_mode(token, fnum);
1495   }
1496
1497   fd_attempt_close(fs_p->fd_ptr);
1498
1499   if (lp_share_modes(SNUM(cnum)))
1500     unlock_share_entry( cnum, dev, inode, token);
1501
1502   /* NT uses smbclose to start a print - weird */
1503   if (normal_close && fs_p->print_file)
1504     print_file(fnum);
1505
1506   /* check for magic scripts */
1507   if (normal_close)
1508     check_magic(fnum,cnum);
1509
1510   if(fs_p->granted_oplock == True)
1511     global_oplocks_open--;
1512
1513   fs_p->sent_oplock_break = False;
1514
1515   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1516            timestring(),Connections[cnum].user,fs_p->name,
1517            Connections[cnum].num_files_open));
1518 }
1519
1520 enum {AFAIL,AREAD,AWRITE,AALL};
1521
1522 /*******************************************************************
1523 reproduce the share mode access table
1524 ********************************************************************/
1525 static int access_table(int new_deny,int old_deny,int old_mode,
1526                         int share_pid,char *fname)
1527 {
1528   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1529
1530   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1531     int pid = getpid();
1532     if (old_deny == new_deny && share_pid == pid) 
1533         return(AALL);    
1534
1535     if (old_mode == 0) return(AREAD);
1536
1537     /* the new smbpub.zip spec says that if the file extension is
1538        .com, .dll, .exe or .sym then allow the open. I will force
1539        it to read-only as this seems sensible although the spec is
1540        a little unclear on this. */
1541     if ((fname = strrchr(fname,'.'))) {
1542       if (strequal(fname,".com") ||
1543           strequal(fname,".dll") ||
1544           strequal(fname,".exe") ||
1545           strequal(fname,".sym"))
1546         return(AREAD);
1547     }
1548
1549     return(AFAIL);
1550   }
1551
1552   switch (new_deny) 
1553     {
1554     case DENY_WRITE:
1555       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1556       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1557       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1558       return(AFAIL);
1559     case DENY_READ:
1560       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1561       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1562       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1563       return(AFAIL);
1564     case DENY_NONE:
1565       if (old_deny==DENY_WRITE) return(AREAD);
1566       if (old_deny==DENY_READ) return(AWRITE);
1567       if (old_deny==DENY_NONE) return(AALL);
1568       return(AFAIL);      
1569     }
1570   return(AFAIL);      
1571 }
1572
1573 /*******************************************************************
1574 check if the share mode on a file allows it to be deleted or unlinked
1575 return True if sharing doesn't prevent the operation
1576 ********************************************************************/
1577 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1578 {
1579   int i;
1580   int ret = False;
1581   share_mode_entry *old_shares = 0;
1582   int num_share_modes;
1583   struct stat sbuf;
1584   int token;
1585   int pid = getpid();
1586   uint32 dev, inode;
1587
1588   if(!lp_share_modes(SNUM(cnum)))
1589     return True;
1590
1591   if (stat(fname,&sbuf) == -1) return(True);
1592
1593   dev = (uint32)sbuf.st_dev;
1594   inode = (uint32)sbuf.st_ino;
1595
1596   lock_share_entry(cnum, dev, inode, &token);
1597   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1598
1599   /*
1600    * Check if the share modes will give us access.
1601    */
1602
1603   if(num_share_modes != 0)
1604   {
1605     BOOL broke_oplock;
1606
1607     do
1608     {
1609
1610       broke_oplock = False;
1611       for(i = 0; i < num_share_modes; i++)
1612       {
1613         share_mode_entry *share_entry = &old_shares[i];
1614
1615         /* 
1616          * Break oplocks before checking share modes. See comment in
1617          * open_file_shared for details. 
1618          * Check if someone has an oplock on this file. If so we must 
1619          * break it before continuing. 
1620          */
1621         if(share_entry->op_type & BATCH_OPLOCK)
1622         {
1623
1624           /*
1625            * It appears that the NT redirector may have a bug, in that
1626            * it tries to do an SMBmv on a file that it has open with a
1627            * batch oplock, and then fails to respond to the oplock break
1628            * request. This only seems to occur when the client is doing an
1629            * SMBmv to the smbd it is using - thus we try and detect this
1630            * condition by checking if the file being moved is open and oplocked by
1631            * this smbd process, and then not sending the oplock break in this
1632            * special case. If the file was open with a deny mode that 
1633            * prevents the move the SMBmv will fail anyway with a share
1634            * violation error. JRA.
1635            */
1636           if(rename_op && (share_entry->pid == pid))
1637           {
1638             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1639 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1640 #if 0
1641             /* 
1642              * This next line is a test that allows the deny-mode
1643              * processing to be skipped. JRA.
1644              */ 
1645             continue;
1646 #endif
1647           }
1648           else
1649           {
1650             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1651 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1652
1653             /* Oplock break.... */
1654             unlock_share_entry(cnum, dev, inode, token);
1655             if(request_oplock_break(share_entry, dev, inode) == False)
1656             {
1657               free((char *)old_shares);
1658               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1659 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1660               return False;
1661             }
1662             lock_share_entry(cnum, dev, inode, &token);
1663             broke_oplock = True;
1664             break;
1665           }
1666         }
1667
1668         /* someone else has a share lock on it, check to see 
1669            if we can too */
1670         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1671           goto free_and_exit;
1672
1673       } /* end for */
1674
1675       if(broke_oplock)
1676       {
1677         free((char *)old_shares);
1678         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1679       }
1680     } while(broke_oplock);
1681   }
1682
1683   /* XXXX exactly what share mode combinations should be allowed for
1684      deleting/renaming? */
1685   /* If we got here then either there were no share modes or
1686      all share modes were DENY_DOS and the pid == getpid() */
1687   ret = True;
1688
1689 free_and_exit:
1690
1691   unlock_share_entry(cnum, dev, inode, token);
1692   if(old_shares != NULL)
1693     free((char *)old_shares);
1694   return(ret);
1695 }
1696
1697 /****************************************************************************
1698   C. Hoch 11/22/95
1699   Helper for open_file_shared. 
1700   Truncate a file after checking locking; close file if locked.
1701   **************************************************************************/
1702 static void truncate_unless_locked(int fnum, int cnum, int token, 
1703                                    BOOL *share_locked)
1704 {
1705   if (Files[fnum].can_write){
1706     if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1707       /* If share modes are in force for this connection we
1708          have the share entry locked. Unlock it before closing. */
1709       if (*share_locked && lp_share_modes(SNUM(cnum)))
1710         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
1711                             Files[fnum].fd_ptr->inode, token);
1712       close_file(fnum,False);   
1713       /* Share mode no longer locked. */
1714       *share_locked = False;
1715       errno = EACCES;
1716       unix_ERR_class = ERRDOS;
1717       unix_ERR_code = ERRlock;
1718     }
1719     else
1720       ftruncate(Files[fnum].fd_ptr->fd,0); 
1721   }
1722 }
1723
1724 /****************************************************************************
1725 check if we can open a file with a share mode
1726 ****************************************************************************/
1727 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1728                       BOOL fcbopen, int *flags)
1729 {
1730   int old_open_mode = share->share_mode &0xF;
1731   int old_deny_mode = (share->share_mode >>4)&7;
1732
1733   if (old_deny_mode > 4 || old_open_mode > 2)
1734   {
1735     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1736                deny_mode,old_deny_mode,old_open_mode,fname));
1737     return False;
1738   }
1739
1740   {
1741     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1742                                 share->pid,fname);
1743
1744     if ((access_allowed == AFAIL) ||
1745         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1746         (access_allowed == AREAD && *flags == O_WRONLY) ||
1747         (access_allowed == AWRITE && *flags == O_RDONLY))
1748     {
1749       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1750                 deny_mode,old_deny_mode,old_open_mode,
1751                 share->pid,fname, fcbopen, *flags, access_allowed));
1752       return False;
1753     }
1754
1755     if (access_allowed == AREAD)
1756       *flags = O_RDONLY;
1757
1758     if (access_allowed == AWRITE)
1759       *flags = O_WRONLY;
1760
1761   }
1762   return True;
1763 }
1764
1765 /****************************************************************************
1766 open a file with a share mode
1767 ****************************************************************************/
1768 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1769                       int mode,int oplock_request, int *Access,int *action)
1770 {
1771   files_struct *fs_p = &Files[fnum];
1772   int flags=0;
1773   int flags2=0;
1774   int deny_mode = (share_mode>>4)&7;
1775   struct stat sbuf;
1776   BOOL file_existed = file_exist(fname,&sbuf);
1777   BOOL share_locked = False;
1778   BOOL fcbopen = False;
1779   int token;
1780   uint32 dev = 0;
1781   uint32 inode = 0;
1782   int num_share_modes = 0;
1783
1784   fs_p->open = False;
1785   fs_p->fd_ptr = 0;
1786
1787   /* this is for OS/2 EAs - try and say we don't support them */
1788   if (strstr(fname,".+,;=[].")) 
1789   {
1790     unix_ERR_class = ERRDOS;
1791     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1792 #ifdef OS2_WPS_FIX
1793     unix_ERR_code = ERRcannotopen;
1794 #else /* OS2_WPS_FIX */
1795     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1796 #endif /* OS2_WPS_FIX */
1797
1798     return;
1799   }
1800
1801   if ((ofun & 0x3) == 0 && file_existed)  
1802   {
1803     errno = EEXIST;
1804     return;
1805   }
1806       
1807   if (ofun & 0x10)
1808     flags2 |= O_CREAT;
1809   if ((ofun & 0x3) == 2)
1810     flags2 |= O_TRUNC;
1811
1812   /* note that we ignore the append flag as 
1813      append does not mean the same thing under dos and unix */
1814
1815   switch (share_mode&0xF)
1816   {
1817     case 1: 
1818       flags = O_WRONLY; 
1819       break;
1820     case 0xF: 
1821       fcbopen = True;
1822       flags = O_RDWR; 
1823       break;
1824     case 2: 
1825       flags = O_RDWR; 
1826       break;
1827     default:
1828       flags = O_RDONLY;
1829       break;
1830   }
1831   
1832   if (flags != O_RDONLY && file_existed && 
1833       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
1834   {
1835     if (!fcbopen) 
1836     {
1837       errno = EACCES;
1838       return;
1839     }
1840     flags = O_RDONLY;
1841   }
1842
1843   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
1844   {
1845     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1846     errno = EINVAL;
1847     return;
1848   }
1849
1850   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1851
1852   if (lp_share_modes(SNUM(cnum))) 
1853   {
1854     int i;
1855     share_mode_entry *old_shares = 0;
1856
1857     if (file_existed)
1858     {
1859       dev = (uint32)sbuf.st_dev;
1860       inode = (uint32)sbuf.st_ino;
1861       lock_share_entry(cnum, dev, inode, &token);
1862       share_locked = True;
1863       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1864     }
1865
1866     /*
1867      * Check if the share modes will give us access.
1868      */
1869
1870     if(share_locked && (num_share_modes != 0))
1871     {
1872       BOOL broke_oplock;
1873
1874       do
1875       {
1876
1877         broke_oplock = False;
1878         for(i = 0; i < num_share_modes; i++)
1879         {
1880           share_mode_entry *share_entry = &old_shares[i];
1881
1882           /* 
1883            * By observation of NetBench, oplocks are broken *before* share
1884            * modes are checked. This allows a file to be closed by the client
1885            * if the share mode would deny access and the client has an oplock. 
1886            * Check if someone has an oplock on this file. If so we must break 
1887            * it before continuing. 
1888            */
1889           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1890           {
1891
1892             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1893 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1894
1895             /* Oplock break.... */
1896             unlock_share_entry(cnum, dev, inode, token);
1897             if(request_oplock_break(share_entry, dev, inode) == False)
1898             {
1899               free((char *)old_shares);
1900               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1901 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1902               errno = EACCES;
1903               unix_ERR_class = ERRDOS;
1904               unix_ERR_code = ERRbadshare;
1905               return;
1906             }
1907             lock_share_entry(cnum, dev, inode, &token);
1908             broke_oplock = True;
1909             break;
1910           }
1911
1912           /* someone else has a share lock on it, check to see 
1913              if we can too */
1914           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1915           {
1916             free((char *)old_shares);
1917             unlock_share_entry(cnum, dev, inode, token);
1918             errno = EACCES;
1919             unix_ERR_class = ERRDOS;
1920             unix_ERR_code = ERRbadshare;
1921             return;
1922           }
1923
1924         } /* end for */
1925
1926         if(broke_oplock)
1927         {
1928           free((char *)old_shares);
1929           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1930         }
1931       } while(broke_oplock);
1932     }
1933
1934     if(old_shares != 0)
1935       free((char *)old_shares);
1936   }
1937
1938   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1939            flags,flags2,mode));
1940
1941   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1942   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
1943   {
1944     flags = O_RDONLY;
1945     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1946   }
1947
1948   if (fs_p->open) 
1949   {
1950     int open_mode=0;
1951
1952     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1953     {
1954       /* We created the file - thus we must now lock the share entry before creating it. */
1955       dev = fs_p->fd_ptr->dev;
1956       inode = fs_p->fd_ptr->inode;
1957       lock_share_entry(cnum, dev, inode, &token);
1958       share_locked = True;
1959     }
1960
1961     switch (flags) 
1962     {
1963       case O_RDONLY:
1964         open_mode = 0;
1965         break;
1966       case O_RDWR:
1967         open_mode = 2;
1968         break;
1969       case O_WRONLY:
1970         open_mode = 1;
1971         break;
1972     }
1973
1974     fs_p->share_mode = (deny_mode<<4) | open_mode;
1975
1976     if (Access)
1977       (*Access) = open_mode;
1978
1979     if (action) 
1980     {
1981       if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1982       if (!file_existed) *action = 2;
1983       if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1984     }
1985     /* We must create the share mode entry before truncate as
1986        truncate can fail due to locking and have to close the
1987        file (which expects the share_mode_entry to be there).
1988      */
1989     if (lp_share_modes(SNUM(cnum)))
1990     {
1991       uint16 port = 0;
1992       /* JRA. Currently this only services Exlcusive and batch
1993          oplocks (no other opens on this file). This needs to
1994          be extended to level II oplocks (multiple reader
1995          oplocks). */
1996
1997       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
1998               !IS_VETO_OPLOCK_PATH(cnum,fname))
1999       {
2000         fs_p->granted_oplock = True;
2001         fs_p->sent_oplock_break = False;
2002         global_oplocks_open++;
2003         port = oplock_port;
2004
2005         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2006 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2007
2008       }
2009       else
2010       {
2011         port = 0;
2012         oplock_request = 0;
2013       }
2014       set_share_mode(token, fnum, port, oplock_request);
2015     }
2016
2017     if ((flags2&O_TRUNC) && file_existed)
2018       truncate_unless_locked(fnum,cnum,token,&share_locked);
2019   }
2020
2021   if (share_locked && lp_share_modes(SNUM(cnum)))
2022     unlock_share_entry( cnum, dev, inode, token);
2023 }
2024
2025 /****************************************************************************
2026 seek a file. Try to avoid the seek if possible
2027 ****************************************************************************/
2028 int seek_file(int fnum,uint32 pos)
2029 {
2030   uint32 offset = 0;
2031   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2032     offset = 3;
2033
2034   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
2035                                   - offset);
2036   return(Files[fnum].pos);
2037 }
2038
2039 /****************************************************************************
2040 read from a file
2041 ****************************************************************************/
2042 int read_file(int fnum,char *data,uint32 pos,int n)
2043 {
2044   int ret=0,readret;
2045
2046 #if USE_READ_PREDICTION
2047   if (!Files[fnum].can_write)
2048     {
2049       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2050
2051       data += ret;
2052       n -= ret;
2053       pos += ret;
2054     }
2055 #endif
2056
2057 #if USE_MMAP
2058   if (Files[fnum].mmap_ptr)
2059     {
2060       int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
2061       if (num > 0)
2062         {
2063           memcpy(data,Files[fnum].mmap_ptr+pos,num);
2064           data += num;
2065           pos += num;
2066           n -= num;
2067           ret += num;
2068         }
2069     }
2070 #endif
2071
2072   if (n <= 0)
2073     return(ret);
2074
2075   if (seek_file(fnum,pos) != pos)
2076     {
2077       DEBUG(3,("Failed to seek to %d\n",pos));
2078       return(ret);
2079     }
2080   
2081   if (n > 0) {
2082     readret = read(Files[fnum].fd_ptr->fd,data,n);
2083     if (readret > 0) ret += readret;
2084   }
2085
2086   return(ret);
2087 }
2088
2089
2090 /****************************************************************************
2091 write to a file
2092 ****************************************************************************/
2093 int write_file(int fnum,char *data,int n)
2094 {
2095   if (!Files[fnum].can_write) {
2096     errno = EPERM;
2097     return(0);
2098   }
2099
2100   if (!Files[fnum].modified) {
2101     struct stat st;
2102     Files[fnum].modified = True;
2103     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2104       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2105       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {  
2106         dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2107       }
2108     }  
2109   }
2110
2111   return(write_data(Files[fnum].fd_ptr->fd,data,n));
2112 }
2113
2114
2115 /****************************************************************************
2116 load parameters specific to a connection/service
2117 ****************************************************************************/
2118 BOOL become_service(int cnum,BOOL do_chdir)
2119 {
2120   extern char magic_char;
2121   static int last_cnum = -1;
2122   int snum;
2123
2124   if (!OPEN_CNUM(cnum))
2125     {
2126       last_cnum = -1;
2127       return(False);
2128     }
2129
2130   Connections[cnum].lastused = smb_last_time;
2131
2132   snum = SNUM(cnum);
2133   
2134   if (do_chdir &&
2135       ChDir(Connections[cnum].connectpath) != 0 &&
2136       ChDir(Connections[cnum].origpath) != 0)
2137     {
2138       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2139             Connections[cnum].connectpath,cnum));     
2140       return(False);
2141     }
2142
2143   if (cnum == last_cnum)
2144     return(True);
2145
2146   last_cnum = cnum;
2147
2148   case_default = lp_defaultcase(snum);
2149   case_preserve = lp_preservecase(snum);
2150   short_case_preserve = lp_shortpreservecase(snum);
2151   case_mangle = lp_casemangle(snum);
2152   case_sensitive = lp_casesensitive(snum);
2153   magic_char = lp_magicchar(snum);
2154   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2155   return(True);
2156 }
2157
2158
2159 /****************************************************************************
2160   find a service entry
2161 ****************************************************************************/
2162 int find_service(char *service)
2163 {
2164    int iService;
2165
2166    string_sub(service,"\\","/");
2167
2168    iService = lp_servicenumber(service);
2169
2170    /* now handle the special case of a home directory */
2171    if (iService < 0)
2172    {
2173       char *phome_dir = get_home_dir(service);
2174       DEBUG(3,("checking for home directory %s gave %s\n",service,
2175             phome_dir?phome_dir:"(NULL)"));
2176       if (phome_dir)
2177       {   
2178          int iHomeService;
2179          if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2180          {
2181             lp_add_home(service,iHomeService,phome_dir);
2182             iService = lp_servicenumber(service);
2183          }
2184       }
2185    }
2186
2187    /* If we still don't have a service, attempt to add it as a printer. */
2188    if (iService < 0)
2189    {
2190       int iPrinterService;
2191
2192       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2193       {
2194          char *pszTemp;
2195
2196          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2197          pszTemp = PRINTCAP;
2198          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2199          {
2200             DEBUG(3,("%s is a valid printer name\n", service));
2201             DEBUG(3,("adding %s as a printer service\n", service));
2202             lp_add_printer(service,iPrinterService);
2203             iService = lp_servicenumber(service);
2204             if (iService < 0)
2205                DEBUG(0,("failed to add %s as a printer service!\n", service));
2206          }
2207          else
2208             DEBUG(3,("%s is not a valid printer name\n", service));
2209       }
2210    }
2211
2212    /* just possibly it's a default service? */
2213    if (iService < 0) 
2214      {
2215        char *defservice = lp_defaultservice();
2216        if (defservice && *defservice && !strequal(defservice,service)) {
2217          iService = find_service(defservice);
2218          if (iService >= 0) {
2219            string_sub(service,"_","/");
2220            iService = lp_add_service(service,iService);
2221          }
2222        }
2223      }
2224
2225    if (iService >= 0)
2226       if (!VALID_SNUM(iService))
2227       {
2228          DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2229          iService = -1;
2230       }
2231
2232    if (iService < 0)
2233       DEBUG(3,("find_service() failed to find service %s\n", service));
2234
2235    return (iService);
2236 }
2237
2238
2239 /****************************************************************************
2240   create an error packet from a cached error.
2241 ****************************************************************************/
2242 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2243 {
2244   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2245
2246   int32 eclass = wbmpx->wr_errclass;
2247   int32 err = wbmpx->wr_error;
2248
2249   /* We can now delete the auxiliary struct */
2250   free((char *)wbmpx);
2251   Files[fnum].wbmpx_ptr = NULL;
2252   return error_packet(inbuf,outbuf,eclass,err,line);
2253 }
2254
2255
2256 struct
2257 {
2258   int unixerror;
2259   int smbclass;
2260   int smbcode;
2261 } unix_smb_errmap[] =
2262 {
2263   {EPERM,ERRDOS,ERRnoaccess},
2264   {EACCES,ERRDOS,ERRnoaccess},
2265   {ENOENT,ERRDOS,ERRbadfile},
2266   {ENOTDIR,ERRDOS,ERRbadpath},
2267   {EIO,ERRHRD,ERRgeneral},
2268   {EBADF,ERRSRV,ERRsrverror},
2269   {EINVAL,ERRSRV,ERRsrverror},
2270   {EEXIST,ERRDOS,ERRfilexists},
2271   {ENFILE,ERRDOS,ERRnofids},
2272   {EMFILE,ERRDOS,ERRnofids},
2273   {ENOSPC,ERRHRD,ERRdiskfull},
2274 #ifdef EDQUOT
2275   {EDQUOT,ERRHRD,ERRdiskfull},
2276 #endif
2277 #ifdef ENOTEMPTY
2278   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2279 #endif
2280 #ifdef EXDEV
2281   {EXDEV,ERRDOS,ERRdiffdevice},
2282 #endif
2283   {EROFS,ERRHRD,ERRnowrite},
2284   {0,0,0}
2285 };
2286
2287 /****************************************************************************
2288   create an error packet from errno
2289 ****************************************************************************/
2290 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2291 {
2292   int eclass=def_class;
2293   int ecode=def_code;
2294   int i=0;
2295
2296   if (unix_ERR_class != SUCCESS)
2297     {
2298       eclass = unix_ERR_class;
2299       ecode = unix_ERR_code;
2300       unix_ERR_class = SUCCESS;
2301       unix_ERR_code = 0;
2302     }
2303   else
2304     {
2305       while (unix_smb_errmap[i].smbclass != 0)
2306       {
2307             if (unix_smb_errmap[i].unixerror == errno)
2308             {
2309               eclass = unix_smb_errmap[i].smbclass;
2310               ecode = unix_smb_errmap[i].smbcode;
2311               break;
2312             }
2313           i++;
2314       }
2315     }
2316
2317   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2318 }
2319
2320
2321 /****************************************************************************
2322   create an error packet. Normally called using the ERROR() macro
2323 ****************************************************************************/
2324 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2325 {
2326   int outsize = set_message(outbuf,0,0,True);
2327   int cmd;
2328   cmd = CVAL(inbuf,smb_com);
2329   
2330   CVAL(outbuf,smb_rcls) = error_class;
2331   SSVAL(outbuf,smb_err,error_code);  
2332   
2333   DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2334            timestring(),
2335            line,
2336            (int)CVAL(inbuf,smb_com),
2337            smb_fn_name(CVAL(inbuf,smb_com)),
2338            error_class,
2339            error_code));
2340
2341   if (errno != 0)
2342     DEBUG(3,("error string = %s\n",strerror(errno)));
2343   
2344   return(outsize);
2345 }
2346
2347
2348 #ifndef SIGCLD_IGNORE
2349 /****************************************************************************
2350 this prevents zombie child processes
2351 ****************************************************************************/
2352 static int sig_cld()
2353 {
2354   static int depth = 0;
2355   if (depth != 0)
2356     {
2357       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2358       depth=0;
2359       return(0);
2360     }
2361   depth++;
2362
2363   BlockSignals(True,SIGCLD);
2364   DEBUG(5,("got SIGCLD\n"));
2365
2366 #ifdef USE_WAITPID
2367   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2368 #endif
2369
2370   /* Stop zombies */
2371   /* Stevens, Adv. Unix Prog. says that on system V you must call
2372      wait before reinstalling the signal handler, because the kernel
2373      calls the handler from within the signal-call when there is a
2374      child that has exited. This would lead to an infinite recursion
2375      if done vice versa. */
2376         
2377 #ifndef DONT_REINSTALL_SIG
2378 #ifdef SIGCLD_IGNORE
2379   signal(SIGCLD, SIG_IGN);  
2380 #else
2381   signal(SIGCLD, SIGNAL_CAST sig_cld);
2382 #endif
2383 #endif
2384
2385 #ifndef USE_WAITPID
2386   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2387 #endif
2388   depth--;
2389   BlockSignals(False,SIGCLD);
2390   return 0;
2391 }
2392 #endif
2393
2394 /****************************************************************************
2395   this is called when the client exits abruptly
2396   **************************************************************************/
2397 static int sig_pipe()
2398 {
2399         struct cli_state *cli;
2400         BlockSignals(True,SIGPIPE);
2401
2402         if ((cli = server_client()) && cli->initialised) {
2403                 DEBUG(3,("lost connection to password server\n"));
2404                 cli_shutdown(cli);
2405 #ifndef DONT_REINSTALL_SIG
2406                 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2407 #endif
2408                 BlockSignals(False,SIGPIPE);
2409                 return 0;
2410         }
2411
2412         exit_server("Got sigpipe\n");
2413         return(0);
2414 }
2415
2416 /****************************************************************************
2417   open the socket communication
2418 ****************************************************************************/
2419 static BOOL open_sockets(BOOL is_daemon,int port)
2420 {
2421   extern int Client;
2422
2423   if (is_daemon)
2424   {
2425     int num_interfaces = iface_count();
2426     int fd_listenset[FD_SETSIZE];
2427     fd_set listen_set;
2428     int s;
2429     int i;
2430
2431     /* Stop zombies */
2432 #ifdef SIGCLD_IGNORE
2433     signal(SIGCLD, SIG_IGN);
2434 #else
2435     signal(SIGCLD, SIGNAL_CAST sig_cld);
2436 #endif
2437
2438     if(atexit_set == 0)
2439       atexit(killkids);
2440
2441     FD_ZERO(&listen_set);
2442
2443     if(lp_interfaces() && lp_bind_interfaces_only())
2444     {
2445        /* We have been given an interfaces line, and been 
2446           told to only bind to those interfaces. Create a
2447           socket per interface and bind to only these.
2448         */
2449
2450       if(num_interfaces > FD_SETSIZE)
2451       {
2452         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2453 max can be %d\n", num_interfaces, FD_SETSIZE));
2454         return False;
2455       }
2456
2457       /* Now open a listen socket for each of the interfaces. */
2458       for(i = 0; i < num_interfaces; i++)
2459       {
2460         struct in_addr *ifip = iface_n_ip(i);
2461
2462         if(ifip == NULL)
2463         {
2464           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2465           continue;
2466         }
2467         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2468         if(s == -1)
2469           return False;
2470         /* ready to listen */
2471         if (listen(s, 5) == -1) 
2472         {
2473           DEBUG(0,("listen: %s\n",strerror(errno)));
2474           close(s);
2475           return False;
2476         }
2477         FD_SET(s,&listen_set);
2478       }
2479     }
2480     else
2481     {
2482       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2483       num_interfaces = 1;
2484
2485       /* open an incoming socket */
2486       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2487       if (s == -1)
2488         return(False);
2489
2490       /* ready to listen */
2491       if (listen(s, 5) == -1) 
2492       {
2493         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2494         close(s);
2495         return False;
2496       }
2497
2498       fd_listenset[0] = s;
2499       FD_SET(s,&listen_set);
2500     }      
2501
2502     /* now accept incoming connections - forking a new process
2503        for each incoming connection */
2504     DEBUG(2,("waiting for a connection\n"));
2505     while (1)
2506     {
2507       fd_set lfds;
2508       int num;
2509
2510       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2511
2512       num = sys_select(&lfds,NULL);
2513
2514       if (num == -1 && errno == EINTR)
2515         continue;
2516
2517       /* Find the sockets that are read-ready - accept on these. */
2518       for( ; num > 0; num--)
2519       {
2520         struct sockaddr addr;
2521         int in_addrlen = sizeof(addr);
2522
2523         s = -1;
2524         for(i = 0; i < num_interfaces; i++)
2525         {
2526           if(FD_ISSET(fd_listenset[i],&lfds))
2527           {
2528             s = fd_listenset[i];
2529             /* Clear this so we don't look at it again. */
2530             FD_CLR(fd_listenset[i],&lfds);
2531             break;
2532           }
2533         }
2534
2535         Client = accept(s,&addr,&in_addrlen);
2536
2537         if (Client == -1 && errno == EINTR)
2538           continue;
2539
2540         if (Client == -1)
2541         {
2542           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2543           continue;
2544         }
2545
2546 #ifdef NO_FORK_DEBUG
2547 #ifndef NO_SIGNAL_TEST
2548         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2549         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2550 #endif /* NO_SIGNAL_TEST */
2551         return True;
2552 #else /* NO_FORK_DEBUG */
2553         if (Client != -1 && fork()==0)
2554         {
2555           /* Child code ... */
2556
2557 #ifndef NO_SIGNAL_TEST
2558           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2559           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2560 #endif /* NO_SIGNAL_TEST */
2561           /* close the listening socket(s) */
2562           for(i = 0; i < num_interfaces; i++)
2563             close(fd_listenset[i]);
2564
2565           /* close our standard file descriptors */
2566           close_low_fds();
2567           am_parent = 0;
2568   
2569           set_socket_options(Client,"SO_KEEPALIVE");
2570           set_socket_options(Client,user_socket_options);
2571
2572           /* Reset global variables in util.c so that
2573              client substitutions will be done correctly
2574              in the process.
2575            */
2576           reset_globals_after_fork();
2577           return True; 
2578         }
2579         close(Client); /* The parent doesn't need this socket */
2580 #endif /* NO_FORK_DEBUG */
2581       } /* end for num */
2582     } /* end while 1 */
2583   } /* end if is_daemon */
2584   else
2585   {
2586     /* Started from inetd. fd 0 is the socket. */
2587     /* We will abort gracefully when the client or remote system 
2588        goes away */
2589 #ifndef NO_SIGNAL_TEST
2590     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2591 #endif
2592     Client = dup(0);
2593
2594     /* close our standard file descriptors */
2595     close_low_fds();
2596
2597     set_socket_options(Client,"SO_KEEPALIVE");
2598     set_socket_options(Client,user_socket_options);
2599   }
2600
2601   return True;
2602 }
2603
2604 /****************************************************************************
2605   process an smb from the client - split out from the process() code so
2606   it can be used by the oplock break code.
2607 ****************************************************************************/
2608
2609 static void process_smb(char *inbuf, char *outbuf)
2610 {
2611   extern int Client;
2612   static int trans_num;
2613   int msg_type = CVAL(inbuf,0);
2614   int32 len = smb_len(inbuf);
2615   int nread = len + 4;
2616
2617   if (trans_num == 0) {
2618           /* on the first packet, check the global hosts allow/ hosts
2619              deny parameters before doing any parsing of the packet
2620              passed to us by the client.  This prevents attacks on our
2621              parsing code from hosts not in the hosts allow list */
2622           if (!check_access(-1)) {
2623                   /* send a negative session response "not listining on calling
2624                    name" */
2625                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2626                   DEBUG(1,("%s Connection denied from %s\n",
2627                            timestring(),client_addr()));
2628                   send_smb(Client,(char *)buf);
2629                   exit_server("connection denied");
2630           }
2631   }
2632
2633   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2634   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2635
2636 #ifdef WITH_VTP
2637   if(trans_num == 1 && VT_Check(inbuf)) 
2638   {
2639     VT_Process();
2640     return;
2641   }
2642 #endif
2643
2644   if (msg_type == 0)
2645     show_msg(inbuf);
2646   else if(msg_type == 0x85)
2647     return; /* Keepalive packet. */
2648
2649   nread = construct_reply(inbuf,outbuf,nread,max_send);
2650       
2651   if(nread > 0) 
2652   {
2653     if (CVAL(outbuf,0) == 0)
2654       show_msg(outbuf);
2655         
2656     if (nread != smb_len(outbuf) + 4) 
2657     {
2658       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2659                  nread, smb_len(outbuf)));
2660     }
2661     else
2662       send_smb(Client,outbuf);
2663   }
2664   trans_num++;
2665 }
2666
2667 /****************************************************************************
2668   open the oplock IPC socket communication
2669 ****************************************************************************/
2670 static BOOL open_oplock_ipc()
2671 {
2672   struct sockaddr_in sock_name;
2673   int len = sizeof(sock_name);
2674
2675   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2676
2677   /* Open a lookback UDP socket on a random port. */
2678   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2679   if (oplock_sock == -1)
2680   {
2681     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2682 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2683     oplock_port = 0;
2684     return(False);
2685   }
2686
2687   /* Find out the transient UDP port we have been allocated. */
2688   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2689   {
2690     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2691             strerror(errno)));
2692     close(oplock_sock);
2693     oplock_sock = -1;
2694     oplock_port = 0;
2695     return False;
2696   }
2697   oplock_port = ntohs(sock_name.sin_port);
2698
2699   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2700             getpid(), oplock_port));
2701
2702   return True;
2703 }
2704
2705 /****************************************************************************
2706   process an oplock break message.
2707 ****************************************************************************/
2708 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2709 {
2710   int32 msg_len;
2711   uint16 from_port;
2712   char *msg_start;
2713
2714   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2715   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2716
2717   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2718
2719   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2720             msg_len, from_port));
2721
2722   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2723      only valid request. */
2724
2725   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2726   {
2727     case OPLOCK_BREAK_CMD:
2728       /* Ensure that the msg length is correct. */
2729       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2730       {
2731         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2732 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2733         return False;
2734       }
2735       {
2736         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2737         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2738         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2739         struct timeval tval;
2740         struct sockaddr_in toaddr;
2741
2742         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2743         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2744
2745         DEBUG(5,("process_local_message: oplock break request from \
2746 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2747
2748         /*
2749          * If we have no record of any currently open oplocks,
2750          * it's not an error, as a close command may have
2751          * just been issued on the file that was oplocked.
2752          * Just return success in this case.
2753          */
2754
2755         if(global_oplocks_open != 0)
2756         {
2757           if(oplock_break(dev, inode, &tval) == False)
2758           {
2759             DEBUG(0,("process_local_message: oplock break failed - \
2760 not returning udp message.\n"));
2761             return False;
2762           }
2763         }
2764         else
2765         {
2766           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2767 oplocks. Returning success.\n"));
2768         }
2769
2770         /* Send the message back after OR'ing in the 'REPLY' bit. */
2771         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2772   
2773         bzero((char *)&toaddr,sizeof(toaddr));
2774         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2775         toaddr.sin_port = htons(from_port);
2776         toaddr.sin_family = AF_INET;
2777
2778         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2779                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2780         {
2781           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2782                     remotepid, strerror(errno)));
2783           return False;
2784         }
2785
2786         DEBUG(5,("process_local_message: oplock break reply sent to \
2787 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2788                 from_port, dev, inode));
2789
2790       }
2791       break;
2792     /* 
2793      * Keep this as a debug case - eventually we can remove it.
2794      */
2795     case 0x8001:
2796       DEBUG(0,("process_local_message: Received unsolicited break \
2797 reply - dumping info.\n"));
2798
2799       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2800       {
2801         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2802 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2803         return False;
2804       }
2805
2806       {
2807         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2808         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2809         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2810
2811         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2812 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2813
2814        }
2815        return False;
2816
2817     default:
2818       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2819                 (unsigned int)SVAL(msg_start,0)));
2820       return False;
2821   }
2822   return True;
2823 }
2824
2825 /****************************************************************************
2826  Process an oplock break directly.
2827 ****************************************************************************/
2828 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2829 {
2830   extern int Client;
2831   char *inbuf = NULL;
2832   char *outbuf = NULL;
2833   files_struct *fsp = NULL;
2834   int fnum;
2835   time_t start_time;
2836   BOOL shutdown_server = False;
2837
2838   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2839 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2840
2841   /* We need to search the file open table for the
2842      entry containing this dev and inode, and ensure
2843      we have an oplock on it. */
2844   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2845   {
2846     if(OPEN_FNUM(fnum))
2847     {
2848       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2849          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
2850          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2851               fsp = &Files[fnum];
2852               break;
2853       }
2854     }
2855   }
2856
2857   if(fsp == NULL)
2858   {
2859     /* The file could have been closed in the meantime - return success. */
2860     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2861 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2862     return True;
2863   }
2864
2865   /* Ensure we have an oplock on the file */
2866
2867   /* There is a potential race condition in that an oplock could
2868      have been broken due to another udp request, and yet there are
2869      still oplock break messages being sent in the udp message
2870      queue for this file. So return true if we don't have an oplock,
2871      as we may have just freed it.
2872    */
2873
2874   if(!fsp->granted_oplock)
2875   {
2876     DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2877     return True;
2878   }
2879
2880   /* mark the oplock break as sent - we don't want to send twice! */
2881   if (fsp->sent_oplock_break)
2882   {
2883     DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
2884
2885     /* We have to fail the open here as we cannot send another oplock break on this
2886        file whilst we are awaiting a response from the client - neither can we
2887        allow another open to succeed while we are waiting for the client. */
2888     return False;
2889   }
2890
2891   /* Now comes the horrid part. We must send an oplock break to the client,
2892      and then process incoming messages until we get a close or oplock release.
2893      At this point we know we need a new inbuf/outbuf buffer pair.
2894      We cannot use these staticaly as we may recurse into here due to
2895      messages crossing on the wire.
2896    */
2897
2898   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2899   {
2900     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2901     return False;
2902   }
2903
2904   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2905   {
2906     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2907     free(inbuf);
2908     inbuf = NULL;
2909     return False;
2910   }
2911
2912   /* Prepare the SMBlockingX message. */
2913   bzero(outbuf,smb_size);
2914   set_message(outbuf,8,0,True);
2915
2916   SCVAL(outbuf,smb_com,SMBlockingX);
2917   SSVAL(outbuf,smb_tid,fsp->cnum);
2918   SSVAL(outbuf,smb_pid,0xFFFF);
2919   SSVAL(outbuf,smb_uid,0);
2920   SSVAL(outbuf,smb_mid,0xFFFF);
2921   SCVAL(outbuf,smb_vwv0,0xFF);
2922   SSVAL(outbuf,smb_vwv2,fnum);
2923   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2924   /* Change this when we have level II oplocks. */
2925   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2926  
2927   send_smb(Client, outbuf);
2928
2929   /* Remember we just sent an oplock break on this file. */
2930   fsp->sent_oplock_break = True;
2931
2932   /* We need this in case a readraw crosses on the wire. */
2933   global_oplock_break = True;
2934  
2935   /* Process incoming messages. */
2936
2937   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2938      seconds we should just die.... */
2939
2940   start_time = time(NULL);
2941
2942   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2943   {
2944     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2945     {
2946       /*
2947        * Die if we got an error.
2948        */
2949
2950       if (smb_read_error == READ_EOF)
2951         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2952  
2953       if (smb_read_error == READ_ERROR)
2954         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2955                   timestring(), strerror(errno)));
2956
2957       if (smb_read_error == READ_TIMEOUT)
2958         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2959                   timestring(), OPLOCK_BREAK_TIMEOUT));
2960
2961       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2962 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2963       shutdown_server = True;
2964       break;
2965     }
2966
2967     /*
2968      * There are certain SMB requests that we shouldn't allow
2969      * to recurse. opens, renames and deletes are the obvious
2970      * ones. This is handled in the switch_message() function.
2971      * If global_oplock_break is set they will push the packet onto
2972      * the pending smb queue and return -1 (no reply).
2973      * JRA.
2974      */
2975
2976     process_smb(inbuf, outbuf);
2977
2978     /*
2979      * Die if we go over the time limit.
2980      */
2981
2982     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2983     {
2984       DEBUG(0,("%s oplock_break: no break received from client within \
2985 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2986       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2987 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2988       shutdown_server = True;
2989       break;
2990     }
2991   }
2992
2993   /* Free the buffers we've been using to recurse. */
2994   free(inbuf);
2995   free(outbuf);
2996
2997   /* We need this in case a readraw crossed on the wire. */
2998   if(global_oplock_break)
2999     global_oplock_break = False;
3000
3001   /*
3002    * If the client did not respond we must die.
3003    */
3004
3005   if(shutdown_server)
3006   {
3007     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3008           timestring()));
3009     close_sockets();
3010     close(oplock_sock);
3011     exit_server("oplock break failure");
3012   }
3013
3014   if(OPEN_FNUM(fnum))
3015   {
3016     /* The lockingX reply will have removed the oplock flag 
3017        from the sharemode. */
3018     /* Paranoia.... */
3019     fsp->granted_oplock = False;
3020     fsp->sent_oplock_break = False;
3021     global_oplocks_open--;
3022   }
3023
3024   /* Santity check - remove this later. JRA */
3025   if(global_oplocks_open < 0)
3026   {
3027     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3028               global_oplocks_open));
3029     exit_server("oplock_break: global_oplocks_open < 0");
3030   }
3031
3032   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3033 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3034
3035   return True;
3036 }
3037
3038 /****************************************************************************
3039 Send an oplock break message to another smbd process. If the oplock is held 
3040 by the local smbd then call the oplock break function directly.
3041 ****************************************************************************/
3042
3043 BOOL request_oplock_break(share_mode_entry *share_entry, 
3044                           uint32 dev, uint32 inode)
3045 {
3046   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3047   struct sockaddr_in addr_out;
3048   int pid = getpid();
3049   time_t start_time;
3050   int time_left;
3051
3052   if(pid == share_entry->pid)
3053   {
3054     /* We are breaking our own oplock, make sure it's us. */
3055     if(share_entry->op_port != oplock_port)
3056     {
3057       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3058 should be %d\n", pid, share_entry->op_port, oplock_port));
3059       return False;
3060     }
3061
3062     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3063
3064     /* Call oplock break direct. */
3065     return oplock_break(dev, inode, &share_entry->time);
3066   }
3067
3068   /* We need to send a OPLOCK_BREAK_CMD message to the
3069      port in the share mode entry. */
3070
3071   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3072   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3073   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3074   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3075   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3076   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3077
3078   /* set the address and port */
3079   bzero((char *)&addr_out,sizeof(addr_out));
3080   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3081   addr_out.sin_port = htons( share_entry->op_port );
3082   addr_out.sin_family = AF_INET;
3083    
3084   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3085 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3086
3087   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3088          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3089   {
3090     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3091 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3092          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3093          strerror(errno)));
3094     return False;
3095   }
3096
3097   /*
3098    * Now we must await the oplock broken message coming back
3099    * from the target smbd process. Timeout if it fails to
3100    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3101    * While we get messages that aren't ours, loop.
3102    */
3103
3104   start_time = time(NULL);
3105   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3106
3107   while(time_left >= 0)
3108   {
3109     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3110     int32 reply_msg_len;
3111     uint16 reply_from_port;
3112     char *reply_msg_start;
3113
3114     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3115                time_left ? time_left * 1000 : 1) == False)
3116     {
3117       if(smb_read_error == READ_TIMEOUT)
3118       {
3119         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3120 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3121                            share_entry->op_port, dev, inode));
3122         /*
3123          * This is a hack to make handling of failing clients more robust.
3124          * If a oplock break response message is not received in the timeout
3125          * period we may assume that the smbd servicing that client holding
3126          * the oplock has died and the client changes were lost anyway, so
3127          * we should continue to try and open the file.
3128          */
3129         break;
3130       }
3131       else
3132         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3133 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3134                          share_entry->op_port, dev, inode, strerror(errno)));
3135       return False;
3136     }
3137
3138     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3139     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3140
3141     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3142
3143     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3144     {
3145       /* Ignore it. */
3146       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3147              timestring()));
3148       continue;
3149     }
3150
3151     /*
3152      * Test to see if this is the reply we are awaiting.
3153      */
3154
3155     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3156        (reply_from_port == share_entry->op_port) && 
3157        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3158                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3159                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3160     {
3161       /*
3162        * This is the reply we've been waiting for.
3163        */
3164       break;
3165     }
3166     else
3167     {
3168       /*
3169        * This is another message - probably a break request.
3170        * Process it to prevent potential deadlock.
3171        * Note that the code in switch_message() prevents
3172        * us from recursing into here as any SMB requests
3173        * we might process that would cause another oplock
3174        * break request to be made will be queued.
3175        * JRA.
3176        */
3177
3178       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3179     }
3180
3181     time_left -= (time(NULL) - start_time);
3182   }
3183
3184   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3185
3186   return True;
3187 }
3188
3189 /****************************************************************************
3190 Get the next SMB packet, doing the local message processing automatically.
3191 ****************************************************************************/
3192
3193 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3194 {
3195   BOOL got_smb = False;
3196   BOOL ret;
3197
3198   do
3199   {
3200     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3201                                  timeout,&got_smb);
3202
3203     if(ret && !got_smb)
3204     {
3205       /* Deal with oplock break requests from other smbd's. */
3206       process_local_message(oplock_sock, inbuf, bufsize);
3207       continue;
3208     }
3209
3210     if(ret && (CVAL(inbuf,0) == 0x85))
3211     {
3212       /* Keepalive packet. */
3213       got_smb = False;
3214     }
3215
3216   }
3217   while(ret && !got_smb);
3218
3219   return ret;
3220 }
3221
3222 /****************************************************************************
3223 check if a snum is in use
3224 ****************************************************************************/
3225 BOOL snum_used(int snum)
3226 {
3227   int i;
3228   for (i=0;i<MAX_CONNECTIONS;i++)
3229     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3230       return(True);
3231   return(False);
3232 }
3233
3234 /****************************************************************************
3235   reload the services file
3236   **************************************************************************/
3237 BOOL reload_services(BOOL test)
3238 {
3239   BOOL ret;
3240
3241   if (lp_loaded())
3242     {
3243       pstring fname;
3244       pstrcpy(fname,lp_configfile());
3245       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3246         {
3247           pstrcpy(servicesf,fname);
3248           test = False;
3249         }
3250     }
3251
3252   reopen_logs();
3253
3254   if (test && !lp_file_list_changed())
3255     return(True);
3256
3257   lp_killunused(snum_used);
3258
3259   ret = lp_load(servicesf,False);
3260
3261   /* perhaps the config filename is now set */
3262   if (!test)
3263     reload_services(True);
3264
3265   reopen_logs();
3266
3267   load_interfaces();
3268
3269   {
3270     extern int Client;
3271     if (Client != -1) {      
3272       set_socket_options(Client,"SO_KEEPALIVE");
3273       set_socket_options(Client,user_socket_options);
3274     }
3275   }
3276
3277   reset_mangled_stack( lp_mangledstack() );
3278
3279   /* this forces service parameters to be flushed */
3280   become_service(-1,True);
3281
3282   return(ret);
3283 }
3284
3285
3286
3287 /****************************************************************************
3288 this prevents zombie child processes
3289 ****************************************************************************/
3290 static int sig_hup()
3291 {
3292   BlockSignals(True,SIGHUP);
3293   DEBUG(0,("Got SIGHUP\n"));
3294   reload_services(False);
3295 #ifndef DONT_REINSTALL_SIG
3296   signal(SIGHUP,SIGNAL_CAST sig_hup);
3297 #endif
3298   BlockSignals(False,SIGHUP);
3299   return(0);
3300 }
3301
3302 /****************************************************************************
3303 Setup the groups a user belongs to.
3304 ****************************************************************************/
3305 int setup_groups(char *user, int uid, int gid, int *p_ngroups, 
3306                  int **p_igroups, gid_t **p_groups,
3307          int **p_attrs)
3308 {
3309   if (-1 == initgroups(user,gid))
3310     {
3311       if (getuid() == 0)
3312         {
3313           DEBUG(0,("Unable to initgroups!\n"));
3314           if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3315             DEBUG(0,("This is probably a problem with the account %s\n",user));
3316         }
3317     }
3318   else
3319     {
3320       int i,ngroups;
3321       int *igroups;
3322       int *attrs;
3323       gid_t grp = 0;
3324       ngroups = getgroups(0,&grp);
3325       if (ngroups <= 0)
3326         ngroups = 32;
3327       igroups = (int *)malloc(sizeof(int)*ngroups);
3328       attrs   = (int *)malloc(sizeof(int)*ngroups);
3329       for (i=0;i<ngroups;i++)
3330       {
3331         attrs  [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3332         igroups[i] = 0x42424242;
3333       }
3334       ngroups = getgroups(ngroups,(gid_t *)igroups);
3335
3336       if (igroups[0] == 0x42424242)
3337         ngroups = 0;
3338
3339       *p_ngroups = ngroups;
3340       *p_attrs   = attrs;
3341
3342       /* The following bit of code is very strange. It is due to the
3343          fact that some OSes use int* and some use gid_t* for
3344          getgroups, and some (like SunOS) use both, one in prototypes,
3345          and one in man pages and the actual code. Thus we detect it
3346          dynamically using some very ugly code */
3347       if (ngroups > 0)
3348         {
3349           /* does getgroups return ints or gid_t ?? */
3350           static BOOL groups_use_ints = True;
3351
3352           if (groups_use_ints && 
3353               ngroups == 1 && 
3354               SVAL(igroups,2) == 0x4242)
3355             groups_use_ints = False;
3356           
3357           for (i=0;groups_use_ints && i<ngroups;i++)
3358             if (igroups[i] == 0x42424242)
3359               groups_use_ints = False;
3360               
3361           if (groups_use_ints)
3362           {
3363               *p_igroups = igroups;
3364               *p_groups = (gid_t *)igroups;       
3365           }
3366           else
3367           {
3368               gid_t *groups = (gid_t *)igroups;
3369               igroups = (int *)malloc(sizeof(int)*ngroups);
3370               for (i=0;i<ngroups;i++)
3371           {
3372                 igroups[i] = groups[i];
3373           }
3374               *p_igroups = igroups;
3375               *p_groups = (gid_t *)groups;
3376             }
3377         }
3378       DEBUG(3,("%s is in %d groups\n",user,ngroups));
3379       for (i=0;i<ngroups;i++)
3380         DEBUG(3,("%d ",igroups[i]));
3381       DEBUG(3,("\n"));
3382     }
3383   return 0;
3384 }
3385
3386 /****************************************************************************
3387   make a connection to a service
3388 ****************************************************************************/
3389 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3390 {
3391   int cnum;
3392   int snum;
3393   struct passwd *pass = NULL;
3394   connection_struct *pcon;
3395   BOOL guest = False;
3396   BOOL force = False;
3397   static BOOL first_connection = True;
3398
3399   strlower(service);
3400
3401   snum = find_service(service);
3402   if (snum < 0)
3403     {
3404       if (strequal(service,"IPC$"))
3405         {         
3406           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3407           return(-3);
3408         }
3409
3410       DEBUG(0,("%s couldn't find service %s\n",timestring(),service));      
3411       return(-2);
3412     }
3413
3414   if (strequal(service,HOMES_NAME))
3415     {
3416       if (*user && Get_Pwnam(user,True))
3417         return(make_connection(user,user,password,pwlen,dev,vuid));
3418
3419       if (validated_username(vuid))
3420         {
3421           strcpy(user,validated_username(vuid));
3422           return(make_connection(user,user,password,pwlen,dev,vuid));
3423         }
3424     }
3425
3426   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3427     return(-4);
3428   }
3429
3430   /* you can only connect to the IPC$ service as an ipc device */
3431   if (strequal(service,"IPC$"))
3432     strcpy(dev,"IPC");
3433
3434   if (*dev == '?' || !*dev)
3435     {
3436       if (lp_print_ok(snum))
3437         strcpy(dev,"LPT1:");
3438       else
3439         strcpy(dev,"A:");
3440     }
3441
3442   /* if the request is as a printer and you can't print then refuse */
3443   strupper(dev);
3444   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3445     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3446     return(-6);
3447   }
3448
3449   /* lowercase the user name */
3450   strlower(user);
3451
3452   /* add it as a possible user name */
3453   add_session_user(service);
3454
3455   /* shall we let them in? */
3456   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3457     {
3458       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3459       return(-1);
3460     }
3461   
3462   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3463   if (cnum < 0)
3464     {
3465       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3466       return(-1);
3467     }
3468
3469   pcon = &Connections[cnum];
3470   bzero((char *)pcon,sizeof(*pcon));
3471
3472   /* find out some info about the user */
3473   pass = Get_Pwnam(user,True);
3474
3475   if (pass == NULL)
3476     {
3477       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3478       return(-7);
3479     }
3480
3481   pcon->read_only = lp_readonly(snum);
3482
3483   {
3484     pstring list;
3485     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3486     string_sub(list,"%S",service);
3487
3488     if (user_in_list(user,list))
3489       pcon->read_only = True;
3490
3491     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3492     string_sub(list,"%S",service);
3493
3494     if (user_in_list(user,list))
3495       pcon->read_only = False;    
3496   }
3497
3498   /* admin user check */
3499
3500   /* JRA - original code denied admin user if the share was
3501      marked read_only. Changed as I don't think this is needed,
3502      but old code left in case there is a problem here.
3503    */
3504   if (user_in_list(user,lp_admin_users(snum)) 
3505 #if 0
3506       && !pcon->read_only)
3507 #else
3508       )
3509 #endif
3510     {
3511       pcon->admin_user = True;
3512       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3513     }
3514   else
3515     pcon->admin_user = False;
3516     
3517   pcon->force_user = force;
3518   pcon->vuid = vuid;
3519   pcon->uid = pass->pw_uid;
3520   pcon->gid = pass->pw_gid;
3521   pcon->num_files_open = 0;
3522   pcon->lastused = time(NULL);
3523   pcon->service = snum;
3524   pcon->used = True;
3525   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3526   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3527   pcon->dirptr = NULL;
3528   pcon->veto_list = NULL;
3529   pcon->hide_list = NULL;
3530   pcon->veto_oplock_list = NULL;
3531   string_set(&pcon->dirpath,"");
3532   string_set(&pcon->user,user);
3533
3534 #if HAVE_GETGRNAM 
3535   if (*lp_force_group(snum))
3536     {
3537       struct group *gptr;
3538       pstring gname;
3539
3540       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3541       /* default service may be a group name            */
3542       string_sub(gname,"%S",service);
3543       gptr = (struct group *)getgrnam(gname);
3544
3545       if (gptr)
3546         {
3547           pcon->gid = gptr->gr_gid;
3548           DEBUG(3,("Forced group %s\n",gname));
3549         }
3550       else
3551         DEBUG(1,("Couldn't find group %s\n",gname));
3552     }
3553 #endif
3554
3555   if (*lp_force_user(snum))
3556     {
3557       struct passwd *pass2;
3558       fstring fuser;
3559       fstrcpy(fuser,lp_force_user(snum));
3560       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3561       if (pass2)
3562         {
3563           pcon->uid = pass2->pw_uid;
3564           string_set(&pcon->user,fuser);
3565           fstrcpy(user,fuser);
3566           pcon->force_user = True;
3567           DEBUG(3,("Forced user %s\n",fuser));    
3568         }
3569       else
3570         DEBUG(1,("Couldn't find user %s\n",fuser));
3571     }
3572
3573   {
3574     pstring s;
3575     pstrcpy(s,lp_pathname(snum));
3576     standard_sub(cnum,s);
3577     string_set(&pcon->connectpath,s);
3578     DEBUG(3,("Connect path is %s\n",s));
3579   }
3580
3581   /* groups stuff added by ih */
3582   pcon->ngroups = 0;
3583   pcon->igroups = NULL;
3584   pcon->groups = NULL;
3585   pcon->attrs = NULL;
3586
3587   if (!IS_IPC(cnum))
3588     {
3589       /* Find all the groups this uid is in and store them. Used by become_user() */
3590       setup_groups(pcon->user,pcon->uid,pcon->gid,
3591                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3592       
3593       /* check number of connections */
3594       if (!claim_connection(cnum,
3595                             lp_servicename(SNUM(cnum)),
3596                             lp_max_connections(SNUM(cnum)),False))
3597         {
3598           DEBUG(1,("too many connections - rejected\n"));
3599           return(-8);
3600         }  
3601
3602       if (lp_status(SNUM(cnum)))
3603         claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3604
3605       first_connection = False;
3606     } /* IS_IPC */
3607
3608   pcon->open = True;
3609
3610   /* execute any "root preexec = " line */
3611   if (*lp_rootpreexec(SNUM(cnum)))
3612     {
3613       pstring cmd;
3614       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3615       standard_sub(cnum,cmd);
3616       DEBUG(5,("cmd=%s\n",cmd));
3617       smbrun(cmd,NULL,False);
3618     }
3619
3620   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3621     {
3622       DEBUG(0,("Can't become connected user!\n"));
3623       pcon->open = False;
3624       if (!IS_IPC(cnum)) {
3625         yield_connection(cnum,
3626                          lp_servicename(SNUM(cnum)),
3627                          lp_max_connections(SNUM(cnum)));
3628         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3629       }
3630       return(-1);
3631     }
3632
3633   if (ChDir(pcon->connectpath) != 0)
3634     {
3635       DEBUG(0,("Can't change directory to %s (%s)\n",
3636                pcon->connectpath,strerror(errno)));
3637       pcon->open = False;
3638       unbecome_user();
3639       if (!IS_IPC(cnum)) {
3640         yield_connection(cnum,
3641                          lp_servicename(SNUM(cnum)),
3642                          lp_max_connections(SNUM(cnum)));
3643         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3644       }
3645       return(-5);      
3646     }
3647
3648   string_set(&pcon->origpath,pcon->connectpath);
3649
3650 #if SOFTLINK_OPTIMISATION
3651   /* resolve any soft links early */
3652   {
3653     pstring s;
3654     pstrcpy(s,pcon->connectpath);
3655     GetWd(s);
3656     string_set(&pcon->connectpath,s);
3657     ChDir(pcon->connectpath);
3658   }
3659 #endif
3660
3661   num_connections_open++;
3662   add_session_user(user);
3663   
3664   /* execute any "preexec = " line */
3665   if (*lp_preexec(SNUM(cnum)))
3666     {
3667       pstring cmd;
3668       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3669       standard_sub(cnum,cmd);
3670       smbrun(cmd,NULL,False);
3671     }
3672   
3673   /* we've finished with the sensitive stuff */
3674   unbecome_user();
3675
3676   /* Add veto/hide lists */
3677   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3678   {
3679     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3680     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3681     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3682   }
3683
3684   {
3685     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3686                             timestring(),
3687                             remote_machine,
3688                             client_addr(),
3689                             lp_servicename(SNUM(cnum)),user,
3690                             pcon->uid,
3691                             pcon->gid,
3692                             (int)getpid()));
3693   }
3694
3695   return(cnum);
3696 }
3697
3698 /****************************************************************************
3699   Attempt to break an oplock on a file (if oplocked).
3700   Returns True if the file was closed as a result of
3701   the oplock break, False otherwise.
3702   Used as a last ditch attempt to free a space in the 
3703   file table when we have run out.
3704 ****************************************************************************/
3705
3706 static BOOL attempt_close_oplocked_file(files_struct *fp)
3707 {
3708
3709   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3710
3711   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3712
3713     /* Try and break the oplock. */
3714     file_fd_struct *fsp = fp->fd_ptr;
3715     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3716       if(!fp->open) /* Did the oplock break close the file ? */
3717         return True;
3718     }
3719   }
3720
3721   return False;
3722 }
3723
3724 /****************************************************************************
3725   find first available file slot
3726 ****************************************************************************/
3727 int find_free_file(void )
3728 {
3729         int i;
3730         static int first_file;
3731
3732         /* we want to give out file handles differently on each new
3733            connection because of a common bug in MS clients where they try to
3734            reuse a file descriptor from an earlier smb connection. This code
3735            increases the chance that the errant client will get an error rather
3736            than causing corruption */
3737         if (first_file == 0) {
3738                 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3739                 if (first_file == 0) first_file = 1;
3740         }
3741
3742         if (first_file >= MAX_OPEN_FILES)
3743                 first_file = 1;
3744
3745         for (i=first_file;i<MAX_OPEN_FILES;i++)
3746                 if (!Files[i].open && !Files[i].reserved) {
3747                         memset(&Files[i], 0, sizeof(Files[i]));
3748                         first_file = i+1;
3749                         Files[i].reserved = True;
3750                         return(i);
3751                 }
3752
3753         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3754         for (i=1;i<first_file;i++)
3755                 if (!Files[i].open && !Files[i].reserved) {
3756                         memset(&Files[i], 0, sizeof(Files[i]));
3757                         first_file = i+1;
3758                         Files[i].reserved = True;
3759                         return(i);
3760                 }
3761
3762         /* 
3763          * Before we give up, go through the open files 
3764          * and see if there are any files opened with a
3765          * batch oplock. If so break the oplock and then
3766          * re-use that entry (if it becomes closed).
3767          * This may help as NT/95 clients tend to keep
3768          * files batch oplocked for quite a long time
3769          * after they have finished with them.
3770          */
3771         for (i=first_file;i<MAX_OPEN_FILES;i++) {
3772           if(attempt_close_oplocked_file( &Files[i])) {
3773             memset(&Files[i], 0, sizeof(Files[i]));
3774             first_file = i+1;
3775             Files[i].reserved = True;
3776             return(i);
3777           }
3778         }
3779
3780         for (i=1;i<MAX_OPEN_FILES;i++) {
3781           if(attempt_close_oplocked_file( &Files[i])) {
3782             memset(&Files[i], 0, sizeof(Files[i]));
3783             first_file = i+1;
3784             Files[i].reserved = True;
3785             return(i);
3786           }
3787         }
3788
3789         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3790         return(-1);
3791 }
3792
3793 /****************************************************************************
3794   find first available connection slot, starting from a random position.
3795 The randomisation stops problems with the server dieing and clients
3796 thinking the server is still available.
3797 ****************************************************************************/
3798 static int find_free_connection(int hash )
3799 {
3800   int i;
3801   BOOL used=False;
3802   hash = (hash % (MAX_CONNECTIONS-2))+1;
3803
3804  again:
3805
3806   for (i=hash+1;i!=hash;)
3807     {
3808       if (!Connections[i].open && Connections[i].used == used) 
3809         {
3810           DEBUG(3,("found free connection number %d\n",i));
3811           return(i);
3812         }
3813       i++;
3814       if (i == MAX_CONNECTIONS)
3815         i = 1;
3816     }
3817
3818   if (!used)
3819     {
3820       used = !used;
3821       goto again;
3822     }
3823
3824   DEBUG(1,("ERROR! Out of connection structures\n"));
3825   return(-1);
3826 }
3827
3828
3829 /****************************************************************************
3830 reply for the core protocol
3831 ****************************************************************************/
3832 int reply_corep(char *outbuf)
3833 {
3834   int outsize = set_message(outbuf,1,0,True);
3835
3836   Protocol = PROTOCOL_CORE;
3837
3838   return outsize;
3839 }
3840
3841
3842 /****************************************************************************
3843 reply for the coreplus protocol
3844 ****************************************************************************/
3845 int reply_coreplus(char *outbuf)
3846 {
3847   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3848   int outsize = set_message(outbuf,13,0,True);
3849   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3850                                  readbraw and writebraw (possibly) */
3851   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3852   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3853
3854   Protocol = PROTOCOL_COREPLUS;
3855
3856   return outsize;
3857 }
3858
3859
3860 /****************************************************************************
3861 reply for the lanman 1.0 protocol
3862 ****************************************************************************/
3863 int reply_lanman1(char *outbuf)
3864 {
3865   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3866   int secword=0;
3867   BOOL doencrypt = SMBENCRYPT();
3868   time_t t = time(NULL);
3869
3870   if (lp_security()>=SEC_USER) secword |= 1;
3871   if (doencrypt) secword |= 2;
3872
3873   set_message(outbuf,13,doencrypt?8:0,True);
3874   SSVAL(outbuf,smb_vwv1,secword); 
3875   /* Create a token value and add it to the outgoing packet. */
3876   if (doencrypt) 
3877     generate_next_challenge(smb_buf(outbuf));
3878
3879   Protocol = PROTOCOL_LANMAN1;
3880
3881   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3882   SSVAL(outbuf,smb_vwv2,max_recv);
3883   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3884   SSVAL(outbuf,smb_vwv4,1);
3885   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3886                                  readbraw writebraw (possibly) */
3887   SIVAL(outbuf,smb_vwv6,getpid());
3888   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3889
3890   put_dos_date(outbuf,smb_vwv8,t);
3891
3892   return (smb_len(outbuf)+4);
3893 }
3894
3895
3896 /****************************************************************************
3897 reply for the lanman 2.0 protocol
3898 ****************************************************************************/
3899 int reply_lanman2(char *outbuf)
3900 {
3901   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3902   int secword=0;
3903   BOOL doencrypt = SMBENCRYPT();
3904   time_t t = time(NULL);
3905   struct cli_state *cli = NULL;
3906   char cryptkey[8];
3907   char crypt_len = 0;
3908
3909   if (lp_security() == SEC_SERVER) {
3910           cli = server_cryptkey();
3911   }
3912
3913   if (cli) {
3914           DEBUG(3,("using password server validation\n"));
3915           doencrypt = ((cli->sec_mode & 2) != 0);
3916   }
3917
3918   if (lp_security()>=SEC_USER) secword |= 1;
3919   if (doencrypt) secword |= 2;
3920
3921   if (doencrypt) {
3922           crypt_len = 8;
3923           if (!cli) {
3924                   generate_next_challenge(cryptkey);
3925           } else {
3926                   memcpy(cryptkey, cli->cryptkey, 8);
3927                   set_challenge(cli->cryptkey);
3928           }
3929   }
3930
3931   set_message(outbuf,13,crypt_len,True);
3932   SSVAL(outbuf,smb_vwv1,secword); 
3933   SIVAL(outbuf,smb_vwv6,getpid());
3934   if (doencrypt) 
3935           memcpy(smb_buf(outbuf), cryptkey, 8);
3936
3937   Protocol = PROTOCOL_LANMAN2;
3938
3939   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3940   SSVAL(outbuf,smb_vwv2,max_recv);
3941   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3942   SSVAL(outbuf,smb_vwv4,1);
3943   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3944   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3945   put_dos_date(outbuf,smb_vwv8,t);
3946
3947   return (smb_len(outbuf)+4);
3948 }
3949
3950
3951 /****************************************************************************
3952 reply for the nt protocol
3953 ****************************************************************************/
3954 int reply_nt1(char *outbuf)
3955 {
3956   /* dual names + lock_and_read + nt SMBs + remote API calls */
3957   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3958 /*
3959   other valid capabilities which we may support at some time...
3960                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3961                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3962  */
3963
3964   int secword=0;
3965   BOOL doencrypt = SMBENCRYPT();
3966   time_t t = time(NULL);
3967   int data_len;
3968   struct cli_state *cli = NULL;
3969   char cryptkey[8];
3970   char crypt_len = 0;
3971
3972   if (lp_security() == SEC_SERVER) {
3973           cli = server_cryptkey();
3974   }
3975
3976   if (cli) {
3977           DEBUG(3,("using password server validation\n"));
3978           doencrypt = ((cli->sec_mode & 2) != 0);
3979   }
3980
3981   if (doencrypt) {
3982           crypt_len = 8;
3983           if (!cli) {
3984                   generate_next_challenge(cryptkey);
3985           } else {
3986                   memcpy(cryptkey, cli->cryptkey, 8);
3987                   set_challenge(cli->cryptkey);
3988           }
3989   }
3990
3991   if (lp_readraw() && lp_writeraw()) {
3992           capabilities |= CAP_RAW_MODE;
3993   }
3994
3995   if (lp_security() >= SEC_USER) secword |= 1;
3996   if (doencrypt) secword |= 2;
3997
3998   /* decide where (if) to put the encryption challenge, and
3999      follow it with the OEM'd domain name
4000    */
4001   data_len = crypt_len + strlen(myworkgroup) + 1;
4002
4003   set_message(outbuf,17,data_len,True);
4004   strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
4005
4006   CVAL(outbuf,smb_vwv1) = secword;
4007   SSVALS(outbuf,smb_vwv16+1,crypt_len);
4008   if (doencrypt) 
4009           memcpy(smb_buf(outbuf), cryptkey, 8);
4010
4011   Protocol = PROTOCOL_NT1;
4012
4013   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4014   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4015   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4016   SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
4017   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4018   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4019   put_long_date(outbuf+smb_vwv11+1,t);
4020   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4021   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4022
4023   return (smb_len(outbuf)+4);
4024 }
4025
4026 /* these are the protocol lists used for auto architecture detection:
4027
4028 WinNT 3.51:
4029 protocol [PC NETWORK PROGRAM 1.0]
4030 protocol [XENIX CORE]
4031 protocol [MICROSOFT NETWORKS 1.03]
4032 protocol [LANMAN1.0]
4033 protocol [Windows for Workgroups 3.1a]
4034 protocol [LM1.2X002]
4035 protocol [LANMAN2.1]
4036 protocol [NT LM 0.12]
4037
4038 Win95:
4039 protocol [PC NETWORK PROGRAM 1.0]
4040 protocol [XENIX CORE]
4041 protocol [MICROSOFT NETWORKS 1.03]
4042 protocol [LANMAN1.0]
4043 protocol [Windows for Workgroups 3.1a]
4044 protocol [LM1.2X002]
4045 protocol [LANMAN2.1]
4046 protocol [NT LM 0.12]
4047
4048 OS/2:
4049 protocol [PC NETWORK PROGRAM 1.0]
4050 protocol [XENIX CORE]
4051 protocol [LANMAN1.0]
4052 protocol [LM1.2X002]
4053 protocol [LANMAN2.1]
4054 */
4055
4056 /*
4057   * Modified to recognize the architecture of the remote machine better.
4058   *
4059   * This appears to be the matrix of which protocol is used by which
4060   * MS product.
4061        Protocol                       WfWg    Win95   WinNT  OS/2
4062        PC NETWORK PROGRAM 1.0          1       1       1      1
4063        XENIX CORE                                      2      2
4064        MICROSOFT NETWORKS 3.0          2       2       
4065        DOS LM1.2X002                   3       3       
4066        MICROSOFT NETWORKS 1.03                         3
4067        DOS LANMAN2.1                   4       4       
4068        LANMAN1.0                                       4      3
4069        Windows for Workgroups 3.1a     5       5       5
4070        LM1.2X002                                       6      4
4071        LANMAN2.1                                       7      5
4072        NT LM 0.12                              6       8
4073   *
4074   *  tim@fsg.com 09/29/95
4075   */
4076   
4077 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4078 #define ARCH_WIN95    0x2
4079 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4080 #define ARCH_WINNT    0x8
4081 #define ARCH_SAMBA    0x10
4082  
4083 #define ARCH_ALL      0x1F
4084  
4085 /* List of supported protocols, most desired first */
4086 struct {
4087   char *proto_name;
4088   char *short_name;
4089   int (*proto_reply_fn)(char *);
4090   int protocol_level;
4091 } supported_protocols[] = {
4092   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4093   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4094   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4095   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4096   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4097   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4098   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4099   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4100   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4101   {NULL,NULL},
4102 };
4103
4104
4105 /****************************************************************************
4106   reply to a negprot
4107 ****************************************************************************/
4108 static int reply_negprot(char *inbuf,char *outbuf)
4109 {
4110   int outsize = set_message(outbuf,1,0,True);
4111   int Index=0;
4112   int choice= -1;
4113   int protocol;
4114   char *p;
4115   int bcc = SVAL(smb_buf(inbuf),-2);
4116   int arch = ARCH_ALL;
4117
4118   p = smb_buf(inbuf)+1;
4119   while (p < (smb_buf(inbuf) + bcc))
4120     { 
4121       Index++;
4122       DEBUG(3,("Requested protocol [%s]\n",p));
4123       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4124         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4125       else if (strcsequal(p,"DOS LM1.2X002"))
4126         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4127       else if (strcsequal(p,"DOS LANMAN2.1"))
4128         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4129       else if (strcsequal(p,"NT LM 0.12"))
4130         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4131       else if (strcsequal(p,"LANMAN2.1"))
4132         arch &= ( ARCH_WINNT | ARCH_OS2 );
4133       else if (strcsequal(p,"LM1.2X002"))
4134         arch &= ( ARCH_WINNT | ARCH_OS2 );
4135       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4136         arch &= ARCH_WINNT;
4137       else if (strcsequal(p,"XENIX CORE"))
4138         arch &= ( ARCH_WINNT | ARCH_OS2 );
4139       else if (strcsequal(p,"Samba")) {
4140         arch = ARCH_SAMBA;
4141         break;
4142       }
4143  
4144       p += strlen(p) + 2;
4145     }
4146     
4147   switch ( arch ) {
4148   case ARCH_SAMBA:
4149     set_remote_arch(RA_SAMBA);
4150     break;
4151   case ARCH_WFWG:
4152     set_remote_arch(RA_WFWG);
4153     break;
4154   case ARCH_WIN95:
4155     set_remote_arch(RA_WIN95);
4156     break;
4157   case ARCH_WINNT:
4158     set_remote_arch(RA_WINNT);
4159     break;
4160   case ARCH_OS2:
4161     set_remote_arch(RA_OS2);
4162     break;
4163   default:
4164     set_remote_arch(RA_UNKNOWN);
4165     break;
4166   }
4167  
4168   /* possibly reload - change of architecture */
4169   reload_services(True);      
4170     
4171   /* a special case to stop password server loops */
4172   if (Index == 1 && strequal(remote_machine,myhostname) && 
4173       lp_security()==SEC_SERVER)
4174     exit_server("Password server loop!");
4175   
4176   /* Check for protocols, most desirable first */
4177   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4178     {
4179       p = smb_buf(inbuf)+1;
4180       Index = 0;
4181       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4182         while (p < (smb_buf(inbuf) + bcc))
4183           { 
4184             if (strequal(p,supported_protocols[protocol].proto_name))
4185               choice = Index;
4186             Index++;
4187             p += strlen(p) + 2;
4188           }
4189       if(choice != -1)
4190         break;
4191     }
4192   
4193   SSVAL(outbuf,smb_vwv0,choice);
4194   if(choice != -1) {
4195     extern fstring remote_proto;
4196     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4197     reload_services(True);          
4198     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4199     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4200   }
4201   else {
4202     DEBUG(0,("No protocol supported !\n"));
4203   }
4204   SSVAL(outbuf,smb_vwv0,choice);
4205   
4206   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4207
4208   return(outsize);
4209 }
4210
4211
4212 /****************************************************************************
4213 close all open files for a connection
4214 ****************************************************************************/
4215 static void close_open_files(int cnum)
4216 {
4217   int i;
4218   for (i=0;i<MAX_OPEN_FILES;i++)
4219     if( Files[i].cnum == cnum && Files[i].open) {
4220       close_file(i,False);
4221     }
4222 }
4223
4224
4225
4226 /****************************************************************************
4227 close a cnum
4228 ****************************************************************************/
4229 void close_cnum(int cnum, uint16 vuid)
4230 {
4231   DirCacheFlush(SNUM(cnum));
4232
4233   unbecome_user();
4234
4235   if (!OPEN_CNUM(cnum))
4236     {
4237       DEBUG(0,("Can't close cnum %d\n",cnum));
4238       return;
4239     }
4240
4241   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4242                           timestring(),
4243                           remote_machine,client_addr(),
4244                           lp_servicename(SNUM(cnum))));
4245
4246   yield_connection(cnum,
4247                    lp_servicename(SNUM(cnum)),
4248                    lp_max_connections(SNUM(cnum)));
4249
4250   if (lp_status(SNUM(cnum)))
4251     yield_connection(cnum,"STATUS.",MAXSTATUS);
4252
4253   close_open_files(cnum);
4254   dptr_closecnum(cnum);
4255
4256   /* execute any "postexec = " line */
4257   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4258     {
4259       pstring cmd;
4260       strcpy(cmd,lp_postexec(SNUM(cnum)));
4261       standard_sub(cnum,cmd);
4262       smbrun(cmd,NULL,False);
4263       unbecome_user();
4264     }
4265
4266   unbecome_user();
4267   /* execute any "root postexec = " line */
4268   if (*lp_rootpostexec(SNUM(cnum)))
4269     {
4270       pstring cmd;
4271       strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4272       standard_sub(cnum,cmd);
4273       smbrun(cmd,NULL,False);
4274     }
4275
4276   Connections[cnum].open = False;
4277   num_connections_open--;
4278   if (Connections[cnum].ngroups && Connections[cnum].groups)
4279     {
4280       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4281         free(Connections[cnum].groups);
4282       free(Connections[cnum].igroups);
4283       Connections[cnum].groups = NULL;
4284       Connections[cnum].igroups = NULL;
4285       Connections[cnum].ngroups = 0;
4286     }
4287
4288   free_namearray(Connections[cnum].veto_list);
4289   free_namearray(Connections[cnum].hide_list);
4290   free_namearray(Connections[cnum].veto_oplock_list);
4291
4292   string_set(&Connections[cnum].user,"");
4293   string_set(&Connections[cnum].dirpath,"");
4294   string_set(&Connections[cnum].connectpath,"");
4295 }
4296
4297
4298 /****************************************************************************
4299 simple routines to do connection counting
4300 ****************************************************************************/
4301 BOOL yield_connection(int cnum,char *name,int max_connections)
4302 {
4303   struct connect_record crec;
4304   pstring fname;
4305   FILE *f;
4306   int mypid = getpid();
4307   int i;
4308
4309   DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4310
4311   if (max_connections <= 0)
4312     return(True);
4313
4314   bzero(&crec,sizeof(crec));
4315
4316   pstrcpy(fname,lp_lockdir());
4317   standard_sub(cnum,fname);
4318   trim_string(fname,"","/");
4319
4320   strcat(fname,"/");
4321   strcat(fname,name);
4322   strcat(fname,".LCK");
4323
4324   f = fopen(fname,"r+");
4325   if (!f)
4326     {
4327       DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4328       return(False);
4329     }
4330
4331   fseek(f,0,SEEK_SET);
4332
4333   /* find a free spot */
4334   for (i=0;i<max_connections;i++)
4335     {
4336       if (fread(&crec,sizeof(crec),1,f) != 1)
4337         {
4338           DEBUG(2,("Entry not found in lock file %s\n",fname));
4339           fclose(f);
4340           return(False);
4341         }
4342       if (crec.pid == mypid && crec.cnum == cnum)
4343         break;
4344     }
4345
4346   if (crec.pid != mypid || crec.cnum != cnum)
4347     {
4348       fclose(f);
4349       DEBUG(2,("Entry not found in lock file %s\n",fname));
4350       return(False);
4351     }
4352
4353   bzero((void *)&crec,sizeof(crec));
4354   
4355   /* remove our mark */
4356   if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4357       fwrite(&crec,sizeof(crec),1,f) != 1)
4358     {
4359       DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4360       fclose(f);
4361       return(False);
4362     }
4363
4364   DEBUG(3,("Yield successful\n"));
4365
4366   fclose(f);
4367   return(True);
4368 }
4369
4370
4371 /****************************************************************************
4372 simple routines to do connection counting
4373 ****************************************************************************/
4374 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4375 {
4376   struct connect_record crec;
4377   pstring fname;
4378   FILE *f;
4379   int snum = SNUM(cnum);
4380   int i,foundi= -1;
4381   int total_recs;
4382
4383   if (max_connections <= 0)
4384     return(True);
4385
4386   DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4387
4388   pstrcpy(fname,lp_lockdir());
4389   standard_sub(cnum,fname);
4390   trim_string(fname,"","/");
4391
4392   if (!directory_exist(fname,NULL))
4393     mkdir(fname,0755);
4394
4395   strcat(fname,"/");
4396   strcat(fname,name);
4397   strcat(fname,".LCK");
4398
4399   if (!file_exist(fname,NULL))
4400     {
4401       int oldmask = umask(022);
4402       f = fopen(fname,"w");
4403       if (f) fclose(f);
4404       umask(oldmask);
4405     }
4406
4407   total_recs = file_size(fname) / sizeof(crec);
4408
4409   f = fopen(fname,"r+");
4410
4411   if (!f)
4412     {
4413       DEBUG(1,("couldn't open lock file %s\n",fname));
4414       return(False);
4415     }
4416
4417   /* find a free spot */
4418   for (i=0;i<max_connections;i++)
4419     {
4420
4421       if (i>=total_recs || 
4422           fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4423           fread(&crec,sizeof(crec),1,f) != 1)
4424         {
4425           if (foundi < 0) foundi = i;
4426           break;
4427         }
4428
4429       if (Clear && crec.pid && !process_exists(crec.pid))
4430         {
4431           fseek(f,i*sizeof(crec),SEEK_SET);
4432           bzero((void *)&crec,sizeof(crec));
4433           fwrite(&crec,sizeof(crec),1,f);
4434           if (foundi < 0) foundi = i;
4435           continue;
4436         }
4437       if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4438         {
4439           foundi=i;
4440           if (!Clear) break;
4441         }
4442     }  
4443
4444   if (foundi < 0)
4445     {
4446       DEBUG(3,("no free locks in %s\n",fname));
4447       fclose(f);
4448       return(False);
4449     }      
4450
4451   /* fill in the crec */
4452   bzero((void *)&crec,sizeof(crec));
4453   crec.magic = 0x280267;
4454   crec.pid = getpid();
4455   crec.cnum = cnum;
4456   crec.uid = Connections[cnum].uid;
4457   crec.gid = Connections[cnum].gid;
4458   StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4459   crec.start = time(NULL);
4460
4461   StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4462   StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4463   
4464   /* make our mark */
4465   if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4466       fwrite(&crec,sizeof(crec),1,f) != 1)
4467     {
4468       fclose(f);
4469       return(False);
4470     }
4471
4472   fclose(f);
4473   return(True);
4474 }
4475
4476 #if DUMP_CORE
4477 /*******************************************************************
4478 prepare to dump a core file - carefully!
4479 ********************************************************************/
4480 static BOOL dump_core(void)
4481 {
4482   char *p;
4483   pstring dname;
4484   pstrcpy(dname,debugf);
4485   if ((p=strrchr(dname,'/'))) *p=0;
4486   strcat(dname,"/corefiles");
4487   mkdir(dname,0700);
4488   sys_chown(dname,getuid(),getgid());
4489   chmod(dname,0700);
4490   if (chdir(dname)) return(False);
4491   umask(~(0700));
4492
4493 #ifndef NO_GETRLIMIT
4494 #ifdef RLIMIT_CORE
4495   {
4496     struct rlimit rlp;
4497     getrlimit(RLIMIT_CORE, &rlp);
4498     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4499     setrlimit(RLIMIT_CORE, &rlp);
4500     getrlimit(RLIMIT_CORE, &rlp);
4501     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4502   }
4503 #endif
4504 #endif
4505
4506
4507   DEBUG(0,("Dumping core in %s\n",dname));
4508   return(True);
4509 }
4510 #endif
4511
4512 /****************************************************************************
4513 exit the server
4514 ****************************************************************************/
4515 void exit_server(char *reason)
4516 {
4517   static int firsttime=1;
4518   int i;
4519
4520   if (!firsttime) exit(0);
4521   firsttime = 0;
4522
4523   unbecome_user();
4524   DEBUG(2,("Closing connections\n"));
4525   for (i=0;i<MAX_CONNECTIONS;i++)
4526     if (Connections[i].open)
4527       close_cnum(i,(uint16)-1);
4528 #ifdef DFS_AUTH
4529   if (dcelogin_atmost_once)
4530     dfs_unlogin();
4531 #endif
4532   if (!reason) {   
4533     int oldlevel = DEBUGLEVEL;
4534     DEBUGLEVEL = 10;
4535     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4536     if (last_inbuf)
4537       show_msg(last_inbuf);
4538     DEBUGLEVEL = oldlevel;
4539     DEBUG(0,("===============================================================\n"));
4540 #if DUMP_CORE
4541     if (dump_core()) return;
4542 #endif
4543   }    
4544
4545   locking_end();
4546
4547   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4548   exit(0);
4549 }
4550
4551 /****************************************************************************
4552 do some standard substitutions in a string
4553 ****************************************************************************/
4554 void standard_sub(int cnum,char *str)
4555 {
4556   if (VALID_CNUM(cnum)) {
4557     char *p, *s, *home;
4558
4559     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4560       switch (*(p+1)) {
4561         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4562                      string_sub(p,"%H",home);
4563                    else
4564                      p += 2;
4565                    break;
4566         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4567         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4568         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4569         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4570         case '\0' : p++; break; /* don't run off the end of the string */
4571         default  : p+=2; break;
4572       }
4573     }
4574   }
4575   standard_sub_basic(str);
4576 }
4577
4578 /*
4579 These flags determine some of the permissions required to do an operation 
4580
4581 Note that I don't set NEED_WRITE on some write operations because they
4582 are used by some brain-dead clients when printing, and I don't want to
4583 force write permissions on print services.
4584 */
4585 #define AS_USER (1<<0)
4586 #define NEED_WRITE (1<<1)
4587 #define TIME_INIT (1<<2)
4588 #define CAN_IPC (1<<3)
4589 #define AS_GUEST (1<<5)
4590 #define QUEUE_IN_OPLOCK (1<<6)
4591
4592 /* 
4593    define a list of possible SMB messages and their corresponding
4594    functions. Any message that has a NULL function is unimplemented -
4595    please feel free to contribute implementations!
4596 */
4597 struct smb_message_struct
4598 {
4599   int code;
4600   char *name;
4601   int (*fn)();
4602   int flags;
4603 #if PROFILING
4604   unsigned long time;
4605 #endif
4606 }
4607  smb_messages[] = {
4608
4609     /* CORE PROTOCOL */
4610
4611    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4612    {SMBtcon,"SMBtcon",reply_tcon,0},
4613    {SMBtdis,"SMBtdis",reply_tdis,0},
4614    {SMBexit,"SMBexit",reply_exit,0},
4615    {SMBioctl,"SMBioctl",reply_ioctl,0},
4616    {SMBecho,"SMBecho",reply_echo,0},
4617    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4618    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4619    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4620    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4621    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4622    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4623    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4624    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4625
4626    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4627    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4628    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4629
4630    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4631    {SMBread,"SMBread",reply_read,AS_USER},
4632    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4633    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4634    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4635    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4636    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4637    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4638
4639    /* this is a Pathworks specific call, allowing the 
4640       changing of the root path */
4641    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4642
4643    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4644    {SMBflush,"SMBflush",reply_flush,AS_USER},
4645    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4646    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4647    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4648    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4649    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4650    {SMBlock,"SMBlock",reply_lock,AS_USER},
4651    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4652    
4653    /* CORE+ PROTOCOL FOLLOWS */
4654    
4655    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4656    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4657    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4658    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4659    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4660    
4661    /* LANMAN1.0 PROTOCOL FOLLOWS */
4662    
4663    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4664    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4665    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4666    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4667    {SMBwritec,"SMBwritec",NULL,AS_USER},
4668    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4669    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4670    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4671    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4672    {SMBioctls,"SMBioctls",NULL,AS_USER},
4673    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4674    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4675    
4676    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4677    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4678    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4679    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4680    
4681    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4682    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4683    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4684
4685    /* LANMAN2.0 PROTOCOL FOLLOWS */
4686    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4687    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4688    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK },
4689    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4690
4691    /* messaging routines */
4692    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4693    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4694    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4695    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4696
4697    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4698    
4699    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4700    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4701    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4702    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4703  };
4704
4705 /****************************************************************************
4706 return a string containing the function name of a SMB command
4707 ****************************************************************************/
4708 char *smb_fn_name(int type)
4709 {
4710   static char *unknown_name = "SMBunknown";
4711   static int num_smb_messages = 
4712     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4713   int match;
4714
4715   for (match=0;match<num_smb_messages;match++)
4716     if (smb_messages[match].code == type)
4717       break;
4718
4719   if (match == num_smb_messages)
4720     return(unknown_name);
4721
4722   return(smb_messages[match].name);
4723 }
4724
4725
4726 /****************************************************************************
4727 do a switch on the message type, and return the response size
4728 ****************************************************************************/
4729 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4730 {
4731   static int pid= -1;
4732   int outsize = 0;
4733   static int num_smb_messages = 
4734     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4735   int match;
4736
4737 #if PROFILING
4738   struct timeval msg_start_time;
4739   struct timeval msg_end_time;
4740   static unsigned long total_time = 0;
4741
4742   GetTimeOfDay(&msg_start_time);
4743 #endif
4744
4745   if (pid == -1)
4746     pid = getpid();
4747
4748   errno = 0;
4749   last_message = type;
4750
4751   /* make sure this is an SMB packet */
4752   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4753     {
4754       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4755       return(-1);
4756     }
4757
4758   for (match=0;match<num_smb_messages;match++)
4759     if (smb_messages[match].code == type)
4760       break;
4761
4762   if (match == num_smb_messages)
4763     {
4764       DEBUG(0,("Unknown message type %d!\n",type));
4765       outsize = reply_unknown(inbuf,outbuf);
4766     }
4767   else
4768     {
4769       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4770
4771       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4772       {
4773         /* 
4774          * Queue this message as we are the process of an oplock break.
4775          */
4776
4777         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4778                timestring() ));
4779
4780         push_smb_message( inbuf, size);
4781         return -1;
4782       }          
4783
4784       if (smb_messages[match].fn)
4785         {
4786           int cnum = SVAL(inbuf,smb_tid);
4787           int flags = smb_messages[match].flags;
4788           /* In share mode security we must ignore the vuid. */
4789           uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4790           /* Ensure this value is replaced in the incoming packet. */
4791           SSVAL(inbuf,smb_uid,session_tag);
4792
4793           /* does this protocol need to be run as root? */
4794           if (!(flags & AS_USER))
4795             unbecome_user();
4796
4797           /* does this protocol need to be run as the connected user? */
4798           if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4799             if (flags & AS_GUEST) 
4800               flags &= ~AS_USER;
4801             else
4802               return(ERROR(ERRSRV,ERRinvnid));
4803           }
4804           /* this code is to work around a bug is MS client 3 without
4805              introducing a security hole - it needs to be able to do
4806              print queue checks as guest if it isn't logged in properly */
4807           if (flags & AS_USER)
4808             flags &= ~AS_GUEST;
4809
4810           /* does it need write permission? */
4811           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4812             return(ERROR(ERRSRV,ERRaccess));
4813
4814           /* ipc services are limited */
4815           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4816             return(ERROR(ERRSRV,ERRaccess));        
4817
4818           /* load service specific parameters */
4819           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4820             return(ERROR(ERRSRV,ERRaccess));
4821
4822           /* does this protocol need to be run as guest? */
4823           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4824             return(ERROR(ERRSRV,ERRaccess));
4825
4826           last_inbuf = inbuf;
4827
4828           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4829         }
4830       else
4831         {
4832           outsize = reply_unknown(inbuf,outbuf);
4833         }
4834     }
4835
4836 #if PROFILING
4837   GetTimeOfDay(&msg_end_time);
4838   if (!(smb_messages[match].flags & TIME_INIT))
4839     {
4840       smb_messages[match].time = 0;
4841       smb_messages[match].flags |= TIME_INIT;
4842     }
4843   {
4844     unsigned long this_time =     
4845       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4846         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4847     smb_messages[match].time += this_time;
4848     total_time += this_time;
4849   }
4850   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4851            smb_fn_name(type),smb_messages[match].time,
4852         (100.0*smb_messages[match].time) / total_time));
4853 #endif
4854
4855   return(outsize);
4856 }
4857
4858
4859 /****************************************************************************
4860   construct a chained reply and add it to the already made reply
4861   **************************************************************************/
4862 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4863 {
4864   static char *orig_inbuf;
4865   static char *orig_outbuf;
4866   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4867   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4868   char *inbuf2, *outbuf2;
4869   int outsize2;
4870   char inbuf_saved[smb_wct];
4871   char outbuf_saved[smb_wct];
4872   extern int chain_size;
4873   int wct = CVAL(outbuf,smb_wct);
4874   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4875
4876   /* maybe its not chained */
4877   if (smb_com2 == 0xFF) {
4878     CVAL(outbuf,smb_vwv0) = 0xFF;
4879     return outsize;
4880   }
4881
4882   if (chain_size == 0) {
4883     /* this is the first part of the chain */
4884     orig_inbuf = inbuf;
4885     orig_outbuf = outbuf;
4886   }
4887
4888   /* we need to tell the client where the next part of the reply will be */
4889   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4890   CVAL(outbuf,smb_vwv0) = smb_com2;
4891
4892   /* remember how much the caller added to the chain, only counting stuff
4893      after the parameter words */
4894   chain_size += outsize - smb_wct;
4895
4896   /* work out pointers into the original packets. The
4897      headers on these need to be filled in */
4898   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4899   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4900
4901   /* remember the original command type */
4902   smb_com1 = CVAL(orig_inbuf,smb_com);
4903
4904   /* save the data which will be overwritten by the new headers */
4905   memcpy(inbuf_saved,inbuf2,smb_wct);
4906   memcpy(outbuf_saved,outbuf2,smb_wct);
4907
4908   /* give the new packet the same header as the last part of the SMB */
4909   memmove(inbuf2,inbuf,smb_wct);
4910
4911   /* create the in buffer */
4912   CVAL(inbuf2,smb_com) = smb_com2;
4913
4914   /* create the out buffer */
4915   bzero(outbuf2,smb_size);
4916   set_message(outbuf2,0,0,True);
4917   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4918   
4919   memcpy(outbuf2+4,inbuf2+4,4);
4920   CVAL(outbuf2,smb_rcls) = SUCCESS;
4921   CVAL(outbuf2,smb_reh) = 0;
4922   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4923                                                                   means a reply */
4924   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4925   SSVAL(outbuf2,smb_err,SUCCESS);
4926   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4927   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4928   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4929   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4930
4931   DEBUG(3,("Chained message\n"));
4932   show_msg(inbuf2);
4933
4934   /* process the request */
4935   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4936                             bufsize-chain_size);
4937
4938   /* copy the new reply and request headers over the old ones, but
4939      preserve the smb_com field */
4940   memmove(orig_outbuf,outbuf2,smb_wct);
4941   CVAL(orig_outbuf,smb_com) = smb_com1;
4942
4943   /* restore the saved data, being careful not to overwrite any
4944    data from the reply header */
4945   memcpy(inbuf2,inbuf_saved,smb_wct);
4946   {
4947     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4948     if (ofs < 0) ofs = 0;
4949     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4950   }
4951
4952   return outsize2;
4953 }
4954
4955
4956
4957 /****************************************************************************
4958   construct a reply to the incoming packet
4959 ****************************************************************************/
4960 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4961 {
4962   int type = CVAL(inbuf,smb_com);
4963   int outsize = 0;
4964   int msg_type = CVAL(inbuf,0);
4965   extern int chain_size;
4966
4967   smb_last_time = time(NULL);
4968
4969   chain_size = 0;
4970   chain_fnum = -1;
4971   reset_chain_pnum();
4972
4973   bzero(outbuf,smb_size);
4974
4975   if (msg_type != 0)
4976     return(reply_special(inbuf,outbuf));  
4977
4978   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4979   set_message(outbuf,0,0,True);
4980   
4981   memcpy(outbuf+4,inbuf+4,4);
4982   CVAL(outbuf,smb_rcls) = SUCCESS;
4983   CVAL(outbuf,smb_reh) = 0;
4984   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4985                                                              means a reply */
4986   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4987   SSVAL(outbuf,smb_err,SUCCESS);
4988   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4989   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4990   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4991   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4992
4993   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4994
4995   outsize += chain_size;
4996
4997   if(outsize > 4)
4998     smb_setlen(outbuf,outsize - 4);
4999   return(outsize);
5000 }
5001
5002 /****************************************************************************
5003   process commands from the client
5004 ****************************************************************************/
5005 static void process(void)
5006 {
5007   extern int Client;
5008
5009   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5010   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5011   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
5012     return;
5013
5014   InBuffer += SMB_ALIGNMENT;
5015   OutBuffer += SMB_ALIGNMENT;
5016
5017 #if PRIME_NMBD
5018   DEBUG(3,("priming nmbd\n"));
5019   {
5020     struct in_addr ip;
5021     ip = *interpret_addr2("localhost");
5022     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
5023     *OutBuffer = 0;
5024     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
5025   }
5026 #endif    
5027
5028   /* re-initialise the timezone */
5029   TimeInit();
5030
5031   while (True)
5032   {
5033     int deadtime = lp_deadtime()*60;
5034     int counter;
5035     int last_keepalive=0;
5036     int service_load_counter = 0;
5037     BOOL got_smb = False;
5038
5039     if (deadtime <= 0)
5040       deadtime = DEFAULT_SMBD_TIMEOUT;
5041
5042 #if USE_READ_PREDICTION
5043     if (lp_readprediction())
5044       do_read_prediction();
5045 #endif
5046
5047     errno = 0;      
5048
5049     for (counter=SMBD_SELECT_LOOP; 
5050           !receive_message_or_smb(Client,oplock_sock,
5051                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
5052           counter += SMBD_SELECT_LOOP)
5053     {
5054       int i;
5055       time_t t;
5056       BOOL allidle = True;
5057       extern int keepalive;
5058
5059       if (counter > 365 * 3600) /* big number of seconds. */
5060       {
5061         counter = 0;
5062         service_load_counter = 0;
5063       }
5064
5065       if (smb_read_error == READ_EOF) 
5066       {
5067         DEBUG(3,("end of file from client\n"));
5068         return;
5069       }
5070
5071       if (smb_read_error == READ_ERROR) 
5072       {
5073         DEBUG(3,("receive_smb error (%s) exiting\n",
5074                   strerror(errno)));
5075         return;
5076       }
5077
5078       t = time(NULL);
5079
5080       /* become root again if waiting */
5081       unbecome_user();
5082
5083       /* check for smb.conf reload */
5084       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5085       {
5086         service_load_counter = counter;
5087
5088         /* reload services, if files have changed. */
5089         reload_services(True);
5090       }
5091
5092       /* automatic timeout if all connections are closed */      
5093       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
5094       {
5095         DEBUG(2,("%s Closing idle connection\n",timestring()));
5096         return;
5097       }
5098
5099       if (keepalive && (counter-last_keepalive)>keepalive) 
5100       {
5101               struct cli_state *cli = server_client();
5102               if (!send_keepalive(Client)) { 
5103                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5104                       return;
5105               }     
5106               /* also send a keepalive to the password server if its still
5107                  connected */
5108               if (cli && cli->initialised)
5109                       send_keepalive(cli->fd);
5110               last_keepalive = counter;
5111       }
5112
5113       /* check for connection timeouts */
5114       for (i=0;i<MAX_CONNECTIONS;i++)
5115         if (Connections[i].open)
5116         {
5117           /* close dirptrs on connections that are idle */
5118           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5119             dptr_idlecnum(i);
5120
5121           if (Connections[i].num_files_open > 0 ||
5122                      (t-Connections[i].lastused)<deadtime)
5123             allidle = False;
5124         }
5125
5126       if (allidle && num_connections_open>0) 
5127       {
5128         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5129         return;
5130       }
5131     }
5132
5133     if(got_smb)
5134       process_smb(InBuffer, OutBuffer);
5135     else
5136       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5137   }
5138 }
5139
5140
5141 /****************************************************************************
5142   initialise connect, service and file structs
5143 ****************************************************************************/
5144 static void init_structs(void )
5145 {
5146   int i;
5147   get_myname(myhostname,NULL);
5148
5149   for (i=0;i<MAX_CONNECTIONS;i++)
5150     {
5151       Connections[i].open = False;
5152       Connections[i].num_files_open=0;
5153       Connections[i].lastused=0;
5154       Connections[i].used=False;
5155       string_init(&Connections[i].user,"");
5156       string_init(&Connections[i].dirpath,"");
5157       string_init(&Connections[i].connectpath,"");
5158       string_init(&Connections[i].origpath,"");
5159     }
5160
5161   for (i=0;i<MAX_OPEN_FILES;i++)
5162     {
5163       Files[i].open = False;
5164       string_init(&Files[i].name,"");
5165
5166     }
5167
5168   for (i=0;i<MAX_OPEN_FILES;i++)
5169     {
5170       file_fd_struct *fd_ptr = &FileFd[i];
5171       fd_ptr->ref_count = 0;
5172       fd_ptr->dev = (int32)-1;
5173       fd_ptr->inode = (int32)-1;
5174       fd_ptr->fd = -1;
5175       fd_ptr->fd_readonly = -1;
5176       fd_ptr->fd_writeonly = -1;
5177       fd_ptr->real_open_flags = -1;
5178     }
5179
5180   /* for RPC pipes */
5181   init_rpc_pipe_hnd();
5182
5183 #ifdef NTDOMAIN
5184   /* for LSA handles */
5185   init_lsa_policy_hnd();
5186 #endif
5187
5188   init_dptrs();
5189 }
5190
5191 /****************************************************************************
5192 usage on the program
5193 ****************************************************************************/
5194 static void usage(char *pname)
5195 {
5196   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5197
5198   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5199   printf("Version %s\n",VERSION);
5200   printf("\t-D                    become a daemon\n");
5201   printf("\t-p port               listen on the specified port\n");
5202   printf("\t-d debuglevel         set the debuglevel\n");
5203   printf("\t-l log basename.      Basename for log/debug files\n");
5204   printf("\t-s services file.     Filename of services file\n");
5205   printf("\t-P                    passive only\n");
5206   printf("\t-a                    overwrite log file, don't append\n");
5207   printf("\n");
5208 }
5209
5210
5211 /****************************************************************************
5212   main program
5213 ****************************************************************************/
5214  int main(int argc,char *argv[])
5215 {
5216   extern BOOL append_log;
5217   /* shall I run as a daemon */
5218   BOOL is_daemon = False;
5219   int port = SMB_PORT;
5220   int opt;
5221   extern char *optarg;
5222   char pidFile[100];
5223
5224   *pidFile = '\0';
5225
5226 #ifdef NEED_AUTH_PARAMETERS
5227   set_auth_parameters(argc,argv);
5228 #endif
5229
5230 #ifdef SecureWare
5231   setluid(0);
5232 #endif
5233
5234   append_log = True;
5235
5236   TimeInit();
5237
5238   strcpy(debugf,SMBLOGFILE);  
5239
5240   setup_logging(argv[0],False);
5241
5242   charset_initialise();
5243
5244   /* make absolutely sure we run as root - to handle cases where people
5245      are crazy enough to have it setuid */
5246 #ifdef USE_SETRES
5247   setresuid(0,0,0);
5248 #else
5249   setuid(0);
5250   seteuid(0);
5251   setuid(0);
5252   seteuid(0);
5253 #endif
5254
5255   fault_setup(exit_server);
5256   signal(SIGTERM , SIGNAL_CAST dflt_sig);
5257
5258   /* we want total control over the permissions on created files,
5259      so set our umask to 0 */
5260   umask(0);
5261
5262   GetWd(OriginalDir);
5263
5264   init_uid();
5265
5266   /* this is for people who can't start the program correctly */
5267   while (argc > 1 && (*argv[1] != '-'))
5268     {
5269       argv++;
5270       argc--;
5271     }
5272
5273   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5274     switch (opt)
5275       {
5276       case 'f':
5277         strncpy(pidFile, optarg, sizeof(pidFile));
5278         break;
5279       case 'O':
5280         strcpy(user_socket_options,optarg);
5281         break;
5282       case 'i':
5283         strcpy(scope,optarg);
5284         break;
5285       case 'P':
5286         {
5287           extern BOOL passive;
5288           passive = True;
5289         }
5290         break;  
5291       case 's':
5292         strcpy(servicesf,optarg);
5293         break;
5294       case 'l':
5295         strcpy(debugf,optarg);
5296         break;
5297       case 'a':
5298         {
5299           extern BOOL append_log;
5300           append_log = !append_log;
5301         }
5302         break;
5303       case 'D':
5304         is_daemon = True;
5305         break;
5306       case 'd':
5307         if (*optarg == 'A')
5308           DEBUGLEVEL = 10000;
5309         else
5310           DEBUGLEVEL = atoi(optarg);
5311         break;
5312       case 'p':
5313         port = atoi(optarg);
5314         break;
5315       case 'h':
5316         usage(argv[0]);
5317         exit(0);
5318         break;
5319       default:
5320         usage(argv[0]);
5321         exit(1);
5322       }
5323
5324   reopen_logs();
5325
5326   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5327   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5328
5329 #ifndef NO_GETRLIMIT
5330 #ifdef RLIMIT_NOFILE
5331   {
5332     struct rlimit rlp;
5333     getrlimit(RLIMIT_NOFILE, &rlp);
5334     /*
5335      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5336      * extra fd we need to read directories, as well as the log files
5337      * and standard handles etc.
5338      */
5339     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5340     setrlimit(RLIMIT_NOFILE, &rlp);
5341     getrlimit(RLIMIT_NOFILE, &rlp);
5342     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5343   }
5344 #endif
5345 #endif
5346
5347   
5348   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5349         getuid(),getgid(),geteuid(),getegid()));
5350
5351   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5352     {
5353       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5354       exit(1);
5355     }
5356
5357   init_structs();
5358
5359   if (!reload_services(False))
5360     return(-1); 
5361
5362   codepage_initialise(lp_client_code_page());
5363
5364   strcpy(myworkgroup, lp_workgroup());
5365
5366 #ifndef NO_SIGNAL_TEST
5367   signal(SIGHUP,SIGNAL_CAST sig_hup);
5368 #endif
5369
5370   /* Setup the signals that allow the debug log level
5371      to by dynamically changed. */
5372  
5373   /* If we are using the malloc debug code we can't use
5374      SIGUSR1 and SIGUSR2 to do debug level changes. */
5375
5376 #ifndef MEM_MAN
5377 #if defined(SIGUSR1)
5378   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5379 #endif /* SIGUSR1 */
5380    
5381 #if defined(SIGUSR2)
5382   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5383 #endif /* SIGUSR2 */
5384 #endif /* MEM_MAN */
5385
5386   DEBUG(3,("%s loaded services\n",timestring()));
5387
5388   if (!is_daemon && !is_a_socket(0))
5389     {
5390       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5391       is_daemon = True;
5392     }
5393
5394   if (is_daemon)
5395     {
5396       DEBUG(3,("%s becoming a daemon\n",timestring()));
5397       become_daemon();
5398     }
5399
5400   if (!directory_exist(lp_lockdir(), NULL)) {
5401           mkdir(lp_lockdir(), 0755);
5402   }
5403
5404   if (*pidFile)
5405     {
5406       int     fd;
5407       char    buf[20];
5408
5409       if ((fd = open(pidFile,
5410 #ifdef O_NONBLOCK
5411          O_NONBLOCK | 
5412 #endif
5413          O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5414         {
5415            DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5416            exit(1);
5417         }
5418       if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5419         {
5420           DEBUG(0,("ERROR: smbd is already running\n"));
5421           exit(1);
5422         }
5423       sprintf(buf, "%u\n", (unsigned int) getpid());
5424       if (write(fd, buf, strlen(buf)) < 0)
5425         {
5426           DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5427           exit(1);
5428         }
5429       /* Leave pid file open & locked for the duration... */
5430     }
5431
5432   if (!open_sockets(is_daemon,port))
5433     exit(1);
5434
5435   if (!locking_init(0))
5436     exit(1);
5437
5438   /* possibly reload the services file. */
5439   reload_services(True);
5440
5441   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5442
5443   if (*lp_rootdir())
5444     {
5445       if (sys_chroot(lp_rootdir()) == 0)
5446         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5447     }
5448
5449   /* Setup the oplock IPC socket. */
5450   if(!open_oplock_ipc())
5451     exit(1);
5452
5453   process();
5454   close_sockets();
5455
5456   exit_server("normal exit");
5457   return(0);
5458 }
5459
5460