Needed fix to SIGHUP handling donated by branko.cibej@hermes.si
[kai/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_OPEN_FILES];
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(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(flags & O_WRONLY) {
1439         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1440         fd_ptr->real_open_flags = O_WRONLY;
1441       } else {
1442         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1443         fd_ptr->real_open_flags = O_RDONLY;
1444       }
1445     }
1446   }
1447
1448   if ((fd_ptr->fd >=0) && 
1449       Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1450     pstring dname;
1451     int dum1,dum2,dum3;
1452     char *p;
1453     pstrcpy(dname,fname);
1454     p = strrchr(dname,'/');
1455     if (p) *p = 0;
1456     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
1457         lp_minprintspace(SNUM(cnum))) {
1458       fd_attempt_close(fd_ptr);
1459       fsp->fd_ptr = 0;
1460       if(fd_ptr->ref_count == 0)
1461         sys_unlink(fname);
1462       errno = ENOSPC;
1463       return;
1464     }
1465   }
1466     
1467   if (fd_ptr->fd < 0)
1468   {
1469     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1470       fname,strerror(errno),flags));
1471     /* Ensure the ref_count is decremented. */
1472     fd_attempt_close(fd_ptr);
1473     check_for_pipe(fname);
1474     return;
1475   }
1476
1477   if (fd_ptr->fd >= 0)
1478   {
1479     if(sbuf == 0) {
1480       /* Do the fstat */
1481       if(fstat(fd_ptr->fd, &statbuf) == -1) {
1482         /* Error - backout !! */
1483         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1484                  fd_ptr->fd, fname,strerror(errno)));
1485         /* Ensure the ref_count is decremented. */
1486         fd_attempt_close(fd_ptr);
1487         return;
1488       }
1489       sbuf = &statbuf;
1490     }
1491
1492     /* Set the correct entries in fd_ptr. */
1493     fd_ptr->dev = (uint32)sbuf->st_dev;
1494     fd_ptr->inode = (uint32)sbuf->st_ino;
1495
1496     fsp->fd_ptr = fd_ptr;
1497     Connections[cnum].num_files_open++;
1498     fsp->mode = sbuf->st_mode;
1499     GetTimeOfDay(&fsp->open_time);
1500     fsp->vuid = current_user.vuid;
1501     fsp->size = 0;
1502     fsp->pos = -1;
1503     fsp->open = True;
1504     fsp->mmap_ptr = NULL;
1505     fsp->mmap_size = 0;
1506     fsp->can_lock = True;
1507     fsp->can_read = ((flags & O_WRONLY)==0);
1508     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1509     fsp->share_mode = 0;
1510     fsp->print_file = Connections[cnum].printer;
1511     fsp->modified = False;
1512     fsp->granted_oplock = False;
1513     fsp->sent_oplock_break = False;
1514     fsp->cnum = cnum;
1515     string_set(&fsp->name,dos_to_unix(fname,False));
1516     fsp->wbmpx_ptr = NULL;      
1517
1518     /*
1519      * If the printer is marked as postscript output a leading
1520      * file identifier to ensure the file is treated as a raw
1521      * postscript file.
1522      * This has a similar effect as CtrlD=0 in WIN.INI file.
1523      * tim@fsg.com 09/06/94
1524      */
1525     if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write) 
1526     {
1527       DEBUG(3,("Writing postscript line\n"));
1528       write_file(fnum,"%!\n",3);
1529     }
1530       
1531     DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1532           timestring(),
1533           *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname,
1534           BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1535           Connections[cnum].num_files_open,fnum));
1536
1537   }
1538
1539 #if USE_MMAP
1540   /* mmap it if read-only */
1541   if (!fsp->can_write)
1542   {
1543     fsp->mmap_size = file_size(fname);
1544     fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1545                                  PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1546
1547     if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1548     {
1549       DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1550       fsp->mmap_ptr = NULL;
1551     }
1552   }
1553 #endif
1554 }
1555
1556 /*******************************************************************
1557 sync a file
1558 ********************************************************************/
1559 void sync_file(int fnum)
1560 {
1561 #ifndef NO_FSYNC
1562   fsync(Files[fnum].fd_ptr->fd);
1563 #endif
1564 }
1565
1566 /****************************************************************************
1567 run a file if it is a magic script
1568 ****************************************************************************/
1569 static void check_magic(int fnum,int cnum)
1570 {
1571   if (!*lp_magicscript(SNUM(cnum)))
1572     return;
1573
1574   DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1575
1576   {
1577     char *p;
1578     if (!(p = strrchr(Files[fnum].name,'/')))
1579       p = Files[fnum].name;
1580     else
1581       p++;
1582
1583     if (!strequal(lp_magicscript(SNUM(cnum)),p))
1584       return;
1585   }
1586
1587   {
1588     int ret;
1589     pstring magic_output;
1590     pstring fname;
1591     pstrcpy(fname,Files[fnum].name);
1592
1593     if (*lp_magicoutput(SNUM(cnum)))
1594       pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1595     else
1596       slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
1597
1598     chmod(fname,0755);
1599     ret = smbrun(fname,magic_output,False);
1600     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1601     unlink(fname);
1602   }
1603 }
1604
1605
1606 /****************************************************************************
1607 close a file - possibly invalidating the read prediction
1608
1609 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1610 operation otherwise it came as the result of some other operation such as
1611 the closing of the connection. In the latter case printing and
1612 magic scripts are not run
1613 ****************************************************************************/
1614 void close_file(int fnum, BOOL normal_close)
1615 {
1616   files_struct *fs_p = &Files[fnum];
1617   int cnum = fs_p->cnum;
1618   uint32 dev = fs_p->fd_ptr->dev;
1619   uint32 inode = fs_p->fd_ptr->inode;
1620   int token;
1621
1622   Files[fnum].reserved = False;
1623
1624 #if USE_READ_PREDICTION
1625   invalidate_read_prediction(fs_p->fd_ptr->fd);
1626 #endif
1627
1628   fs_p->open = False;
1629   Connections[cnum].num_files_open--;
1630   if(fs_p->wbmpx_ptr) 
1631   {
1632     free((char *)fs_p->wbmpx_ptr);
1633     fs_p->wbmpx_ptr = NULL;
1634   }
1635
1636 #if USE_MMAP
1637   if(fs_p->mmap_ptr) 
1638   {
1639     munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1640     fs_p->mmap_ptr = NULL;
1641   }
1642 #endif
1643
1644   if (lp_share_modes(SNUM(cnum)))
1645   {
1646     lock_share_entry( cnum, dev, inode, &token);
1647     del_share_mode(token, fnum);
1648   }
1649
1650   fd_attempt_close(fs_p->fd_ptr);
1651
1652   if (lp_share_modes(SNUM(cnum)))
1653     unlock_share_entry( cnum, dev, inode, token);
1654
1655   /* NT uses smbclose to start a print - weird */
1656   if (normal_close && fs_p->print_file)
1657     print_file(fnum);
1658
1659   /* check for magic scripts */
1660   if (normal_close)
1661     check_magic(fnum,cnum);
1662
1663   if(fs_p->granted_oplock == True)
1664     global_oplocks_open--;
1665
1666   fs_p->sent_oplock_break = False;
1667
1668   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1669            timestring(),Connections[cnum].user,fs_p->name,
1670            Connections[cnum].num_files_open));
1671
1672   if (fs_p->name) {
1673           string_free(&fs_p->name);
1674   }
1675
1676   /* we will catch bugs faster by zeroing this structure */
1677   memset(fs_p, 0, sizeof(*fs_p));
1678 }
1679
1680 enum {AFAIL,AREAD,AWRITE,AALL};
1681
1682 /*******************************************************************
1683 reproduce the share mode access table
1684 ********************************************************************/
1685 static int access_table(int new_deny,int old_deny,int old_mode,
1686                         int share_pid,char *fname)
1687 {
1688   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1689
1690   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1691     int pid = getpid();
1692     if (old_deny == new_deny && share_pid == pid) 
1693         return(AALL);    
1694
1695     if (old_mode == 0) return(AREAD);
1696
1697     /* the new smbpub.zip spec says that if the file extension is
1698        .com, .dll, .exe or .sym then allow the open. I will force
1699        it to read-only as this seems sensible although the spec is
1700        a little unclear on this. */
1701     if ((fname = strrchr(fname,'.'))) {
1702       if (strequal(fname,".com") ||
1703           strequal(fname,".dll") ||
1704           strequal(fname,".exe") ||
1705           strequal(fname,".sym"))
1706         return(AREAD);
1707     }
1708
1709     return(AFAIL);
1710   }
1711
1712   switch (new_deny) 
1713     {
1714     case DENY_WRITE:
1715       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1716       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1717       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1718       return(AFAIL);
1719     case DENY_READ:
1720       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1721       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1722       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1723       return(AFAIL);
1724     case DENY_NONE:
1725       if (old_deny==DENY_WRITE) return(AREAD);
1726       if (old_deny==DENY_READ) return(AWRITE);
1727       if (old_deny==DENY_NONE) return(AALL);
1728       return(AFAIL);      
1729     }
1730   return(AFAIL);      
1731 }
1732
1733 /*******************************************************************
1734 check if the share mode on a file allows it to be deleted or unlinked
1735 return True if sharing doesn't prevent the operation
1736 ********************************************************************/
1737 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1738 {
1739   int i;
1740   int ret = False;
1741   share_mode_entry *old_shares = 0;
1742   int num_share_modes;
1743   struct stat sbuf;
1744   int token;
1745   int pid = getpid();
1746   uint32 dev, inode;
1747
1748   if(!lp_share_modes(SNUM(cnum)))
1749     return True;
1750
1751   if (stat(fname,&sbuf) == -1) return(True);
1752
1753   dev = (uint32)sbuf.st_dev;
1754   inode = (uint32)sbuf.st_ino;
1755
1756   lock_share_entry(cnum, dev, inode, &token);
1757   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1758
1759   /*
1760    * Check if the share modes will give us access.
1761    */
1762
1763   if(num_share_modes != 0)
1764   {
1765     BOOL broke_oplock;
1766
1767     do
1768     {
1769
1770       broke_oplock = False;
1771       for(i = 0; i < num_share_modes; i++)
1772       {
1773         share_mode_entry *share_entry = &old_shares[i];
1774
1775         /* 
1776          * Break oplocks before checking share modes. See comment in
1777          * open_file_shared for details. 
1778          * Check if someone has an oplock on this file. If so we must 
1779          * break it before continuing. 
1780          */
1781         if(share_entry->op_type & BATCH_OPLOCK)
1782         {
1783
1784           /*
1785            * It appears that the NT redirector may have a bug, in that
1786            * it tries to do an SMBmv on a file that it has open with a
1787            * batch oplock, and then fails to respond to the oplock break
1788            * request. This only seems to occur when the client is doing an
1789            * SMBmv to the smbd it is using - thus we try and detect this
1790            * condition by checking if the file being moved is open and oplocked by
1791            * this smbd process, and then not sending the oplock break in this
1792            * special case. If the file was open with a deny mode that 
1793            * prevents the move the SMBmv will fail anyway with a share
1794            * violation error. JRA.
1795            */
1796           if(rename_op && (share_entry->pid == pid))
1797           {
1798             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1799 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1800             /* 
1801              * This next line is a test that allows the deny-mode
1802              * processing to be skipped. This seems to be needed as
1803              * NT insists on the rename succeeding (in Office 9x no less !).
1804              * This should be removed as soon as (a) MS fix the redirector
1805              * bug or (b) NT SMB support in Samba makes NT not issue the
1806              * call (as is my fervent hope). JRA.
1807              */ 
1808             continue;
1809           }
1810           else
1811           {
1812             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1813 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1814
1815             /* Oplock break.... */
1816             unlock_share_entry(cnum, dev, inode, token);
1817             if(request_oplock_break(share_entry, dev, inode) == False)
1818             {
1819               free((char *)old_shares);
1820               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1821 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1822               return False;
1823             }
1824             lock_share_entry(cnum, dev, inode, &token);
1825             broke_oplock = True;
1826             break;
1827           }
1828         }
1829
1830         /* someone else has a share lock on it, check to see 
1831            if we can too */
1832         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1833           goto free_and_exit;
1834
1835       } /* end for */
1836
1837       if(broke_oplock)
1838       {
1839         free((char *)old_shares);
1840         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1841       }
1842     } while(broke_oplock);
1843   }
1844
1845   /* XXXX exactly what share mode combinations should be allowed for
1846      deleting/renaming? */
1847   /* If we got here then either there were no share modes or
1848      all share modes were DENY_DOS and the pid == getpid() */
1849   ret = True;
1850
1851 free_and_exit:
1852
1853   unlock_share_entry(cnum, dev, inode, token);
1854   if(old_shares != NULL)
1855     free((char *)old_shares);
1856   return(ret);
1857 }
1858
1859 /****************************************************************************
1860   C. Hoch 11/22/95
1861   Helper for open_file_shared. 
1862   Truncate a file after checking locking; close file if locked.
1863   **************************************************************************/
1864 static void truncate_unless_locked(int fnum, int cnum, int token, 
1865                                    BOOL *share_locked)
1866 {
1867   if (Files[fnum].can_write){
1868     if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1869       /* If share modes are in force for this connection we
1870          have the share entry locked. Unlock it before closing. */
1871       if (*share_locked && lp_share_modes(SNUM(cnum)))
1872         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
1873                             Files[fnum].fd_ptr->inode, token);
1874       close_file(fnum,False);   
1875       /* Share mode no longer locked. */
1876       *share_locked = False;
1877       errno = EACCES;
1878       unix_ERR_class = ERRDOS;
1879       unix_ERR_code = ERRlock;
1880     }
1881     else
1882       ftruncate(Files[fnum].fd_ptr->fd,0); 
1883   }
1884 }
1885
1886 /****************************************************************************
1887 check if we can open a file with a share mode
1888 ****************************************************************************/
1889 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1890                       BOOL fcbopen, int *flags)
1891 {
1892   int old_open_mode = share->share_mode &0xF;
1893   int old_deny_mode = (share->share_mode >>4)&7;
1894
1895   if (old_deny_mode > 4 || old_open_mode > 2)
1896   {
1897     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1898                deny_mode,old_deny_mode,old_open_mode,fname));
1899     return False;
1900   }
1901
1902   {
1903     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1904                                 share->pid,fname);
1905
1906     if ((access_allowed == AFAIL) ||
1907         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1908         (access_allowed == AREAD && *flags == O_WRONLY) ||
1909         (access_allowed == AWRITE && *flags == O_RDONLY))
1910     {
1911       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1912                 deny_mode,old_deny_mode,old_open_mode,
1913                 share->pid,fname, fcbopen, *flags, access_allowed));
1914       return False;
1915     }
1916
1917     if (access_allowed == AREAD)
1918       *flags = O_RDONLY;
1919
1920     if (access_allowed == AWRITE)
1921       *flags = O_WRONLY;
1922
1923   }
1924   return True;
1925 }
1926
1927 /****************************************************************************
1928 open a file with a share mode
1929 ****************************************************************************/
1930 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1931                       int mode,int oplock_request, int *Access,int *action)
1932 {
1933   files_struct *fs_p = &Files[fnum];
1934   int flags=0;
1935   int flags2=0;
1936   int deny_mode = (share_mode>>4)&7;
1937   struct stat sbuf;
1938   BOOL file_existed = file_exist(fname,&sbuf);
1939   BOOL share_locked = False;
1940   BOOL fcbopen = False;
1941   int token;
1942   uint32 dev = 0;
1943   uint32 inode = 0;
1944   int num_share_modes = 0;
1945
1946   fs_p->open = False;
1947   fs_p->fd_ptr = 0;
1948
1949   /* this is for OS/2 EAs - try and say we don't support them */
1950   if (strstr(fname,".+,;=[].")) 
1951   {
1952     unix_ERR_class = ERRDOS;
1953     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1954 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1955     unix_ERR_code = ERRcannotopen;
1956 #else /* OS2_WPS_FIX */
1957     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1958 #endif /* OS2_WPS_FIX */
1959
1960     return;
1961   }
1962
1963   if ((ofun & 0x3) == 0 && file_existed)  
1964   {
1965     errno = EEXIST;
1966     return;
1967   }
1968       
1969   if (ofun & 0x10)
1970     flags2 |= O_CREAT;
1971   if ((ofun & 0x3) == 2)
1972     flags2 |= O_TRUNC;
1973
1974   /* note that we ignore the append flag as 
1975      append does not mean the same thing under dos and unix */
1976
1977   switch (share_mode&0xF)
1978   {
1979     case 1: 
1980       flags = O_WRONLY; 
1981       break;
1982     case 0xF: 
1983       fcbopen = True;
1984       flags = O_RDWR; 
1985       break;
1986     case 2: 
1987       flags = O_RDWR; 
1988       break;
1989     default:
1990       flags = O_RDONLY;
1991       break;
1992   }
1993
1994 #if defined(O_SYNC)
1995   if (share_mode&(1<<14)) {
1996           flags2 |= O_SYNC;
1997   }
1998 #endif /* O_SYNC */
1999   
2000   if (flags != O_RDONLY && file_existed && 
2001       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
2002   {
2003     if (!fcbopen) 
2004     {
2005       errno = EACCES;
2006       return;
2007     }
2008     flags = O_RDONLY;
2009   }
2010
2011   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
2012   {
2013     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
2014     errno = EINVAL;
2015     return;
2016   }
2017
2018   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
2019
2020   if (lp_share_modes(SNUM(cnum))) 
2021   {
2022     int i;
2023     share_mode_entry *old_shares = 0;
2024
2025     if (file_existed)
2026     {
2027       dev = (uint32)sbuf.st_dev;
2028       inode = (uint32)sbuf.st_ino;
2029       lock_share_entry(cnum, dev, inode, &token);
2030       share_locked = True;
2031       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
2032     }
2033
2034     /*
2035      * Check if the share modes will give us access.
2036      */
2037
2038     if(share_locked && (num_share_modes != 0))
2039     {
2040       BOOL broke_oplock;
2041
2042       do
2043       {
2044
2045         broke_oplock = False;
2046         for(i = 0; i < num_share_modes; i++)
2047         {
2048           share_mode_entry *share_entry = &old_shares[i];
2049
2050           /* 
2051            * By observation of NetBench, oplocks are broken *before* share
2052            * modes are checked. This allows a file to be closed by the client
2053            * if the share mode would deny access and the client has an oplock. 
2054            * Check if someone has an oplock on this file. If so we must break 
2055            * it before continuing. 
2056            */
2057           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
2058           {
2059
2060             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
2061 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
2062
2063             /* Oplock break.... */
2064             unlock_share_entry(cnum, dev, inode, token);
2065             if(request_oplock_break(share_entry, dev, inode) == False)
2066             {
2067               free((char *)old_shares);
2068               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
2069 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
2070               errno = EACCES;
2071               unix_ERR_class = ERRDOS;
2072               unix_ERR_code = ERRbadshare;
2073               return;
2074             }
2075             lock_share_entry(cnum, dev, inode, &token);
2076             broke_oplock = True;
2077             break;
2078           }
2079
2080           /* someone else has a share lock on it, check to see 
2081              if we can too */
2082           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
2083           {
2084             free((char *)old_shares);
2085             unlock_share_entry(cnum, dev, inode, token);
2086             errno = EACCES;
2087             unix_ERR_class = ERRDOS;
2088             unix_ERR_code = ERRbadshare;
2089             return;
2090           }
2091
2092         } /* end for */
2093
2094         if(broke_oplock)
2095         {
2096           free((char *)old_shares);
2097           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
2098         }
2099       } while(broke_oplock);
2100     }
2101
2102     if(old_shares != 0)
2103       free((char *)old_shares);
2104   }
2105
2106   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
2107            flags,flags2,mode));
2108
2109   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
2110   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
2111   {
2112     flags = O_RDONLY;
2113     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
2114   }
2115
2116   if (fs_p->open) 
2117   {
2118     int open_mode=0;
2119
2120     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
2121     {
2122       /* We created the file - thus we must now lock the share entry before creating it. */
2123       dev = fs_p->fd_ptr->dev;
2124       inode = fs_p->fd_ptr->inode;
2125       lock_share_entry(cnum, dev, inode, &token);
2126       share_locked = True;
2127     }
2128
2129     switch (flags) 
2130     {
2131       case O_RDONLY:
2132         open_mode = 0;
2133         break;
2134       case O_RDWR:
2135         open_mode = 2;
2136         break;
2137       case O_WRONLY:
2138         open_mode = 1;
2139         break;
2140     }
2141
2142     fs_p->share_mode = (deny_mode<<4) | open_mode;
2143
2144     if (Access)
2145       (*Access) = open_mode;
2146
2147     if (action) 
2148     {
2149       if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
2150       if (!file_existed) *action = 2;
2151       if (file_existed && (flags2 & O_TRUNC)) *action = 3;
2152     }
2153     /* We must create the share mode entry before truncate as
2154        truncate can fail due to locking and have to close the
2155        file (which expects the share_mode_entry to be there).
2156      */
2157     if (lp_share_modes(SNUM(cnum)))
2158     {
2159       uint16 port = 0;
2160       /* JRA. Currently this only services Exlcusive and batch
2161          oplocks (no other opens on this file). This needs to
2162          be extended to level II oplocks (multiple reader
2163          oplocks). */
2164
2165       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
2166               !IS_VETO_OPLOCK_PATH(cnum,fname))
2167       {
2168         fs_p->granted_oplock = True;
2169         fs_p->sent_oplock_break = False;
2170         global_oplocks_open++;
2171         port = oplock_port;
2172
2173         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2174 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2175
2176       }
2177       else
2178       {
2179         port = 0;
2180         oplock_request = 0;
2181       }
2182       set_share_mode(token, fnum, port, oplock_request);
2183     }
2184
2185     if ((flags2&O_TRUNC) && file_existed)
2186       truncate_unless_locked(fnum,cnum,token,&share_locked);
2187   }
2188
2189   if (share_locked && lp_share_modes(SNUM(cnum)))
2190     unlock_share_entry( cnum, dev, inode, token);
2191 }
2192
2193 /****************************************************************************
2194 seek a file. Try to avoid the seek if possible
2195 ****************************************************************************/
2196 int seek_file(int fnum,uint32 pos)
2197 {
2198   uint32 offset = 0;
2199   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2200     offset = 3;
2201
2202   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
2203                                   - offset);
2204   return(Files[fnum].pos);
2205 }
2206
2207 /****************************************************************************
2208 read from a file
2209 ****************************************************************************/
2210 int read_file(int fnum,char *data,uint32 pos,int n)
2211 {
2212   int ret=0,readret;
2213
2214 #if USE_READ_PREDICTION
2215   if (!Files[fnum].can_write)
2216     {
2217       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2218
2219       data += ret;
2220       n -= ret;
2221       pos += ret;
2222     }
2223 #endif
2224
2225 #if USE_MMAP
2226   if (Files[fnum].mmap_ptr)
2227     {
2228       int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2229       num = MIN(n,num);
2230       if (num > 0)
2231         {
2232           memcpy(data,Files[fnum].mmap_ptr+pos,num);
2233           data += num;
2234           pos += num;
2235           n -= num;
2236           ret += num;
2237         }
2238     }
2239 #endif
2240
2241   if (n <= 0)
2242     return(ret);
2243
2244   if (seek_file(fnum,pos) != pos)
2245     {
2246       DEBUG(3,("Failed to seek to %d\n",pos));
2247       return(ret);
2248     }
2249   
2250   if (n > 0) {
2251     readret = read(Files[fnum].fd_ptr->fd,data,n);
2252     if (readret > 0) ret += readret;
2253   }
2254
2255   return(ret);
2256 }
2257
2258
2259 /****************************************************************************
2260 write to a file
2261 ****************************************************************************/
2262 int write_file(int fnum,char *data,int n)
2263 {
2264   if (!Files[fnum].can_write) {
2265     errno = EPERM;
2266     return(0);
2267   }
2268
2269   if (!Files[fnum].modified) {
2270     struct stat st;
2271     Files[fnum].modified = True;
2272     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2273       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2274       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {  
2275         dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2276       }
2277     }  
2278   }
2279
2280   return(write_data(Files[fnum].fd_ptr->fd,data,n));
2281 }
2282
2283
2284 /****************************************************************************
2285 load parameters specific to a connection/service
2286 ****************************************************************************/
2287 BOOL become_service(int cnum,BOOL do_chdir)
2288 {
2289   extern char magic_char;
2290   static int last_cnum = -1;
2291   int snum;
2292
2293   if (!OPEN_CNUM(cnum))
2294     {
2295       last_cnum = -1;
2296       return(False);
2297     }
2298
2299   Connections[cnum].lastused = smb_last_time;
2300
2301   snum = SNUM(cnum);
2302   
2303   if (do_chdir &&
2304       ChDir(Connections[cnum].connectpath) != 0 &&
2305       ChDir(Connections[cnum].origpath) != 0)
2306     {
2307       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2308             Connections[cnum].connectpath,cnum));     
2309       return(False);
2310     }
2311
2312   if (cnum == last_cnum)
2313     return(True);
2314
2315   last_cnum = cnum;
2316
2317   case_default = lp_defaultcase(snum);
2318   case_preserve = lp_preservecase(snum);
2319   short_case_preserve = lp_shortpreservecase(snum);
2320   case_mangle = lp_casemangle(snum);
2321   case_sensitive = lp_casesensitive(snum);
2322   magic_char = lp_magicchar(snum);
2323   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2324   return(True);
2325 }
2326
2327
2328 /****************************************************************************
2329   find a service entry
2330 ****************************************************************************/
2331 int find_service(char *service)
2332 {
2333    int iService;
2334
2335    string_sub(service,"\\","/");
2336
2337    iService = lp_servicenumber(service);
2338
2339    /* now handle the special case of a home directory */
2340    if (iService < 0)
2341    {
2342       char *phome_dir = get_home_dir(service);
2343
2344       if(!phome_dir)
2345       {
2346         /*
2347          * Try mapping the servicename, it may
2348          * be a Windows to unix mapped user name.
2349          */
2350         if(map_username(service))
2351           phome_dir = get_home_dir(service);
2352       }
2353
2354       DEBUG(3,("checking for home directory %s gave %s\n",service,
2355             phome_dir?phome_dir:"(NULL)"));
2356
2357       if (phome_dir)
2358       {   
2359         int iHomeService;
2360         if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2361         {
2362           lp_add_home(service,iHomeService,phome_dir);
2363           iService = lp_servicenumber(service);
2364         }
2365       }
2366    }
2367
2368    /* If we still don't have a service, attempt to add it as a printer. */
2369    if (iService < 0)
2370    {
2371       int iPrinterService;
2372
2373       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2374       {
2375          char *pszTemp;
2376
2377          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2378          pszTemp = PRINTCAP;
2379          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2380          {
2381             DEBUG(3,("%s is a valid printer name\n", service));
2382             DEBUG(3,("adding %s as a printer service\n", service));
2383             lp_add_printer(service,iPrinterService);
2384             iService = lp_servicenumber(service);
2385             if (iService < 0)
2386                DEBUG(0,("failed to add %s as a printer service!\n", service));
2387          }
2388          else
2389             DEBUG(3,("%s is not a valid printer name\n", service));
2390       }
2391    }
2392
2393    /* just possibly it's a default service? */
2394    if (iService < 0) 
2395    {
2396      char *pdefservice = lp_defaultservice();
2397      if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2398      {
2399        /*
2400         * We need to do a local copy here as lp_defaultservice() 
2401         * returns one of the rotating lp_string buffers that
2402         * could get overwritten by the recursive find_service() call
2403         * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2404         */
2405        pstring defservice;
2406        pstrcpy(defservice, pdefservice);
2407        iService = find_service(defservice);
2408        if (iService >= 0)
2409        {
2410          string_sub(service,"_","/");
2411          iService = lp_add_service(service,iService);
2412        }
2413      }
2414    }
2415
2416    if (iService >= 0)
2417      if (!VALID_SNUM(iService))
2418      {
2419        DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2420        iService = -1;
2421      }
2422
2423    if (iService < 0)
2424      DEBUG(3,("find_service() failed to find service %s\n", service));
2425
2426    return (iService);
2427 }
2428
2429
2430 /****************************************************************************
2431   create an error packet from a cached error.
2432 ****************************************************************************/
2433 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2434 {
2435   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2436
2437   int32 eclass = wbmpx->wr_errclass;
2438   int32 err = wbmpx->wr_error;
2439
2440   /* We can now delete the auxiliary struct */
2441   free((char *)wbmpx);
2442   Files[fnum].wbmpx_ptr = NULL;
2443   return error_packet(inbuf,outbuf,eclass,err,line);
2444 }
2445
2446
2447 struct
2448 {
2449   int unixerror;
2450   int smbclass;
2451   int smbcode;
2452 } unix_smb_errmap[] =
2453 {
2454   {EPERM,ERRDOS,ERRnoaccess},
2455   {EACCES,ERRDOS,ERRnoaccess},
2456   {ENOENT,ERRDOS,ERRbadfile},
2457   {ENOTDIR,ERRDOS,ERRbadpath},
2458   {EIO,ERRHRD,ERRgeneral},
2459   {EBADF,ERRSRV,ERRsrverror},
2460   {EINVAL,ERRSRV,ERRsrverror},
2461   {EEXIST,ERRDOS,ERRfilexists},
2462   {ENFILE,ERRDOS,ERRnofids},
2463   {EMFILE,ERRDOS,ERRnofids},
2464   {ENOSPC,ERRHRD,ERRdiskfull},
2465 #ifdef EDQUOT
2466   {EDQUOT,ERRHRD,ERRdiskfull},
2467 #endif
2468 #ifdef ENOTEMPTY
2469   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2470 #endif
2471 #ifdef EXDEV
2472   {EXDEV,ERRDOS,ERRdiffdevice},
2473 #endif
2474   {EROFS,ERRHRD,ERRnowrite},
2475   {0,0,0}
2476 };
2477
2478 /****************************************************************************
2479   create an error packet from errno
2480 ****************************************************************************/
2481 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2482 {
2483   int eclass=def_class;
2484   int ecode=def_code;
2485   int i=0;
2486
2487   if (unix_ERR_class != SMB_SUCCESS)
2488     {
2489       eclass = unix_ERR_class;
2490       ecode = unix_ERR_code;
2491       unix_ERR_class = SMB_SUCCESS;
2492       unix_ERR_code = 0;
2493     }
2494   else
2495     {
2496       while (unix_smb_errmap[i].smbclass != 0)
2497       {
2498             if (unix_smb_errmap[i].unixerror == errno)
2499             {
2500               eclass = unix_smb_errmap[i].smbclass;
2501               ecode = unix_smb_errmap[i].smbcode;
2502               break;
2503             }
2504           i++;
2505       }
2506     }
2507
2508   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2509 }
2510
2511
2512 /****************************************************************************
2513   create an error packet. Normally called using the ERROR() macro
2514 ****************************************************************************/
2515 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2516 {
2517   int outsize = set_message(outbuf,0,0,True);
2518   int cmd = CVAL(inbuf,smb_com);
2519   int flgs2 = SVAL(outbuf,smb_flg2); 
2520
2521   if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2522   {
2523     SIVAL(outbuf,smb_rcls,error_code);
2524     
2525     DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2526            timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2527   }
2528   else
2529   {
2530     CVAL(outbuf,smb_rcls) = error_class;
2531     SSVAL(outbuf,smb_err,error_code);  
2532     DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2533            timestring(),
2534            line,
2535            (int)CVAL(inbuf,smb_com),
2536            smb_fn_name(CVAL(inbuf,smb_com)),
2537            error_class,
2538            error_code));
2539
2540   }
2541   
2542   if (errno != 0)
2543     DEBUG(3,("error string = %s\n",strerror(errno)));
2544   
2545   return(outsize);
2546 }
2547
2548
2549 #ifndef SIGCLD_IGNORE
2550 /****************************************************************************
2551 this prevents zombie child processes
2552 ****************************************************************************/
2553 static int sig_cld(void)
2554 {
2555   static int depth = 0;
2556   if (depth != 0)
2557     {
2558       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2559       depth=0;
2560       return(0);
2561     }
2562   depth++;
2563
2564   BlockSignals(True,SIGCLD);
2565   DEBUG(5,("got SIGCLD\n"));
2566
2567 #ifdef USE_WAITPID
2568   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2569 #endif
2570
2571   /* Stop zombies */
2572   /* Stevens, Adv. Unix Prog. says that on system V you must call
2573      wait before reinstalling the signal handler, because the kernel
2574      calls the handler from within the signal-call when there is a
2575      child that has exited. This would lead to an infinite recursion
2576      if done vice versa. */
2577         
2578 #ifndef DONT_REINSTALL_SIG
2579 #ifdef SIGCLD_IGNORE
2580   signal(SIGCLD, SIG_IGN);  
2581 #else
2582   signal(SIGCLD, SIGNAL_CAST sig_cld);
2583 #endif
2584 #endif
2585
2586 #ifndef USE_WAITPID
2587   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2588 #endif
2589   depth--;
2590   BlockSignals(False,SIGCLD);
2591   return 0;
2592 }
2593 #endif
2594
2595 /****************************************************************************
2596   this is called when the client exits abruptly
2597   **************************************************************************/
2598 static int sig_pipe(void)
2599 {
2600         struct cli_state *cli;
2601         BlockSignals(True,SIGPIPE);
2602
2603         if ((cli = server_client()) && cli->initialised) {
2604                 DEBUG(3,("lost connection to password server\n"));
2605                 cli_shutdown(cli);
2606 #ifndef DONT_REINSTALL_SIG
2607                 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2608 #endif
2609                 BlockSignals(False,SIGPIPE);
2610                 return 0;
2611         }
2612
2613         exit_server("Got sigpipe\n");
2614         return(0);
2615 }
2616
2617 /****************************************************************************
2618   open the socket communication
2619 ****************************************************************************/
2620 static BOOL open_sockets(BOOL is_daemon,int port)
2621 {
2622   extern int Client;
2623
2624   if (is_daemon)
2625   {
2626     int num_interfaces = iface_count();
2627     int fd_listenset[FD_SETSIZE];
2628     fd_set listen_set;
2629     int s;
2630     int i;
2631
2632     /* Stop zombies */
2633 #ifdef SIGCLD_IGNORE
2634     signal(SIGCLD, SIG_IGN);
2635 #else
2636     signal(SIGCLD, SIGNAL_CAST sig_cld);
2637 #endif
2638
2639     if(atexit_set == 0)
2640       atexit(killkids);
2641
2642     FD_ZERO(&listen_set);
2643
2644     if(lp_interfaces() && lp_bind_interfaces_only())
2645     {
2646        /* We have been given an interfaces line, and been 
2647           told to only bind to those interfaces. Create a
2648           socket per interface and bind to only these.
2649         */
2650
2651       if(num_interfaces > FD_SETSIZE)
2652       {
2653         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2654 max can be %d\n", num_interfaces, FD_SETSIZE));
2655         return False;
2656       }
2657
2658       /* Now open a listen socket for each of the interfaces. */
2659       for(i = 0; i < num_interfaces; i++)
2660       {
2661         struct in_addr *ifip = iface_n_ip(i);
2662
2663         if(ifip == NULL)
2664         {
2665           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2666           continue;
2667         }
2668         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2669         if(s == -1)
2670           return False;
2671         /* ready to listen */
2672         if (listen(s, 5) == -1) 
2673         {
2674           DEBUG(0,("listen: %s\n",strerror(errno)));
2675           close(s);
2676           return False;
2677         }
2678         FD_SET(s,&listen_set);
2679       }
2680     }
2681     else
2682     {
2683       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2684       num_interfaces = 1;
2685
2686       /* open an incoming socket */
2687       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2688       if (s == -1)
2689         return(False);
2690
2691       /* ready to listen */
2692       if (listen(s, 5) == -1) 
2693       {
2694         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2695         close(s);
2696         return False;
2697       }
2698
2699       fd_listenset[0] = s;
2700       FD_SET(s,&listen_set);
2701     }      
2702
2703     /* now accept incoming connections - forking a new process
2704        for each incoming connection */
2705     DEBUG(2,("waiting for a connection\n"));
2706     while (1)
2707     {
2708       fd_set lfds;
2709       int num;
2710
2711       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2712
2713       num = sys_select(&lfds,NULL);
2714
2715       if (num == -1 && errno == EINTR)
2716         continue;
2717
2718       /* Find the sockets that are read-ready - accept on these. */
2719       for( ; num > 0; num--)
2720       {
2721         struct sockaddr addr;
2722         int in_addrlen = sizeof(addr);
2723
2724         s = -1;
2725         for(i = 0; i < num_interfaces; i++)
2726         {
2727           if(FD_ISSET(fd_listenset[i],&lfds))
2728           {
2729             s = fd_listenset[i];
2730             /* Clear this so we don't look at it again. */
2731             FD_CLR(fd_listenset[i],&lfds);
2732             break;
2733           }
2734         }
2735
2736         Client = accept(s,&addr,&in_addrlen);
2737
2738         if (Client == -1 && errno == EINTR)
2739           continue;
2740
2741         if (Client == -1)
2742         {
2743           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2744           continue;
2745         }
2746
2747 #ifdef NO_FORK_DEBUG
2748 #ifndef NO_SIGNAL_TEST
2749         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2750         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2751 #endif /* NO_SIGNAL_TEST */
2752         return True;
2753 #else /* NO_FORK_DEBUG */
2754         if (Client != -1 && fork()==0)
2755         {
2756           /* Child code ... */
2757
2758 #ifndef NO_SIGNAL_TEST
2759           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2760           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2761 #endif /* NO_SIGNAL_TEST */
2762           /* close the listening socket(s) */
2763           for(i = 0; i < num_interfaces; i++)
2764             close(fd_listenset[i]);
2765
2766           /* close our standard file descriptors */
2767           close_low_fds();
2768           am_parent = 0;
2769   
2770           set_socket_options(Client,"SO_KEEPALIVE");
2771           set_socket_options(Client,user_socket_options);
2772
2773           /* Reset global variables in util.c so that
2774              client substitutions will be done correctly
2775              in the process.
2776            */
2777           reset_globals_after_fork();
2778           return True; 
2779         }
2780         close(Client); /* The parent doesn't need this socket */
2781 #endif /* NO_FORK_DEBUG */
2782       } /* end for num */
2783     } /* end while 1 */
2784   } /* end if is_daemon */
2785   else
2786   {
2787     /* Started from inetd. fd 0 is the socket. */
2788     /* We will abort gracefully when the client or remote system 
2789        goes away */
2790 #ifndef NO_SIGNAL_TEST
2791     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2792 #endif
2793     Client = dup(0);
2794
2795     /* close our standard file descriptors */
2796     close_low_fds();
2797
2798     set_socket_options(Client,"SO_KEEPALIVE");
2799     set_socket_options(Client,user_socket_options);
2800   }
2801
2802   return True;
2803 }
2804
2805 /****************************************************************************
2806   process an smb from the client - split out from the process() code so
2807   it can be used by the oplock break code.
2808 ****************************************************************************/
2809
2810 static void process_smb(char *inbuf, char *outbuf)
2811 {
2812   extern int Client;
2813 #ifdef USE_SSL
2814   extern BOOL sslEnabled;     /* don't use function for performance reasons */
2815   static int sslConnected = 0;
2816 #endif /* USE_SSL */
2817   static int trans_num;
2818   int msg_type = CVAL(inbuf,0);
2819   int32 len = smb_len(inbuf);
2820   int nread = len + 4;
2821
2822   if (trans_num == 0) {
2823           /* on the first packet, check the global hosts allow/ hosts
2824              deny parameters before doing any parsing of the packet
2825              passed to us by the client.  This prevents attacks on our
2826              parsing code from hosts not in the hosts allow list */
2827           if (!check_access(-1)) {
2828                   /* send a negative session response "not listining on calling
2829                    name" */
2830                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2831                   DEBUG(1,("%s Connection denied from %s\n",
2832                            timestring(),client_addr(Client)));
2833                   send_smb(Client,(char *)buf);
2834                   exit_server("connection denied");
2835           }
2836   }
2837
2838   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2839   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2840
2841 #ifdef USE_SSL
2842     if(sslEnabled && !sslConnected){
2843         sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2844         if(sslConnected < 0){   /* an error occured */
2845             exit_server("SSL negotiation failed");
2846         }else if(sslConnected){
2847             trans_num++;
2848             return;
2849         }
2850     }
2851 #endif  /* USE_SSL */
2852
2853 #ifdef WITH_VTP
2854   if(trans_num == 1 && VT_Check(inbuf)) 
2855   {
2856     VT_Process();
2857     return;
2858   }
2859 #endif
2860
2861   if (msg_type == 0)
2862     show_msg(inbuf);
2863   else if(msg_type == 0x85)
2864     return; /* Keepalive packet. */
2865
2866   nread = construct_reply(inbuf,outbuf,nread,max_send);
2867       
2868   if(nread > 0) 
2869   {
2870     if (CVAL(outbuf,0) == 0)
2871       show_msg(outbuf);
2872         
2873     if (nread != smb_len(outbuf) + 4) 
2874     {
2875       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2876                  nread, smb_len(outbuf)));
2877     }
2878     else
2879       send_smb(Client,outbuf);
2880   }
2881   trans_num++;
2882 }
2883
2884 /****************************************************************************
2885   open the oplock IPC socket communication
2886 ****************************************************************************/
2887 static BOOL open_oplock_ipc(void)
2888 {
2889   struct sockaddr_in sock_name;
2890   int len = sizeof(sock_name);
2891
2892   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2893
2894   /* Open a lookback UDP socket on a random port. */
2895   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2896   if (oplock_sock == -1)
2897   {
2898     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2899 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2900     oplock_port = 0;
2901     return(False);
2902   }
2903
2904   /* Find out the transient UDP port we have been allocated. */
2905   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2906   {
2907     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2908             strerror(errno)));
2909     close(oplock_sock);
2910     oplock_sock = -1;
2911     oplock_port = 0;
2912     return False;
2913   }
2914   oplock_port = ntohs(sock_name.sin_port);
2915
2916   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2917             getpid(), oplock_port));
2918
2919   return True;
2920 }
2921
2922 /****************************************************************************
2923   process an oplock break message.
2924 ****************************************************************************/
2925 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2926 {
2927   int32 msg_len;
2928   uint16 from_port;
2929   char *msg_start;
2930
2931   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2932   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2933
2934   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2935
2936   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2937             msg_len, from_port));
2938
2939   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2940      only valid request. */
2941
2942   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2943   {
2944     case OPLOCK_BREAK_CMD:
2945       /* Ensure that the msg length is correct. */
2946       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2947       {
2948         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2949 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2950         return False;
2951       }
2952       {
2953         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2954         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2955         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2956         struct timeval tval;
2957         struct sockaddr_in toaddr;
2958
2959         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2960         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2961
2962         DEBUG(5,("process_local_message: oplock break request from \
2963 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2964
2965         /*
2966          * If we have no record of any currently open oplocks,
2967          * it's not an error, as a close command may have
2968          * just been issued on the file that was oplocked.
2969          * Just return success in this case.
2970          */
2971
2972         if(global_oplocks_open != 0)
2973         {
2974           if(oplock_break(dev, inode, &tval) == False)
2975           {
2976             DEBUG(0,("process_local_message: oplock break failed - \
2977 not returning udp message.\n"));
2978             return False;
2979           }
2980         }
2981         else
2982         {
2983           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2984 oplocks. Returning success.\n"));
2985         }
2986
2987         /* Send the message back after OR'ing in the 'REPLY' bit. */
2988         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2989   
2990         bzero((char *)&toaddr,sizeof(toaddr));
2991         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2992         toaddr.sin_port = htons(from_port);
2993         toaddr.sin_family = AF_INET;
2994
2995         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2996                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2997         {
2998           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2999                     remotepid, strerror(errno)));
3000           return False;
3001         }
3002
3003         DEBUG(5,("process_local_message: oplock break reply sent to \
3004 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
3005                 from_port, dev, inode));
3006
3007       }
3008       break;
3009     /* 
3010      * Keep this as a debug case - eventually we can remove it.
3011      */
3012     case 0x8001:
3013       DEBUG(0,("process_local_message: Received unsolicited break \
3014 reply - dumping info.\n"));
3015
3016       if(msg_len != OPLOCK_BREAK_MSG_LEN)
3017       {
3018         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
3019 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
3020         return False;
3021       }
3022
3023       {
3024         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
3025         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
3026         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
3027
3028         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
3029 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
3030
3031        }
3032        return False;
3033
3034     default:
3035       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
3036                 (unsigned int)SVAL(msg_start,0)));
3037       return False;
3038   }
3039   return True;
3040 }
3041
3042 /****************************************************************************
3043  Process an oplock break directly.
3044 ****************************************************************************/
3045 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
3046 {
3047   extern struct current_user current_user;
3048   extern int Client;
3049   char *inbuf = NULL;
3050   char *outbuf = NULL;
3051   files_struct *fsp = NULL;
3052   int fnum;
3053   time_t start_time;
3054   BOOL shutdown_server = False;
3055   int saved_cnum;
3056   int saved_vuid;
3057   pstring saved_dir; 
3058
3059   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
3060 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
3061
3062   /* We need to search the file open table for the
3063      entry containing this dev and inode, and ensure
3064      we have an oplock on it. */
3065   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
3066   {
3067     if(OPEN_FNUM(fnum))
3068     {
3069       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
3070          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
3071          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
3072               fsp = &Files[fnum];
3073               break;
3074       }
3075     }
3076   }
3077
3078   if(fsp == NULL)
3079   {
3080     /* The file could have been closed in the meantime - return success. */
3081     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
3082 allowing break to succeed.\n", timestring(), dev, inode, fnum));
3083     return True;
3084   }
3085
3086   /* Ensure we have an oplock on the file */
3087
3088   /* There is a potential race condition in that an oplock could
3089      have been broken due to another udp request, and yet there are
3090      still oplock break messages being sent in the udp message
3091      queue for this file. So return true if we don't have an oplock,
3092      as we may have just freed it.
3093    */
3094
3095   if(!fsp->granted_oplock)
3096   {
3097     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));
3098     return True;
3099   }
3100
3101   /* mark the oplock break as sent - we don't want to send twice! */
3102   if (fsp->sent_oplock_break)
3103   {
3104     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));
3105
3106     /* We have to fail the open here as we cannot send another oplock break on this
3107        file whilst we are awaiting a response from the client - neither can we
3108        allow another open to succeed while we are waiting for the client. */
3109     return False;
3110   }
3111
3112   /* Now comes the horrid part. We must send an oplock break to the client,
3113      and then process incoming messages until we get a close or oplock release.
3114      At this point we know we need a new inbuf/outbuf buffer pair.
3115      We cannot use these staticaly as we may recurse into here due to
3116      messages crossing on the wire.
3117    */
3118
3119   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3120   {
3121     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
3122     return False;
3123   }
3124
3125   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3126   {
3127     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
3128     free(inbuf);
3129     inbuf = NULL;
3130     return False;
3131   }
3132
3133   /* Prepare the SMBlockingX message. */
3134   bzero(outbuf,smb_size);
3135   set_message(outbuf,8,0,True);
3136
3137   SCVAL(outbuf,smb_com,SMBlockingX);
3138   SSVAL(outbuf,smb_tid,fsp->cnum);
3139   SSVAL(outbuf,smb_pid,0xFFFF);
3140   SSVAL(outbuf,smb_uid,0);
3141   SSVAL(outbuf,smb_mid,0xFFFF);
3142   SCVAL(outbuf,smb_vwv0,0xFF);
3143   SSVAL(outbuf,smb_vwv2,fnum);
3144   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
3145   /* Change this when we have level II oplocks. */
3146   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
3147  
3148   send_smb(Client, outbuf);
3149
3150   /* Remember we just sent an oplock break on this file. */
3151   fsp->sent_oplock_break = True;
3152
3153   /* We need this in case a readraw crosses on the wire. */
3154   global_oplock_break = True;
3155  
3156   /* Process incoming messages. */
3157
3158   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
3159      seconds we should just die.... */
3160
3161   start_time = time(NULL);
3162
3163   /*
3164    * Save the information we need to re-become the
3165    * user, then unbecome the user whilst we're doing this.
3166    */
3167   saved_cnum = fsp->cnum;
3168   saved_vuid = current_user.vuid;
3169   GetWd(saved_dir);
3170   unbecome_user();
3171
3172   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
3173   {
3174     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
3175     {
3176       /*
3177        * Die if we got an error.
3178        */
3179
3180       if (smb_read_error == READ_EOF)
3181         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
3182  
3183       if (smb_read_error == READ_ERROR)
3184         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
3185                   timestring(), strerror(errno)));
3186
3187       if (smb_read_error == READ_TIMEOUT)
3188         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
3189                   timestring(), OPLOCK_BREAK_TIMEOUT));
3190
3191       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3192 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3193       shutdown_server = True;
3194       break;
3195     }
3196
3197     /*
3198      * There are certain SMB requests that we shouldn't allow
3199      * to recurse. opens, renames and deletes are the obvious
3200      * ones. This is handled in the switch_message() function.
3201      * If global_oplock_break is set they will push the packet onto
3202      * the pending smb queue and return -1 (no reply).
3203      * JRA.
3204      */
3205
3206     process_smb(inbuf, outbuf);
3207
3208     /*
3209      * Die if we go over the time limit.
3210      */
3211
3212     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3213     {
3214       DEBUG(0,("%s oplock_break: no break received from client within \
3215 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3216       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3217 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3218       shutdown_server = True;
3219       break;
3220     }
3221   }
3222
3223   /*
3224    * Go back to being the user who requested the oplock
3225    * break.
3226    */
3227   if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3228   {
3229     DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3230           timestring()));
3231     close_sockets();
3232     close(oplock_sock);
3233     exit_server("unable to re-become user");
3234   }
3235   /* Including the directory. */
3236   ChDir(saved_dir);
3237
3238   /* Free the buffers we've been using to recurse. */
3239   free(inbuf);
3240   free(outbuf);
3241
3242   /* We need this in case a readraw crossed on the wire. */
3243   if(global_oplock_break)
3244     global_oplock_break = False;
3245
3246   /*
3247    * If the client did not respond we must die.
3248    */
3249
3250   if(shutdown_server)
3251   {
3252     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3253           timestring()));
3254     close_sockets();
3255     close(oplock_sock);
3256     exit_server("oplock break failure");
3257   }
3258
3259   if(OPEN_FNUM(fnum))
3260   {
3261     /* The lockingX reply will have removed the oplock flag 
3262        from the sharemode. */
3263     /* Paranoia.... */
3264     fsp->granted_oplock = False;
3265     fsp->sent_oplock_break = False;
3266     global_oplocks_open--;
3267   }
3268
3269   /* Santity check - remove this later. JRA */
3270   if(global_oplocks_open < 0)
3271   {
3272     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3273               global_oplocks_open));
3274     exit_server("oplock_break: global_oplocks_open < 0");
3275   }
3276
3277   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3278 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3279
3280   return True;
3281 }
3282
3283 /****************************************************************************
3284 Send an oplock break message to another smbd process. If the oplock is held 
3285 by the local smbd then call the oplock break function directly.
3286 ****************************************************************************/
3287
3288 BOOL request_oplock_break(share_mode_entry *share_entry, 
3289                           uint32 dev, uint32 inode)
3290 {
3291   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3292   struct sockaddr_in addr_out;
3293   int pid = getpid();
3294   time_t start_time;
3295   int time_left;
3296
3297   if(pid == share_entry->pid)
3298   {
3299     /* We are breaking our own oplock, make sure it's us. */
3300     if(share_entry->op_port != oplock_port)
3301     {
3302       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3303 should be %d\n", pid, share_entry->op_port, oplock_port));
3304       return False;
3305     }
3306
3307     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3308
3309     /* Call oplock break direct. */
3310     return oplock_break(dev, inode, &share_entry->time);
3311   }
3312
3313   /* We need to send a OPLOCK_BREAK_CMD message to the
3314      port in the share mode entry. */
3315
3316   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3317   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3318   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3319   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3320   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3321   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3322
3323   /* set the address and port */
3324   bzero((char *)&addr_out,sizeof(addr_out));
3325   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3326   addr_out.sin_port = htons( share_entry->op_port );
3327   addr_out.sin_family = AF_INET;
3328    
3329   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3330 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3331
3332   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3333          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3334   {
3335     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3336 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3337          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3338          strerror(errno)));
3339     return False;
3340   }
3341
3342   /*
3343    * Now we must await the oplock broken message coming back
3344    * from the target smbd process. Timeout if it fails to
3345    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3346    * While we get messages that aren't ours, loop.
3347    */
3348
3349   start_time = time(NULL);
3350   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3351
3352   while(time_left >= 0)
3353   {
3354     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3355     int32 reply_msg_len;
3356     uint16 reply_from_port;
3357     char *reply_msg_start;
3358
3359     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3360                time_left ? time_left * 1000 : 1) == False)
3361     {
3362       if(smb_read_error == READ_TIMEOUT)
3363       {
3364         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3365 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3366                            share_entry->op_port, dev, inode));
3367         /*
3368          * This is a hack to make handling of failing clients more robust.
3369          * If a oplock break response message is not received in the timeout
3370          * period we may assume that the smbd servicing that client holding
3371          * the oplock has died and the client changes were lost anyway, so
3372          * we should continue to try and open the file.
3373          */
3374         break;
3375       }
3376       else
3377         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3378 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3379                          share_entry->op_port, dev, inode, strerror(errno)));
3380       return False;
3381     }
3382
3383     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3384     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3385
3386     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3387
3388     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3389     {
3390       /* Ignore it. */
3391       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3392              timestring()));
3393       continue;
3394     }
3395
3396     /*
3397      * Test to see if this is the reply we are awaiting.
3398      */
3399
3400     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3401        (reply_from_port == share_entry->op_port) && 
3402        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3403                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3404                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3405     {
3406       /*
3407        * This is the reply we've been waiting for.
3408        */
3409       break;
3410     }
3411     else
3412     {
3413       /*
3414        * This is another message - probably a break request.
3415        * Process it to prevent potential deadlock.
3416        * Note that the code in switch_message() prevents
3417        * us from recursing into here as any SMB requests
3418        * we might process that would cause another oplock
3419        * break request to be made will be queued.
3420        * JRA.
3421        */
3422
3423       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3424     }
3425
3426     time_left -= (time(NULL) - start_time);
3427   }
3428
3429   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3430
3431   return True;
3432 }
3433
3434 /****************************************************************************
3435 Get the next SMB packet, doing the local message processing automatically.
3436 ****************************************************************************/
3437
3438 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3439 {
3440   BOOL got_smb = False;
3441   BOOL ret;
3442
3443   do
3444   {
3445     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3446                                  timeout,&got_smb);
3447
3448     if(ret && !got_smb)
3449     {
3450       /* Deal with oplock break requests from other smbd's. */
3451       process_local_message(oplock_sock, inbuf, bufsize);
3452       continue;
3453     }
3454
3455     if(ret && (CVAL(inbuf,0) == 0x85))
3456     {
3457       /* Keepalive packet. */
3458       got_smb = False;
3459     }
3460
3461   }
3462   while(ret && !got_smb);
3463
3464   return ret;
3465 }
3466
3467 /****************************************************************************
3468 check if a snum is in use
3469 ****************************************************************************/
3470 BOOL snum_used(int snum)
3471 {
3472   int i;
3473   for (i=0;i<MAX_CONNECTIONS;i++)
3474     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3475       return(True);
3476   return(False);
3477 }
3478
3479 /****************************************************************************
3480   reload the services file
3481   **************************************************************************/
3482 BOOL reload_services(BOOL test)
3483 {
3484   BOOL ret;
3485
3486   if (lp_loaded())
3487   {
3488     pstring fname;
3489     pstrcpy(fname,lp_configfile());
3490     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3491     {
3492       pstrcpy(servicesf,fname);
3493       test = False;
3494     }
3495   }
3496
3497   reopen_logs();
3498
3499   if (test && !lp_file_list_changed())
3500     return(True);
3501
3502   lp_killunused(snum_used);
3503
3504   ret = lp_load(servicesf,False,False,True);
3505
3506   /* perhaps the config filename is now set */
3507   if (!test)
3508     reload_services(True);
3509
3510   reopen_logs();
3511
3512   load_interfaces();
3513
3514   {
3515     extern int Client;
3516     if (Client != -1) {      
3517       set_socket_options(Client,"SO_KEEPALIVE");
3518       set_socket_options(Client,user_socket_options);
3519     }
3520   }
3521
3522   reset_mangled_cache();
3523
3524   /* this forces service parameters to be flushed */
3525   become_service(-1,True);
3526
3527   return(ret);
3528 }
3529
3530
3531
3532 /****************************************************************************
3533 this prevents zombie child processes
3534 ****************************************************************************/
3535 static BOOL reload_after_sighup = False;
3536
3537 static int sig_hup(void)
3538 {
3539   BlockSignals(True,SIGHUP);
3540   DEBUG(0,("Got SIGHUP\n"));
3541
3542   /*
3543    * Fix from <branko.cibej@hermes.si> here.
3544    * We used to reload in the signal handler - this
3545    * is a *BIG* no-no.
3546    */
3547
3548   reload_after_sighup = True;
3549 #ifndef DONT_REINSTALL_SIG
3550   signal(SIGHUP,SIGNAL_CAST sig_hup);
3551 #endif
3552   BlockSignals(False,SIGHUP);
3553   return(0);
3554 }
3555
3556
3557 /****************************************************************************
3558   make a connection to a service
3559 ****************************************************************************/
3560 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3561 {
3562   int cnum;
3563   int snum;
3564   struct passwd *pass = NULL;
3565   connection_struct *pcon;
3566   BOOL guest = False;
3567   BOOL force = False;
3568
3569   strlower(service);
3570
3571   snum = find_service(service);
3572   if (snum < 0)
3573     {
3574       extern int Client;
3575       if (strequal(service,"IPC$"))
3576         {         
3577           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3578           return(-3);
3579         }
3580
3581       DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));      
3582       return(-2);
3583     }
3584
3585   if (strequal(service,HOMES_NAME))
3586     {
3587       if (*user && Get_Pwnam(user,True))
3588         return(make_connection(user,user,password,pwlen,dev,vuid));
3589
3590       if(lp_security() != SEC_SHARE)
3591       {
3592         if (validated_username(vuid))
3593         {
3594           pstrcpy(user,validated_username(vuid));
3595           return(make_connection(user,user,password,pwlen,dev,vuid));
3596         }
3597       }
3598       else
3599       {
3600         /*
3601          * Security = share. Try with sesssetup_user as the username.
3602          */
3603         if(*sesssetup_user)
3604         {
3605           pstrcpy(user,sesssetup_user);
3606           return(make_connection(user,user,password,pwlen,dev,vuid));
3607         }
3608       }
3609     }
3610
3611   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3612     return(-4);
3613   }
3614
3615   /* you can only connect to the IPC$ service as an ipc device */
3616   if (strequal(service,"IPC$"))
3617     pstrcpy(dev,"IPC");
3618
3619   if (*dev == '?' || !*dev)
3620     {
3621       if (lp_print_ok(snum))
3622         pstrcpy(dev,"LPT1:");
3623       else
3624         pstrcpy(dev,"A:");
3625     }
3626
3627   /* if the request is as a printer and you can't print then refuse */
3628   strupper(dev);
3629   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3630     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3631     return(-6);
3632   }
3633
3634   /* lowercase the user name */
3635   strlower(user);
3636
3637   /* add it as a possible user name */
3638   add_session_user(service);
3639
3640   /* shall we let them in? */
3641   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3642     {
3643       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3644       return(-1);
3645     }
3646   
3647   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3648   if (cnum < 0)
3649     {
3650       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3651       return(-1);
3652     }
3653
3654   pcon = &Connections[cnum];
3655   bzero((char *)pcon,sizeof(*pcon));
3656
3657   /* find out some info about the user */
3658   pass = Get_Pwnam(user,True);
3659
3660   if (pass == NULL)
3661     {
3662       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3663       return(-7);
3664     }
3665
3666   pcon->read_only = lp_readonly(snum);
3667
3668   {
3669     pstring list;
3670     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3671     string_sub(list,"%S",service);
3672
3673     if (user_in_list(user,list))
3674       pcon->read_only = True;
3675
3676     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3677     string_sub(list,"%S",service);
3678
3679     if (user_in_list(user,list))
3680       pcon->read_only = False;    
3681   }
3682
3683   /* admin user check */
3684
3685   /* JRA - original code denied admin user if the share was
3686      marked read_only. Changed as I don't think this is needed,
3687      but old code left in case there is a problem here.
3688    */
3689   if (user_in_list(user,lp_admin_users(snum)) 
3690 #if 0
3691       && !pcon->read_only)
3692 #else
3693       )
3694 #endif
3695     {
3696       pcon->admin_user = True;
3697       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3698     }
3699   else
3700     pcon->admin_user = False;
3701     
3702   pcon->force_user = force;
3703   pcon->vuid = vuid;
3704   pcon->uid = pass->pw_uid;
3705   pcon->gid = pass->pw_gid;
3706   pcon->num_files_open = 0;
3707   pcon->lastused = time(NULL);
3708   pcon->service = snum;
3709   pcon->used = True;
3710   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3711   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3712   pcon->dirptr = NULL;
3713   pcon->veto_list = NULL;
3714   pcon->hide_list = NULL;
3715   pcon->veto_oplock_list = NULL;
3716   string_set(&pcon->dirpath,"");
3717   string_set(&pcon->user,user);
3718
3719 #if HAVE_GETGRNAM 
3720   if (*lp_force_group(snum))
3721     {
3722       struct group *gptr;
3723       pstring gname;
3724
3725       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3726       /* default service may be a group name            */
3727       string_sub(gname,"%S",service);
3728       gptr = (struct group *)getgrnam(gname);
3729
3730       if (gptr)
3731         {
3732           pcon->gid = gptr->gr_gid;
3733           DEBUG(3,("Forced group %s\n",gname));
3734         }
3735       else
3736         DEBUG(1,("Couldn't find group %s\n",gname));
3737     }
3738 #endif
3739
3740   if (*lp_force_user(snum))
3741     {
3742       struct passwd *pass2;
3743       fstring fuser;
3744       fstrcpy(fuser,lp_force_user(snum));
3745       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3746       if (pass2)
3747         {
3748           pcon->uid = pass2->pw_uid;
3749           string_set(&pcon->user,fuser);
3750           fstrcpy(user,fuser);
3751           pcon->force_user = True;
3752           DEBUG(3,("Forced user %s\n",fuser));    
3753         }
3754       else
3755         DEBUG(1,("Couldn't find user %s\n",fuser));
3756     }
3757
3758   {
3759     pstring s;
3760     pstrcpy(s,lp_pathname(snum));
3761     standard_sub(cnum,s);
3762     string_set(&pcon->connectpath,s);
3763     DEBUG(3,("Connect path is %s\n",s));
3764   }
3765
3766   /* groups stuff added by ih */
3767   pcon->ngroups = 0;
3768   pcon->igroups = NULL;
3769   pcon->groups = NULL;
3770   pcon->attrs = NULL;
3771
3772   if (!IS_IPC(cnum))
3773     {
3774       /* Find all the groups this uid is in and store them. Used by become_user() */
3775       setup_groups(pcon->user,pcon->uid,pcon->gid,
3776                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3777       
3778       /* check number of connections */
3779       if (!claim_connection(cnum,
3780                             lp_servicename(SNUM(cnum)),
3781                             lp_max_connections(SNUM(cnum)),False))
3782         {
3783           DEBUG(1,("too many connections - rejected\n"));
3784           return(-8);
3785         }  
3786
3787       if (lp_status(SNUM(cnum)))
3788         claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3789     } /* IS_IPC */
3790
3791   pcon->open = True;
3792
3793   /* execute any "root preexec = " line */
3794   if (*lp_rootpreexec(SNUM(cnum)))
3795     {
3796       pstring cmd;
3797       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3798       standard_sub(cnum,cmd);
3799       DEBUG(5,("cmd=%s\n",cmd));
3800       smbrun(cmd,NULL,False);
3801     }
3802
3803   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3804     {
3805       DEBUG(0,("Can't become connected user!\n"));
3806       pcon->open = False;
3807       if (!IS_IPC(cnum)) {
3808         yield_connection(cnum,
3809                          lp_servicename(SNUM(cnum)),
3810                          lp_max_connections(SNUM(cnum)));
3811         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3812       }
3813       return(-1);
3814     }
3815
3816   if (ChDir(pcon->connectpath) != 0)
3817     {
3818       DEBUG(0,("Can't change directory to %s (%s)\n",
3819                pcon->connectpath,strerror(errno)));
3820       pcon->open = False;
3821       unbecome_user();
3822       if (!IS_IPC(cnum)) {
3823         yield_connection(cnum,
3824                          lp_servicename(SNUM(cnum)),
3825                          lp_max_connections(SNUM(cnum)));
3826         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3827       }
3828       return(-5);      
3829     }
3830
3831   string_set(&pcon->origpath,pcon->connectpath);
3832
3833 #if SOFTLINK_OPTIMISATION
3834   /* resolve any soft links early */
3835   {
3836     pstring s;
3837     pstrcpy(s,pcon->connectpath);
3838     GetWd(s);
3839     string_set(&pcon->connectpath,s);
3840     ChDir(pcon->connectpath);
3841   }
3842 #endif
3843
3844   num_connections_open++;
3845   add_session_user(user);
3846   
3847   /* execute any "preexec = " line */
3848   if (*lp_preexec(SNUM(cnum)))
3849     {
3850       pstring cmd;
3851       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3852       standard_sub(cnum,cmd);
3853       smbrun(cmd,NULL,False);
3854     }
3855   
3856   /* we've finished with the sensitive stuff */
3857   unbecome_user();
3858
3859   /* Add veto/hide lists */
3860   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3861   {
3862     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3863     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3864     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3865   }
3866
3867   {
3868     extern int Client;
3869     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3870                             timestring(),
3871                             remote_machine,
3872                             client_addr(Client),
3873                             lp_servicename(SNUM(cnum)),user,
3874                             pcon->uid,
3875                             pcon->gid,
3876                             (int)getpid()));
3877   }
3878
3879   return(cnum);
3880 }
3881
3882 /****************************************************************************
3883   Attempt to break an oplock on a file (if oplocked).
3884   Returns True if the file was closed as a result of
3885   the oplock break, False otherwise.
3886   Used as a last ditch attempt to free a space in the 
3887   file table when we have run out.
3888 ****************************************************************************/
3889
3890 static BOOL attempt_close_oplocked_file(files_struct *fp)
3891 {
3892
3893   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3894
3895   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3896
3897     /* Try and break the oplock. */
3898     file_fd_struct *fsp = fp->fd_ptr;
3899     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3900       if(!fp->open) /* Did the oplock break close the file ? */
3901         return True;
3902     }
3903   }
3904
3905   return False;
3906 }
3907
3908 /****************************************************************************
3909   find first available file slot
3910 ****************************************************************************/
3911 int find_free_file(void )
3912 {
3913         int i;
3914         static int first_file;
3915
3916         /* we want to give out file handles differently on each new
3917            connection because of a common bug in MS clients where they try to
3918            reuse a file descriptor from an earlier smb connection. This code
3919            increases the chance that the errant client will get an error rather
3920            than causing corruption */
3921         if (first_file == 0) {
3922                 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3923                 if (first_file == 0) first_file = 1;
3924         }
3925
3926         if (first_file >= MAX_OPEN_FILES)
3927                 first_file = 1;
3928
3929         for (i=first_file;i<MAX_OPEN_FILES;i++)
3930                 if (!Files[i].open && !Files[i].reserved) {
3931                         memset(&Files[i], 0, sizeof(Files[i]));
3932                         first_file = i+1;
3933                         Files[i].reserved = True;
3934                         return(i);
3935                 }
3936
3937         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3938         for (i=1;i<first_file;i++)
3939                 if (!Files[i].open && !Files[i].reserved) {
3940                         memset(&Files[i], 0, sizeof(Files[i]));
3941                         first_file = i+1;
3942                         Files[i].reserved = True;
3943                         return(i);
3944                 }
3945
3946         /* 
3947          * Before we give up, go through the open files 
3948          * and see if there are any files opened with a
3949          * batch oplock. If so break the oplock and then
3950          * re-use that entry (if it becomes closed).
3951          * This may help as NT/95 clients tend to keep
3952          * files batch oplocked for quite a long time
3953          * after they have finished with them.
3954          */
3955         for (i=first_file;i<MAX_OPEN_FILES;i++) {
3956           if(attempt_close_oplocked_file( &Files[i])) {
3957             memset(&Files[i], 0, sizeof(Files[i]));
3958             first_file = i+1;
3959             Files[i].reserved = True;
3960             return(i);
3961           }
3962         }
3963
3964         for (i=1;i<MAX_OPEN_FILES;i++) {
3965           if(attempt_close_oplocked_file( &Files[i])) {
3966             memset(&Files[i], 0, sizeof(Files[i]));
3967             first_file = i+1;
3968             Files[i].reserved = True;
3969             return(i);
3970           }
3971         }
3972
3973         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3974         return(-1);
3975 }
3976
3977 /****************************************************************************
3978   find first available connection slot, starting from a random position.
3979 The randomisation stops problems with the server dieing and clients
3980 thinking the server is still available.
3981 ****************************************************************************/
3982 static int find_free_connection(int hash )
3983 {
3984   int i;
3985   BOOL used=False;
3986   hash = (hash % (MAX_CONNECTIONS-2))+1;
3987
3988  again:
3989
3990   for (i=hash+1;i!=hash;)
3991     {
3992       if (!Connections[i].open && Connections[i].used == used) 
3993         {
3994           DEBUG(3,("found free connection number %d\n",i));
3995           return(i);
3996         }
3997       i++;
3998       if (i == MAX_CONNECTIONS)
3999         i = 1;
4000     }
4001
4002   if (!used)
4003     {
4004       used = !used;
4005       goto again;
4006     }
4007
4008   DEBUG(1,("ERROR! Out of connection structures\n"));
4009   return(-1);
4010 }
4011
4012
4013 /****************************************************************************
4014 reply for the core protocol
4015 ****************************************************************************/
4016 int reply_corep(char *outbuf)
4017 {
4018   int outsize = set_message(outbuf,1,0,True);
4019
4020   Protocol = PROTOCOL_CORE;
4021
4022   return outsize;
4023 }
4024
4025
4026 /****************************************************************************
4027 reply for the coreplus protocol
4028 ****************************************************************************/
4029 int reply_coreplus(char *outbuf)
4030 {
4031   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4032   int outsize = set_message(outbuf,13,0,True);
4033   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
4034                                  readbraw and writebraw (possibly) */
4035   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4036   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
4037
4038   Protocol = PROTOCOL_COREPLUS;
4039
4040   return outsize;
4041 }
4042
4043
4044 /****************************************************************************
4045 reply for the lanman 1.0 protocol
4046 ****************************************************************************/
4047 int reply_lanman1(char *outbuf)
4048 {
4049   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4050   int secword=0;
4051   BOOL doencrypt = SMBENCRYPT();
4052   time_t t = time(NULL);
4053
4054   if (lp_security()>=SEC_USER) secword |= 1;
4055   if (doencrypt) secword |= 2;
4056
4057   set_message(outbuf,13,doencrypt?8:0,True);
4058   SSVAL(outbuf,smb_vwv1,secword); 
4059   /* Create a token value and add it to the outgoing packet. */
4060   if (doencrypt) 
4061     generate_next_challenge(smb_buf(outbuf));
4062
4063   Protocol = PROTOCOL_LANMAN1;
4064
4065   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4066   SSVAL(outbuf,smb_vwv2,max_recv);
4067   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
4068   SSVAL(outbuf,smb_vwv4,1);
4069   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
4070                                  readbraw writebraw (possibly) */
4071   SIVAL(outbuf,smb_vwv6,getpid());
4072   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4073
4074   put_dos_date(outbuf,smb_vwv8,t);
4075
4076   return (smb_len(outbuf)+4);
4077 }
4078
4079
4080 /****************************************************************************
4081 reply for the lanman 2.0 protocol
4082 ****************************************************************************/
4083 int reply_lanman2(char *outbuf)
4084 {
4085   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4086   int secword=0;
4087   BOOL doencrypt = SMBENCRYPT();
4088   time_t t = time(NULL);
4089   struct cli_state *cli = NULL;
4090   char cryptkey[8];
4091   char crypt_len = 0;
4092
4093   if (lp_security() == SEC_SERVER) {
4094           cli = server_cryptkey();
4095   }
4096
4097   if (cli) {
4098           DEBUG(3,("using password server validation\n"));
4099           doencrypt = ((cli->sec_mode & 2) != 0);
4100   }
4101
4102   if (lp_security()>=SEC_USER) secword |= 1;
4103   if (doencrypt) secword |= 2;
4104
4105   if (doencrypt) {
4106           crypt_len = 8;
4107           if (!cli) {
4108                   generate_next_challenge(cryptkey);
4109           } else {
4110                   memcpy(cryptkey, cli->cryptkey, 8);
4111                   set_challenge(cli->cryptkey);
4112           }
4113   }
4114
4115   set_message(outbuf,13,crypt_len,True);
4116   SSVAL(outbuf,smb_vwv1,secword); 
4117   SIVAL(outbuf,smb_vwv6,getpid());
4118   if (doencrypt) 
4119           memcpy(smb_buf(outbuf), cryptkey, 8);
4120
4121   Protocol = PROTOCOL_LANMAN2;
4122
4123   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4124   SSVAL(outbuf,smb_vwv2,max_recv);
4125   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
4126   SSVAL(outbuf,smb_vwv4,1);
4127   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
4128   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4129   put_dos_date(outbuf,smb_vwv8,t);
4130
4131   return (smb_len(outbuf)+4);
4132 }
4133
4134
4135 /****************************************************************************
4136 reply for the nt protocol
4137 ****************************************************************************/
4138 int reply_nt1(char *outbuf)
4139 {
4140   /* dual names + lock_and_read + nt SMBs + remote API calls */
4141   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
4142 /*
4143   other valid capabilities which we may support at some time...
4144                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
4145                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
4146  */
4147
4148   int secword=0;
4149   BOOL doencrypt = SMBENCRYPT();
4150   time_t t = time(NULL);
4151   int data_len;
4152   struct cli_state *cli = NULL;
4153   char cryptkey[8];
4154   char crypt_len = 0;
4155
4156   if (lp_security() == SEC_SERVER) {
4157           cli = server_cryptkey();
4158   }
4159
4160   if (cli) {
4161           DEBUG(3,("using password server validation\n"));
4162           doencrypt = ((cli->sec_mode & 2) != 0);
4163   }
4164
4165   if (doencrypt) {
4166           crypt_len = 8;
4167           if (!cli) {
4168                   generate_next_challenge(cryptkey);
4169           } else {
4170                   memcpy(cryptkey, cli->cryptkey, 8);
4171                   set_challenge(cli->cryptkey);
4172           }
4173   }
4174
4175   if (lp_readraw() && lp_writeraw()) {
4176           capabilities |= CAP_RAW_MODE;
4177   }
4178
4179   if (lp_security() >= SEC_USER) secword |= 1;
4180   if (doencrypt) secword |= 2;
4181
4182   /* decide where (if) to put the encryption challenge, and
4183      follow it with the OEM'd domain name
4184    */
4185   data_len = crypt_len + strlen(global_myworkgroup) + 1;
4186
4187   set_message(outbuf,17,data_len,True);
4188   pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
4189
4190   CVAL(outbuf,smb_vwv1) = secword;
4191   SSVALS(outbuf,smb_vwv16+1,crypt_len);
4192   if (doencrypt) 
4193           memcpy(smb_buf(outbuf), cryptkey, 8);
4194
4195   Protocol = PROTOCOL_NT1;
4196
4197   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4198   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4199   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4200   SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4201   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4202   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4203   put_long_date(outbuf+smb_vwv11+1,t);
4204   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4205   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4206
4207   return (smb_len(outbuf)+4);
4208 }
4209
4210 /* these are the protocol lists used for auto architecture detection:
4211
4212 WinNT 3.51:
4213 protocol [PC NETWORK PROGRAM 1.0]
4214 protocol [XENIX CORE]
4215 protocol [MICROSOFT NETWORKS 1.03]
4216 protocol [LANMAN1.0]
4217 protocol [Windows for Workgroups 3.1a]
4218 protocol [LM1.2X002]
4219 protocol [LANMAN2.1]
4220 protocol [NT LM 0.12]
4221
4222 Win95:
4223 protocol [PC NETWORK PROGRAM 1.0]
4224 protocol [XENIX CORE]
4225 protocol [MICROSOFT NETWORKS 1.03]
4226 protocol [LANMAN1.0]
4227 protocol [Windows for Workgroups 3.1a]
4228 protocol [LM1.2X002]
4229 protocol [LANMAN2.1]
4230 protocol [NT LM 0.12]
4231
4232 OS/2:
4233 protocol [PC NETWORK PROGRAM 1.0]
4234 protocol [XENIX CORE]
4235 protocol [LANMAN1.0]
4236 protocol [LM1.2X002]
4237 protocol [LANMAN2.1]
4238 */
4239
4240 /*
4241   * Modified to recognize the architecture of the remote machine better.
4242   *
4243   * This appears to be the matrix of which protocol is used by which
4244   * MS product.
4245        Protocol                       WfWg    Win95   WinNT  OS/2
4246        PC NETWORK PROGRAM 1.0          1       1       1      1
4247        XENIX CORE                                      2      2
4248        MICROSOFT NETWORKS 3.0          2       2       
4249        DOS LM1.2X002                   3       3       
4250        MICROSOFT NETWORKS 1.03                         3
4251        DOS LANMAN2.1                   4       4       
4252        LANMAN1.0                                       4      3
4253        Windows for Workgroups 3.1a     5       5       5
4254        LM1.2X002                                       6      4
4255        LANMAN2.1                                       7      5
4256        NT LM 0.12                              6       8
4257   *
4258   *  tim@fsg.com 09/29/95
4259   */
4260   
4261 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4262 #define ARCH_WIN95    0x2
4263 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4264 #define ARCH_WINNT    0x8
4265 #define ARCH_SAMBA    0x10
4266  
4267 #define ARCH_ALL      0x1F
4268  
4269 /* List of supported protocols, most desired first */
4270 struct {
4271   char *proto_name;
4272   char *short_name;
4273   int (*proto_reply_fn)(char *);
4274   int protocol_level;
4275 } supported_protocols[] = {
4276   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4277   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4278   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4279   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4280   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4281   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4282   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4283   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4284   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4285   {NULL,NULL},
4286 };
4287
4288
4289 /****************************************************************************
4290   reply to a negprot
4291 ****************************************************************************/
4292 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4293 {
4294   int outsize = set_message(outbuf,1,0,True);
4295   int Index=0;
4296   int choice= -1;
4297   int protocol;
4298   char *p;
4299   int bcc = SVAL(smb_buf(inbuf),-2);
4300   int arch = ARCH_ALL;
4301
4302   p = smb_buf(inbuf)+1;
4303   while (p < (smb_buf(inbuf) + bcc))
4304     { 
4305       Index++;
4306       DEBUG(3,("Requested protocol [%s]\n",p));
4307       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4308         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4309       else if (strcsequal(p,"DOS LM1.2X002"))
4310         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4311       else if (strcsequal(p,"DOS LANMAN2.1"))
4312         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4313       else if (strcsequal(p,"NT LM 0.12"))
4314         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4315       else if (strcsequal(p,"LANMAN2.1"))
4316         arch &= ( ARCH_WINNT | ARCH_OS2 );
4317       else if (strcsequal(p,"LM1.2X002"))
4318         arch &= ( ARCH_WINNT | ARCH_OS2 );
4319       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4320         arch &= ARCH_WINNT;
4321       else if (strcsequal(p,"XENIX CORE"))
4322         arch &= ( ARCH_WINNT | ARCH_OS2 );
4323       else if (strcsequal(p,"Samba")) {
4324         arch = ARCH_SAMBA;
4325         break;
4326       }
4327  
4328       p += strlen(p) + 2;
4329     }
4330     
4331   switch ( arch ) {
4332   case ARCH_SAMBA:
4333     set_remote_arch(RA_SAMBA);
4334     break;
4335   case ARCH_WFWG:
4336     set_remote_arch(RA_WFWG);
4337     break;
4338   case ARCH_WIN95:
4339     set_remote_arch(RA_WIN95);
4340     break;
4341   case ARCH_WINNT:
4342     set_remote_arch(RA_WINNT);
4343     break;
4344   case ARCH_OS2:
4345     set_remote_arch(RA_OS2);
4346     break;
4347   default:
4348     set_remote_arch(RA_UNKNOWN);
4349     break;
4350   }
4351  
4352   /* possibly reload - change of architecture */
4353   reload_services(True);      
4354     
4355   /* a special case to stop password server loops */
4356   if (Index == 1 && strequal(remote_machine,myhostname) && 
4357       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4358     exit_server("Password server loop!");
4359   
4360   /* Check for protocols, most desirable first */
4361   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4362     {
4363       p = smb_buf(inbuf)+1;
4364       Index = 0;
4365       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4366         while (p < (smb_buf(inbuf) + bcc))
4367           { 
4368             if (strequal(p,supported_protocols[protocol].proto_name))
4369               choice = Index;
4370             Index++;
4371             p += strlen(p) + 2;
4372           }
4373       if(choice != -1)
4374         break;
4375     }
4376   
4377   SSVAL(outbuf,smb_vwv0,choice);
4378   if(choice != -1) {
4379     extern fstring remote_proto;
4380     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4381     reload_services(True);          
4382     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4383     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4384   }
4385   else {
4386     DEBUG(0,("No protocol supported !\n"));
4387   }
4388   SSVAL(outbuf,smb_vwv0,choice);
4389   
4390   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4391
4392   return(outsize);
4393 }
4394
4395
4396 /****************************************************************************
4397 close all open files for a connection
4398 ****************************************************************************/
4399 static void close_open_files(int cnum)
4400 {
4401   int i;
4402   for (i=0;i<MAX_OPEN_FILES;i++)
4403     if( Files[i].cnum == cnum && Files[i].open) {
4404       close_file(i,False);
4405     }
4406 }
4407
4408
4409
4410 /****************************************************************************
4411 close a cnum
4412 ****************************************************************************/
4413 void close_cnum(int cnum, uint16 vuid)
4414 {
4415   extern int Client;
4416   DirCacheFlush(SNUM(cnum));
4417
4418   unbecome_user();
4419
4420   if (!OPEN_CNUM(cnum))
4421     {
4422       DEBUG(0,("Can't close cnum %d\n",cnum));
4423       return;
4424     }
4425
4426   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4427                           timestring(),
4428                           remote_machine,client_addr(Client),
4429                           lp_servicename(SNUM(cnum))));
4430
4431   yield_connection(cnum,
4432                    lp_servicename(SNUM(cnum)),
4433                    lp_max_connections(SNUM(cnum)));
4434
4435   if (lp_status(SNUM(cnum)))
4436     yield_connection(cnum,"STATUS.",MAXSTATUS);
4437
4438   close_open_files(cnum);
4439   dptr_closecnum(cnum);
4440
4441   /* execute any "postexec = " line */
4442   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4443     {
4444       pstring cmd;
4445       pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4446       standard_sub(cnum,cmd);
4447       smbrun(cmd,NULL,False);
4448       unbecome_user();
4449     }
4450
4451   unbecome_user();
4452   /* execute any "root postexec = " line */
4453   if (*lp_rootpostexec(SNUM(cnum)))
4454     {
4455       pstring cmd;
4456       pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4457       standard_sub(cnum,cmd);
4458       smbrun(cmd,NULL,False);
4459     }
4460
4461   Connections[cnum].open = False;
4462   num_connections_open--;
4463   if (Connections[cnum].ngroups && Connections[cnum].groups)
4464     {
4465       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4466         free(Connections[cnum].groups);
4467       free(Connections[cnum].igroups);
4468       Connections[cnum].groups = NULL;
4469       Connections[cnum].igroups = NULL;
4470       Connections[cnum].ngroups = 0;
4471     }
4472
4473   free_namearray(Connections[cnum].veto_list);
4474   free_namearray(Connections[cnum].hide_list);
4475   free_namearray(Connections[cnum].veto_oplock_list);
4476
4477   string_set(&Connections[cnum].user,"");
4478   string_set(&Connections[cnum].dirpath,"");
4479   string_set(&Connections[cnum].connectpath,"");
4480 }
4481
4482
4483
4484 #if DUMP_CORE
4485 /*******************************************************************
4486 prepare to dump a core file - carefully!
4487 ********************************************************************/
4488 static BOOL dump_core(void)
4489 {
4490   char *p;
4491   pstring dname;
4492   pstrcpy(dname,debugf);
4493   if ((p=strrchr(dname,'/'))) *p=0;
4494   pstrcat(dname,"/corefiles");
4495   mkdir(dname,0700);
4496   sys_chown(dname,getuid(),getgid());
4497   chmod(dname,0700);
4498   if (chdir(dname)) return(False);
4499   umask(~(0700));
4500
4501 #ifndef NO_GETRLIMIT
4502 #ifdef RLIMIT_CORE
4503   {
4504     struct rlimit rlp;
4505     getrlimit(RLIMIT_CORE, &rlp);
4506     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4507     setrlimit(RLIMIT_CORE, &rlp);
4508     getrlimit(RLIMIT_CORE, &rlp);
4509     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4510   }
4511 #endif
4512 #endif
4513
4514
4515   DEBUG(0,("Dumping core in %s\n",dname));
4516   return(True);
4517 }
4518 #endif
4519
4520 /****************************************************************************
4521 exit the server
4522 ****************************************************************************/
4523 void exit_server(char *reason)
4524 {
4525   static int firsttime=1;
4526   int i;
4527
4528   if (!firsttime) exit(0);
4529   firsttime = 0;
4530
4531   unbecome_user();
4532   DEBUG(2,("Closing connections\n"));
4533   for (i=0;i<MAX_CONNECTIONS;i++)
4534     if (Connections[i].open)
4535       close_cnum(i,(uint16)-1);
4536 #ifdef DFS_AUTH
4537   if (dcelogin_atmost_once)
4538     dfs_unlogin();
4539 #endif
4540   if (!reason) {   
4541     int oldlevel = DEBUGLEVEL;
4542     DEBUGLEVEL = 10;
4543     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4544     if (last_inbuf)
4545       show_msg(last_inbuf);
4546     DEBUGLEVEL = oldlevel;
4547     DEBUG(0,("===============================================================\n"));
4548 #if DUMP_CORE
4549     if (dump_core()) return;
4550 #endif
4551   }    
4552
4553   locking_end();
4554
4555   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4556   exit(0);
4557 }
4558
4559 /****************************************************************************
4560 do some standard substitutions in a string
4561 ****************************************************************************/
4562 void standard_sub(int cnum,char *str)
4563 {
4564   if (VALID_CNUM(cnum)) {
4565     char *p, *s, *home;
4566
4567     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4568       switch (*(p+1)) {
4569         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4570                      string_sub(p,"%H",home);
4571                    else
4572                      p += 2;
4573                    break;
4574         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4575         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4576         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4577         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4578         /* 
4579          * Patch from jkf@soton.ac.uk
4580          * Left the %N (NIS server name) in standard_sub_basic as it
4581          * is a feature for logon servers, hence uses the username.
4582          * The %p (NIS server path) code is here as it is used
4583          * instead of the default "path =" string in [homes] and so
4584          * needs the service name, not the username. 
4585          */
4586         case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4587         case '\0' : p++; break; /* don't run off the end of the string */
4588         default  : p+=2; break;
4589       }
4590     }
4591   }
4592   standard_sub_basic(str);
4593 }
4594
4595 /*
4596 These flags determine some of the permissions required to do an operation 
4597
4598 Note that I don't set NEED_WRITE on some write operations because they
4599 are used by some brain-dead clients when printing, and I don't want to
4600 force write permissions on print services.
4601 */
4602 #define AS_USER (1<<0)
4603 #define NEED_WRITE (1<<1)
4604 #define TIME_INIT (1<<2)
4605 #define CAN_IPC (1<<3)
4606 #define AS_GUEST (1<<5)
4607 #define QUEUE_IN_OPLOCK (1<<6)
4608
4609 /* 
4610    define a list of possible SMB messages and their corresponding
4611    functions. Any message that has a NULL function is unimplemented -
4612    please feel free to contribute implementations!
4613 */
4614 struct smb_message_struct
4615 {
4616   int code;
4617   char *name;
4618   int (*fn)(char *, char *, int, int);
4619   int flags;
4620 #if PROFILING
4621   unsigned long time;
4622 #endif
4623 }
4624  smb_messages[] = {
4625
4626     /* CORE PROTOCOL */
4627
4628    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4629    {SMBtcon,"SMBtcon",reply_tcon,0},
4630    {SMBtdis,"SMBtdis",reply_tdis,0},
4631    {SMBexit,"SMBexit",reply_exit,0},
4632    {SMBioctl,"SMBioctl",reply_ioctl,0},
4633    {SMBecho,"SMBecho",reply_echo,0},
4634    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4635    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4636    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4637    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4638    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4639    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4640    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4641    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4642
4643    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4644    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4645    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4646
4647    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4648    {SMBread,"SMBread",reply_read,AS_USER},
4649    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4650    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4651    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4652    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4653    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4654    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4655
4656    /* this is a Pathworks specific call, allowing the 
4657       changing of the root path */
4658    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4659
4660    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4661    {SMBflush,"SMBflush",reply_flush,AS_USER},
4662    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4663    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4664    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4665    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4666    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4667    {SMBlock,"SMBlock",reply_lock,AS_USER},
4668    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4669    
4670    /* CORE+ PROTOCOL FOLLOWS */
4671    
4672    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4673    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4674    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4675    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4676    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4677    
4678    /* LANMAN1.0 PROTOCOL FOLLOWS */
4679    
4680    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4681    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4682    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4683    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4684    {SMBwritec,"SMBwritec",NULL,AS_USER},
4685    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4686    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4687    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4688    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4689    {SMBioctls,"SMBioctls",NULL,AS_USER},
4690    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4691    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4692    
4693    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4694    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4695    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4696    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4697    
4698    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4699    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4700    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4701
4702    /* LANMAN2.0 PROTOCOL FOLLOWS */
4703    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4704    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4705    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4706    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4707
4708    /* messaging routines */
4709    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4710    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4711    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4712    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4713
4714    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4715    
4716    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4717    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4718    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4719    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4720  };
4721
4722 /****************************************************************************
4723 return a string containing the function name of a SMB command
4724 ****************************************************************************/
4725 char *smb_fn_name(int type)
4726 {
4727   static char *unknown_name = "SMBunknown";
4728   static int num_smb_messages = 
4729     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4730   int match;
4731
4732   for (match=0;match<num_smb_messages;match++)
4733     if (smb_messages[match].code == type)
4734       break;
4735
4736   if (match == num_smb_messages)
4737     return(unknown_name);
4738
4739   return(smb_messages[match].name);
4740 }
4741
4742
4743 /****************************************************************************
4744 do a switch on the message type, and return the response size
4745 ****************************************************************************/
4746 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4747 {
4748   static int pid= -1;
4749   int outsize = 0;
4750   static int num_smb_messages = 
4751     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4752   int match;
4753
4754 #if PROFILING
4755   struct timeval msg_start_time;
4756   struct timeval msg_end_time;
4757   static unsigned long total_time = 0;
4758
4759   GetTimeOfDay(&msg_start_time);
4760 #endif
4761
4762   if (pid == -1)
4763     pid = getpid();
4764
4765   errno = 0;
4766   last_message = type;
4767
4768   /* make sure this is an SMB packet */
4769   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4770     {
4771       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4772       return(-1);
4773     }
4774
4775   for (match=0;match<num_smb_messages;match++)
4776     if (smb_messages[match].code == type)
4777       break;
4778
4779   if (match == num_smb_messages)
4780     {
4781       DEBUG(0,("Unknown message type %d!\n",type));
4782       outsize = reply_unknown(inbuf,outbuf);
4783     }
4784   else
4785     {
4786       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4787
4788       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4789       {
4790         /* 
4791          * Queue this message as we are the process of an oplock break.
4792          */
4793
4794         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4795                timestring() ));
4796
4797         push_smb_message( inbuf, size);
4798         return -1;
4799       }          
4800
4801       if (smb_messages[match].fn)
4802         {
4803           int cnum = SVAL(inbuf,smb_tid);
4804           int flags = smb_messages[match].flags;
4805           static uint16 last_session_tag = UID_FIELD_INVALID;
4806           /* In share mode security we must ignore the vuid. */
4807           uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4808           /* Ensure this value is replaced in the incoming packet. */
4809           SSVAL(inbuf,smb_uid,session_tag);
4810
4811           /*
4812            * Ensure the correct username is in sesssetup_user.
4813            * This is a really ugly bugfix for problems with
4814            * multiple session_setup_and_X's being done and
4815            * allowing %U and %G substitutions to work correctly.
4816            * There is a reason this code is done here, don't
4817            * move it unless you know what you're doing... :-).
4818            * JRA.
4819            */
4820           if(session_tag != last_session_tag ) {
4821             user_struct *vuser = NULL;
4822
4823             last_session_tag = session_tag;
4824             if(session_tag != UID_FIELD_INVALID)
4825               vuser = get_valid_user_struct(session_tag);           
4826             if(vuser != NULL)
4827               pstrcpy( sesssetup_user, vuser->requested_name);
4828           }
4829
4830           /* does this protocol need to be run as root? */
4831           if (!(flags & AS_USER))
4832             unbecome_user();
4833
4834           /* does this protocol need to be run as the connected user? */
4835           if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4836             if (flags & AS_GUEST) 
4837               flags &= ~AS_USER;
4838             else
4839               return(ERROR(ERRSRV,ERRinvnid));
4840           }
4841           /* this code is to work around a bug is MS client 3 without
4842              introducing a security hole - it needs to be able to do
4843              print queue checks as guest if it isn't logged in properly */
4844           if (flags & AS_USER)
4845             flags &= ~AS_GUEST;
4846
4847           /* does it need write permission? */
4848           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4849             return(ERROR(ERRSRV,ERRaccess));
4850
4851           /* ipc services are limited */
4852           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4853             return(ERROR(ERRSRV,ERRaccess));        
4854
4855           /* load service specific parameters */
4856           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4857             return(ERROR(ERRSRV,ERRaccess));
4858
4859           /* does this protocol need to be run as guest? */
4860           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4861             return(ERROR(ERRSRV,ERRaccess));
4862
4863           last_inbuf = inbuf;
4864
4865           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4866         }
4867       else
4868         {
4869           outsize = reply_unknown(inbuf,outbuf);
4870         }
4871     }
4872
4873 #if PROFILING
4874   GetTimeOfDay(&msg_end_time);
4875   if (!(smb_messages[match].flags & TIME_INIT))
4876     {
4877       smb_messages[match].time = 0;
4878       smb_messages[match].flags |= TIME_INIT;
4879     }
4880   {
4881     unsigned long this_time =     
4882       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4883         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4884     smb_messages[match].time += this_time;
4885     total_time += this_time;
4886   }
4887   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4888            smb_fn_name(type),smb_messages[match].time,
4889         (100.0*smb_messages[match].time) / total_time));
4890 #endif
4891
4892   return(outsize);
4893 }
4894
4895
4896 /****************************************************************************
4897   construct a chained reply and add it to the already made reply
4898   **************************************************************************/
4899 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4900 {
4901   static char *orig_inbuf;
4902   static char *orig_outbuf;
4903   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4904   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4905   char *inbuf2, *outbuf2;
4906   int outsize2;
4907   char inbuf_saved[smb_wct];
4908   char outbuf_saved[smb_wct];
4909   extern int chain_size;
4910   int wct = CVAL(outbuf,smb_wct);
4911   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4912
4913   /* maybe its not chained */
4914   if (smb_com2 == 0xFF) {
4915     CVAL(outbuf,smb_vwv0) = 0xFF;
4916     return outsize;
4917   }
4918
4919   if (chain_size == 0) {
4920     /* this is the first part of the chain */
4921     orig_inbuf = inbuf;
4922     orig_outbuf = outbuf;
4923   }
4924
4925   /* we need to tell the client where the next part of the reply will be */
4926   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4927   CVAL(outbuf,smb_vwv0) = smb_com2;
4928
4929   /* remember how much the caller added to the chain, only counting stuff
4930      after the parameter words */
4931   chain_size += outsize - smb_wct;
4932
4933   /* work out pointers into the original packets. The
4934      headers on these need to be filled in */
4935   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4936   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4937
4938   /* remember the original command type */
4939   smb_com1 = CVAL(orig_inbuf,smb_com);
4940
4941   /* save the data which will be overwritten by the new headers */
4942   memcpy(inbuf_saved,inbuf2,smb_wct);
4943   memcpy(outbuf_saved,outbuf2,smb_wct);
4944
4945   /* give the new packet the same header as the last part of the SMB */
4946   memmove(inbuf2,inbuf,smb_wct);
4947
4948   /* create the in buffer */
4949   CVAL(inbuf2,smb_com) = smb_com2;
4950
4951   /* create the out buffer */
4952   bzero(outbuf2,smb_size);
4953   set_message(outbuf2,0,0,True);
4954   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4955   
4956   memcpy(outbuf2+4,inbuf2+4,4);
4957   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4958   CVAL(outbuf2,smb_reh) = 0;
4959   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4960                                                                   means a reply */
4961   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4962   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4963   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4964   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4965   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4966   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4967
4968   DEBUG(3,("Chained message\n"));
4969   show_msg(inbuf2);
4970
4971   /* process the request */
4972   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4973                             bufsize-chain_size);
4974
4975   /* copy the new reply and request headers over the old ones, but
4976      preserve the smb_com field */
4977   memmove(orig_outbuf,outbuf2,smb_wct);
4978   CVAL(orig_outbuf,smb_com) = smb_com1;
4979
4980   /* restore the saved data, being careful not to overwrite any
4981    data from the reply header */
4982   memcpy(inbuf2,inbuf_saved,smb_wct);
4983   {
4984     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4985     if (ofs < 0) ofs = 0;
4986     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4987   }
4988
4989   return outsize2;
4990 }
4991
4992
4993
4994 /****************************************************************************
4995   construct a reply to the incoming packet
4996 ****************************************************************************/
4997 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4998 {
4999   int type = CVAL(inbuf,smb_com);
5000   int outsize = 0;
5001   int msg_type = CVAL(inbuf,0);
5002   extern int chain_size;
5003
5004   smb_last_time = time(NULL);
5005
5006   chain_size = 0;
5007   chain_fnum = -1;
5008   reset_chain_pnum();
5009
5010   bzero(outbuf,smb_size);
5011
5012   if (msg_type != 0)
5013     return(reply_special(inbuf,outbuf));  
5014
5015   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
5016   set_message(outbuf,0,0,True);
5017   
5018   memcpy(outbuf+4,inbuf+4,4);
5019   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
5020   CVAL(outbuf,smb_reh) = 0;
5021   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
5022                                                              means a reply */
5023   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
5024   SSVAL(outbuf,smb_err,SMB_SUCCESS);
5025   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
5026   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
5027   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
5028   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
5029
5030   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
5031
5032   outsize += chain_size;
5033
5034   if(outsize > 4)
5035     smb_setlen(outbuf,outsize - 4);
5036   return(outsize);
5037 }
5038
5039 /****************************************************************************
5040   process commands from the client
5041 ****************************************************************************/
5042 static void process(void)
5043 {
5044   extern int Client;
5045
5046   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5047   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5048   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
5049     return;
5050
5051   InBuffer += SMB_ALIGNMENT;
5052   OutBuffer += SMB_ALIGNMENT;
5053
5054 #if PRIME_NMBD
5055   DEBUG(3,("priming nmbd\n"));
5056   {
5057     struct in_addr ip;
5058     ip = *interpret_addr2("localhost");
5059     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
5060     *OutBuffer = 0;
5061     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
5062   }
5063 #endif    
5064
5065   /* re-initialise the timezone */
5066   TimeInit();
5067
5068   while (True)
5069   {
5070     int deadtime = lp_deadtime()*60;
5071     int counter;
5072     int last_keepalive=0;
5073     int service_load_counter = 0;
5074     BOOL got_smb = False;
5075
5076     if (deadtime <= 0)
5077       deadtime = DEFAULT_SMBD_TIMEOUT;
5078
5079 #if USE_READ_PREDICTION
5080     if (lp_readprediction())
5081       do_read_prediction();
5082 #endif
5083
5084     errno = 0;      
5085
5086     for (counter=SMBD_SELECT_LOOP; 
5087           !receive_message_or_smb(Client,oplock_sock,
5088                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
5089           counter += SMBD_SELECT_LOOP)
5090     {
5091       int i;
5092       time_t t;
5093       BOOL allidle = True;
5094       extern int keepalive;
5095
5096       if (counter > 365 * 3600) /* big number of seconds. */
5097       {
5098         counter = 0;
5099         service_load_counter = 0;
5100       }
5101
5102       if (smb_read_error == READ_EOF) 
5103       {
5104         DEBUG(3,("end of file from client\n"));
5105         return;
5106       }
5107
5108       if (smb_read_error == READ_ERROR) 
5109       {
5110         DEBUG(3,("receive_smb error (%s) exiting\n",
5111                   strerror(errno)));
5112         return;
5113       }
5114
5115       t = time(NULL);
5116
5117       /* become root again if waiting */
5118       unbecome_user();
5119
5120       /* check for smb.conf reload */
5121       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5122       {
5123         service_load_counter = counter;
5124
5125         /* reload services, if files have changed. */
5126         reload_services(True);
5127       }
5128
5129       /*
5130        * If reload_after_sighup == True then we got a SIGHUP
5131        * and are being asked to reload. Fix from <branko.cibej@hermes.si>
5132        */
5133
5134       if (reload_after_sighup)
5135       {
5136         DEBUG(0,("Reloading services after SIGHUP\n"));
5137         reload_services(False);
5138         reload_after_sighup = False;
5139       }
5140
5141       /* automatic timeout if all connections are closed */      
5142       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
5143       {
5144         DEBUG(2,("%s Closing idle connection\n",timestring()));
5145         return;
5146       }
5147
5148       if (keepalive && (counter-last_keepalive)>keepalive) 
5149       {
5150               struct cli_state *cli = server_client();
5151               if (!send_keepalive(Client)) { 
5152                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5153                       return;
5154               }     
5155               /* also send a keepalive to the password server if its still
5156                  connected */
5157               if (cli && cli->initialised)
5158                       send_keepalive(cli->fd);
5159               last_keepalive = counter;
5160       }
5161
5162       /* check for connection timeouts */
5163       for (i=0;i<MAX_CONNECTIONS;i++)
5164         if (Connections[i].open)
5165         {
5166           /* close dirptrs on connections that are idle */
5167           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5168             dptr_idlecnum(i);
5169
5170           if (Connections[i].num_files_open > 0 ||
5171                      (t-Connections[i].lastused)<deadtime)
5172             allidle = False;
5173         }
5174
5175       if (allidle && num_connections_open>0) 
5176       {
5177         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5178         return;
5179       }
5180
5181       if(global_machine_pasword_needs_changing)
5182       {
5183         unsigned char trust_passwd_hash[16];
5184         time_t lct;
5185         pstring remote_machine_list;
5186
5187         /*
5188          * We're in domain level security, and the code that
5189          * read the machine password flagged that the machine
5190          * password needs changing.
5191          */
5192
5193         /*
5194          * First, open the machine password file with an exclusive lock.
5195          */
5196
5197         if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5198           DEBUG(0,("process: unable to open the machine account password file for \
5199 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5200           continue;
5201         }
5202
5203         if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5204           DEBUG(0,("process: unable to read the machine account password for \
5205 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5206           trust_password_unlock();
5207           continue;
5208         }
5209
5210         /*
5211          * Make sure someone else hasn't already done this.
5212          */
5213
5214         if(t < lct + lp_machine_password_timeout()) {
5215           trust_password_unlock();
5216           global_machine_pasword_needs_changing = False;
5217           continue;
5218         }
5219
5220         pstrcpy(remote_machine_list, lp_passwordserver());
5221
5222         change_trust_account_password( global_myworkgroup, remote_machine_list);
5223         trust_password_unlock();
5224         global_machine_pasword_needs_changing = False;
5225       }
5226     }
5227
5228     if(got_smb)
5229       process_smb(InBuffer, OutBuffer);
5230     else
5231       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5232   }
5233 }
5234
5235
5236 /****************************************************************************
5237   initialise connect, service and file structs
5238 ****************************************************************************/
5239 static void init_structs(void )
5240 {
5241   int i;
5242   get_myname(myhostname,NULL);
5243
5244   /*
5245    * Set the machine NETBIOS name if not already
5246    * set from the config file.
5247    */
5248
5249   if (!*global_myname)
5250   {
5251     char *p;
5252     fstrcpy( global_myname, myhostname );
5253     p = strchr( global_myname, '.' );
5254     if (p) 
5255       *p = 0;
5256   }
5257   strupper( global_myname );
5258
5259   for (i=0;i<MAX_CONNECTIONS;i++)
5260     {
5261       Connections[i].open = False;
5262       Connections[i].num_files_open=0;
5263       Connections[i].lastused=0;
5264       Connections[i].used=False;
5265       string_init(&Connections[i].user,"");
5266       string_init(&Connections[i].dirpath,"");
5267       string_init(&Connections[i].connectpath,"");
5268       string_init(&Connections[i].origpath,"");
5269     }
5270
5271   for (i=0;i<MAX_OPEN_FILES;i++)
5272     {
5273       Files[i].open = False;
5274       string_init(&Files[i].name,"");
5275     }
5276
5277   for (i=0;i<MAX_OPEN_FILES;i++)
5278     {
5279       file_fd_struct *fd_ptr = &FileFd[i];
5280       fd_ptr->ref_count = 0;
5281       fd_ptr->dev = (int32)-1;
5282       fd_ptr->inode = (int32)-1;
5283       fd_ptr->fd = -1;
5284       fd_ptr->fd_readonly = -1;
5285       fd_ptr->fd_writeonly = -1;
5286       fd_ptr->real_open_flags = -1;
5287     }
5288
5289   /* for RPC pipes */
5290   init_rpc_pipe_hnd();
5291
5292   /* for LSA handles */
5293   init_lsa_policy_hnd();
5294
5295   init_dptrs();
5296 }
5297
5298 /****************************************************************************
5299 usage on the program
5300 ****************************************************************************/
5301 static void usage(char *pname)
5302 {
5303   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5304
5305   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5306   printf("Version %s\n",VERSION);
5307   printf("\t-D                    become a daemon\n");
5308   printf("\t-p port               listen on the specified port\n");
5309   printf("\t-d debuglevel         set the debuglevel\n");
5310   printf("\t-l log basename.      Basename for log/debug files\n");
5311   printf("\t-s services file.     Filename of services file\n");
5312   printf("\t-P                    passive only\n");
5313   printf("\t-a                    overwrite log file, don't append\n");
5314   printf("\n");
5315 }
5316
5317
5318 /****************************************************************************
5319   main program
5320 ****************************************************************************/
5321  int main(int argc,char *argv[])
5322 {
5323   extern BOOL append_log;
5324   /* shall I run as a daemon */
5325   BOOL is_daemon = False;
5326   int port = SMB_PORT;
5327   int opt;
5328   extern char *optarg;
5329
5330 #ifdef NEED_AUTH_PARAMETERS
5331   set_auth_parameters(argc,argv);
5332 #endif
5333
5334 #ifdef SecureWare
5335   setluid(0);
5336 #endif
5337
5338   append_log = True;
5339
5340   TimeInit();
5341
5342   pstrcpy(debugf,SMBLOGFILE);  
5343
5344   pstrcpy(remote_machine, "smb");
5345
5346   setup_logging(argv[0],False);
5347
5348   charset_initialise();
5349
5350   /* make absolutely sure we run as root - to handle cases where people
5351      are crazy enough to have it setuid */
5352 #ifdef USE_SETRES
5353   setresuid(0,0,0);
5354 #else
5355   setuid(0);
5356   seteuid(0);
5357   setuid(0);
5358   seteuid(0);
5359 #endif
5360
5361   fault_setup((void (*)(void *))exit_server);
5362   signal(SIGTERM , SIGNAL_CAST dflt_sig);
5363
5364   /* we want total control over the permissions on created files,
5365      so set our umask to 0 */
5366   umask(0);
5367
5368   GetWd(OriginalDir);
5369
5370   init_uid();
5371
5372   /* this is for people who can't start the program correctly */
5373   while (argc > 1 && (*argv[1] != '-'))
5374     {
5375       argv++;
5376       argc--;
5377     }
5378
5379   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5380     switch (opt)
5381       {
5382       case 'O':
5383         pstrcpy(user_socket_options,optarg);
5384         break;
5385       case 'i':
5386         pstrcpy(scope,optarg);
5387         break;
5388       case 'P':
5389         {
5390           extern BOOL passive;
5391           passive = True;
5392         }
5393         break;  
5394       case 's':
5395         pstrcpy(servicesf,optarg);
5396         break;
5397       case 'l':
5398         pstrcpy(debugf,optarg);
5399         break;
5400       case 'a':
5401         {
5402           extern BOOL append_log;
5403           append_log = !append_log;
5404         }
5405         break;
5406       case 'D':
5407         is_daemon = True;
5408         break;
5409       case 'd':
5410         if (*optarg == 'A')
5411           DEBUGLEVEL = 10000;
5412         else
5413           DEBUGLEVEL = atoi(optarg);
5414         break;
5415       case 'p':
5416         port = atoi(optarg);
5417         break;
5418       case 'h':
5419         usage(argv[0]);
5420         exit(0);
5421         break;
5422       default:
5423         usage(argv[0]);
5424         exit(1);
5425       }
5426
5427   reopen_logs();
5428
5429   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5430   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5431
5432 #ifndef NO_GETRLIMIT
5433 #ifdef RLIMIT_NOFILE
5434   {
5435     struct rlimit rlp;
5436     getrlimit(RLIMIT_NOFILE, &rlp);
5437     /*
5438      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5439      * extra fd we need to read directories, as well as the log files
5440      * and standard handles etc.
5441      */
5442     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5443     setrlimit(RLIMIT_NOFILE, &rlp);
5444     getrlimit(RLIMIT_NOFILE, &rlp);
5445     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5446   }
5447 #endif
5448 #endif
5449
5450   
5451   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5452         getuid(),getgid(),geteuid(),getegid()));
5453
5454   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5455     {
5456       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5457       exit(1);
5458     }
5459
5460   init_structs();
5461
5462   if (!reload_services(False))
5463     return(-1); 
5464
5465 #ifdef USE_SSL
5466   {
5467     extern BOOL sslEnabled;
5468     sslEnabled = lp_ssl_enabled();
5469     if(sslEnabled)
5470       sslutil_init(True);
5471   }
5472 #endif        /* USE_SSL */
5473
5474   codepage_initialise(lp_client_code_page());
5475
5476   pstrcpy(global_myworkgroup, lp_workgroup());
5477
5478   if(!pdb_generate_machine_sid())
5479   {
5480     DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5481     exit(1);
5482   }
5483
5484 #ifndef NO_SIGNAL_TEST
5485   signal(SIGHUP,SIGNAL_CAST sig_hup);
5486 #endif
5487
5488   /* Setup the signals that allow the debug log level
5489      to by dynamically changed. */
5490  
5491   /* If we are using the malloc debug code we can't use
5492      SIGUSR1 and SIGUSR2 to do debug level changes. */
5493
5494 #ifndef MEM_MAN
5495 #if defined(SIGUSR1)
5496   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5497 #endif /* SIGUSR1 */
5498    
5499 #if defined(SIGUSR2)
5500   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5501 #endif /* SIGUSR2 */
5502 #endif /* MEM_MAN */
5503
5504   DEBUG(3,("%s loaded services\n",timestring()));
5505
5506   if (!is_daemon && !is_a_socket(0))
5507     {
5508       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5509       is_daemon = True;
5510     }
5511
5512   if (is_daemon)
5513     {
5514       DEBUG(3,("%s becoming a daemon\n",timestring()));
5515       become_daemon();
5516     }
5517
5518   if (!directory_exist(lp_lockdir(), NULL)) {
5519           mkdir(lp_lockdir(), 0755);
5520   }
5521
5522   if (is_daemon) {
5523           pidfile_create("smbd");
5524   }
5525
5526   if (!open_sockets(is_daemon,port))
5527     exit(1);
5528
5529   if (!locking_init(0))
5530     exit(1);
5531
5532   if(!initialize_password_db())
5533     exit(1);
5534
5535   /* possibly reload the services file. */
5536   reload_services(True);
5537
5538   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5539
5540   if (*lp_rootdir())
5541     {
5542       if (sys_chroot(lp_rootdir()) == 0)
5543         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5544     }
5545
5546   /* Setup the oplock IPC socket. */
5547   if(!open_oplock_ipc())
5548     exit(1);
5549
5550   process();
5551   close_sockets();
5552
5553   exit_server("normal exit");
5554   return(0);
5555 }