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