Minor changes as I've now discovered gcc -pedantic-errors. This
[ira/wip.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       DEBUG(3,("checking for home directory %s gave %s\n",service,
2344             phome_dir?phome_dir:"(NULL)"));
2345       if (phome_dir)
2346       {   
2347          int iHomeService;
2348          if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2349          {
2350             lp_add_home(service,iHomeService,phome_dir);
2351             iService = lp_servicenumber(service);
2352          }
2353       }
2354    }
2355
2356    /* If we still don't have a service, attempt to add it as a printer. */
2357    if (iService < 0)
2358    {
2359       int iPrinterService;
2360
2361       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2362       {
2363          char *pszTemp;
2364
2365          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2366          pszTemp = PRINTCAP;
2367          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2368          {
2369             DEBUG(3,("%s is a valid printer name\n", service));
2370             DEBUG(3,("adding %s as a printer service\n", service));
2371             lp_add_printer(service,iPrinterService);
2372             iService = lp_servicenumber(service);
2373             if (iService < 0)
2374                DEBUG(0,("failed to add %s as a printer service!\n", service));
2375          }
2376          else
2377             DEBUG(3,("%s is not a valid printer name\n", service));
2378       }
2379    }
2380
2381    /* just possibly it's a default service? */
2382    if (iService < 0) 
2383      {
2384        char *pdefservice = lp_defaultservice();
2385        if (pdefservice && *pdefservice && !strequal(pdefservice,service)) {
2386          /*
2387           * We need to do a local copy here as lp_defaultservice() 
2388           * returns one of the rotating lp_string buffers that
2389           * could get overwritten by the recursive find_service() call
2390           * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2391           */
2392          pstring defservice;
2393          pstrcpy(defservice, pdefservice);
2394          iService = find_service(defservice);
2395          if (iService >= 0) {
2396            string_sub(service,"_","/");
2397            iService = lp_add_service(service,iService);
2398          }
2399        }
2400      }
2401
2402    if (iService >= 0)
2403       if (!VALID_SNUM(iService))
2404       {
2405          DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2406          iService = -1;
2407       }
2408
2409    if (iService < 0)
2410       DEBUG(3,("find_service() failed to find service %s\n", service));
2411
2412    return (iService);
2413 }
2414
2415
2416 /****************************************************************************
2417   create an error packet from a cached error.
2418 ****************************************************************************/
2419 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2420 {
2421   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2422
2423   int32 eclass = wbmpx->wr_errclass;
2424   int32 err = wbmpx->wr_error;
2425
2426   /* We can now delete the auxiliary struct */
2427   free((char *)wbmpx);
2428   Files[fnum].wbmpx_ptr = NULL;
2429   return error_packet(inbuf,outbuf,eclass,err,line);
2430 }
2431
2432
2433 struct
2434 {
2435   int unixerror;
2436   int smbclass;
2437   int smbcode;
2438 } unix_smb_errmap[] =
2439 {
2440   {EPERM,ERRDOS,ERRnoaccess},
2441   {EACCES,ERRDOS,ERRnoaccess},
2442   {ENOENT,ERRDOS,ERRbadfile},
2443   {ENOTDIR,ERRDOS,ERRbadpath},
2444   {EIO,ERRHRD,ERRgeneral},
2445   {EBADF,ERRSRV,ERRsrverror},
2446   {EINVAL,ERRSRV,ERRsrverror},
2447   {EEXIST,ERRDOS,ERRfilexists},
2448   {ENFILE,ERRDOS,ERRnofids},
2449   {EMFILE,ERRDOS,ERRnofids},
2450   {ENOSPC,ERRHRD,ERRdiskfull},
2451 #ifdef EDQUOT
2452   {EDQUOT,ERRHRD,ERRdiskfull},
2453 #endif
2454 #ifdef ENOTEMPTY
2455   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2456 #endif
2457 #ifdef EXDEV
2458   {EXDEV,ERRDOS,ERRdiffdevice},
2459 #endif
2460   {EROFS,ERRHRD,ERRnowrite},
2461   {0,0,0}
2462 };
2463
2464 /****************************************************************************
2465   create an error packet from errno
2466 ****************************************************************************/
2467 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2468 {
2469   int eclass=def_class;
2470   int ecode=def_code;
2471   int i=0;
2472
2473   if (unix_ERR_class != SMB_SUCCESS)
2474     {
2475       eclass = unix_ERR_class;
2476       ecode = unix_ERR_code;
2477       unix_ERR_class = SMB_SUCCESS;
2478       unix_ERR_code = 0;
2479     }
2480   else
2481     {
2482       while (unix_smb_errmap[i].smbclass != 0)
2483       {
2484             if (unix_smb_errmap[i].unixerror == errno)
2485             {
2486               eclass = unix_smb_errmap[i].smbclass;
2487               ecode = unix_smb_errmap[i].smbcode;
2488               break;
2489             }
2490           i++;
2491       }
2492     }
2493
2494   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2495 }
2496
2497
2498 /****************************************************************************
2499   create an error packet. Normally called using the ERROR() macro
2500 ****************************************************************************/
2501 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2502 {
2503   int outsize = set_message(outbuf,0,0,True);
2504   int cmd = CVAL(inbuf,smb_com);
2505   int flgs2 = SVAL(outbuf,smb_flg2); 
2506
2507   if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2508   {
2509     SIVAL(outbuf,smb_rcls,error_code);
2510     
2511     DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2512            timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2513   }
2514   else
2515   {
2516     CVAL(outbuf,smb_rcls) = error_class;
2517     SSVAL(outbuf,smb_err,error_code);  
2518     DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2519            timestring(),
2520            line,
2521            (int)CVAL(inbuf,smb_com),
2522            smb_fn_name(CVAL(inbuf,smb_com)),
2523            error_class,
2524            error_code));
2525
2526   }
2527   
2528   if (errno != 0)
2529     DEBUG(3,("error string = %s\n",strerror(errno)));
2530   
2531   return(outsize);
2532 }
2533
2534
2535 #ifndef SIGCLD_IGNORE
2536 /****************************************************************************
2537 this prevents zombie child processes
2538 ****************************************************************************/
2539 static int sig_cld(void)
2540 {
2541   static int depth = 0;
2542   if (depth != 0)
2543     {
2544       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2545       depth=0;
2546       return(0);
2547     }
2548   depth++;
2549
2550   BlockSignals(True,SIGCLD);
2551   DEBUG(5,("got SIGCLD\n"));
2552
2553 #ifdef USE_WAITPID
2554   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2555 #endif
2556
2557   /* Stop zombies */
2558   /* Stevens, Adv. Unix Prog. says that on system V you must call
2559      wait before reinstalling the signal handler, because the kernel
2560      calls the handler from within the signal-call when there is a
2561      child that has exited. This would lead to an infinite recursion
2562      if done vice versa. */
2563         
2564 #ifndef DONT_REINSTALL_SIG
2565 #ifdef SIGCLD_IGNORE
2566   signal(SIGCLD, SIG_IGN);  
2567 #else
2568   signal(SIGCLD, SIGNAL_CAST sig_cld);
2569 #endif
2570 #endif
2571
2572 #ifndef USE_WAITPID
2573   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2574 #endif
2575   depth--;
2576   BlockSignals(False,SIGCLD);
2577   return 0;
2578 }
2579 #endif
2580
2581 /****************************************************************************
2582   this is called when the client exits abruptly
2583   **************************************************************************/
2584 static int sig_pipe(void)
2585 {
2586         struct cli_state *cli;
2587         BlockSignals(True,SIGPIPE);
2588
2589         if ((cli = server_client()) && cli->initialised) {
2590                 DEBUG(3,("lost connection to password server\n"));
2591                 cli_shutdown(cli);
2592 #ifndef DONT_REINSTALL_SIG
2593                 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2594 #endif
2595                 BlockSignals(False,SIGPIPE);
2596                 return 0;
2597         }
2598
2599         exit_server("Got sigpipe\n");
2600         return(0);
2601 }
2602
2603 /****************************************************************************
2604   open the socket communication
2605 ****************************************************************************/
2606 static BOOL open_sockets(BOOL is_daemon,int port)
2607 {
2608   extern int Client;
2609
2610   if (is_daemon)
2611   {
2612     int num_interfaces = iface_count();
2613     int fd_listenset[FD_SETSIZE];
2614     fd_set listen_set;
2615     int s;
2616     int i;
2617
2618     /* Stop zombies */
2619 #ifdef SIGCLD_IGNORE
2620     signal(SIGCLD, SIG_IGN);
2621 #else
2622     signal(SIGCLD, SIGNAL_CAST sig_cld);
2623 #endif
2624
2625     if(atexit_set == 0)
2626       atexit(killkids);
2627
2628     FD_ZERO(&listen_set);
2629
2630     if(lp_interfaces() && lp_bind_interfaces_only())
2631     {
2632        /* We have been given an interfaces line, and been 
2633           told to only bind to those interfaces. Create a
2634           socket per interface and bind to only these.
2635         */
2636
2637       if(num_interfaces > FD_SETSIZE)
2638       {
2639         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2640 max can be %d\n", num_interfaces, FD_SETSIZE));
2641         return False;
2642       }
2643
2644       /* Now open a listen socket for each of the interfaces. */
2645       for(i = 0; i < num_interfaces; i++)
2646       {
2647         struct in_addr *ifip = iface_n_ip(i);
2648
2649         if(ifip == NULL)
2650         {
2651           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2652           continue;
2653         }
2654         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2655         if(s == -1)
2656           return False;
2657         /* ready to listen */
2658         if (listen(s, 5) == -1) 
2659         {
2660           DEBUG(0,("listen: %s\n",strerror(errno)));
2661           close(s);
2662           return False;
2663         }
2664         FD_SET(s,&listen_set);
2665       }
2666     }
2667     else
2668     {
2669       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2670       num_interfaces = 1;
2671
2672       /* open an incoming socket */
2673       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2674       if (s == -1)
2675         return(False);
2676
2677       /* ready to listen */
2678       if (listen(s, 5) == -1) 
2679       {
2680         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2681         close(s);
2682         return False;
2683       }
2684
2685       fd_listenset[0] = s;
2686       FD_SET(s,&listen_set);
2687     }      
2688
2689     /* now accept incoming connections - forking a new process
2690        for each incoming connection */
2691     DEBUG(2,("waiting for a connection\n"));
2692     while (1)
2693     {
2694       fd_set lfds;
2695       int num;
2696
2697       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2698
2699       num = sys_select(&lfds,NULL);
2700
2701       if (num == -1 && errno == EINTR)
2702         continue;
2703
2704       /* Find the sockets that are read-ready - accept on these. */
2705       for( ; num > 0; num--)
2706       {
2707         struct sockaddr addr;
2708         int in_addrlen = sizeof(addr);
2709
2710         s = -1;
2711         for(i = 0; i < num_interfaces; i++)
2712         {
2713           if(FD_ISSET(fd_listenset[i],&lfds))
2714           {
2715             s = fd_listenset[i];
2716             /* Clear this so we don't look at it again. */
2717             FD_CLR(fd_listenset[i],&lfds);
2718             break;
2719           }
2720         }
2721
2722         Client = accept(s,&addr,&in_addrlen);
2723
2724         if (Client == -1 && errno == EINTR)
2725           continue;
2726
2727         if (Client == -1)
2728         {
2729           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2730           continue;
2731         }
2732
2733 #ifdef NO_FORK_DEBUG
2734 #ifndef NO_SIGNAL_TEST
2735         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2736         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2737 #endif /* NO_SIGNAL_TEST */
2738         return True;
2739 #else /* NO_FORK_DEBUG */
2740         if (Client != -1 && fork()==0)
2741         {
2742           /* Child code ... */
2743
2744 #ifndef NO_SIGNAL_TEST
2745           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2746           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2747 #endif /* NO_SIGNAL_TEST */
2748           /* close the listening socket(s) */
2749           for(i = 0; i < num_interfaces; i++)
2750             close(fd_listenset[i]);
2751
2752           /* close our standard file descriptors */
2753           close_low_fds();
2754           am_parent = 0;
2755   
2756           set_socket_options(Client,"SO_KEEPALIVE");
2757           set_socket_options(Client,user_socket_options);
2758
2759           /* Reset global variables in util.c so that
2760              client substitutions will be done correctly
2761              in the process.
2762            */
2763           reset_globals_after_fork();
2764           return True; 
2765         }
2766         close(Client); /* The parent doesn't need this socket */
2767 #endif /* NO_FORK_DEBUG */
2768       } /* end for num */
2769     } /* end while 1 */
2770   } /* end if is_daemon */
2771   else
2772   {
2773     /* Started from inetd. fd 0 is the socket. */
2774     /* We will abort gracefully when the client or remote system 
2775        goes away */
2776 #ifndef NO_SIGNAL_TEST
2777     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2778 #endif
2779     Client = dup(0);
2780
2781     /* close our standard file descriptors */
2782     close_low_fds();
2783
2784     set_socket_options(Client,"SO_KEEPALIVE");
2785     set_socket_options(Client,user_socket_options);
2786   }
2787
2788   return True;
2789 }
2790
2791 /****************************************************************************
2792   process an smb from the client - split out from the process() code so
2793   it can be used by the oplock break code.
2794 ****************************************************************************/
2795
2796 static void process_smb(char *inbuf, char *outbuf)
2797 {
2798   extern int Client;
2799   static int trans_num;
2800   int msg_type = CVAL(inbuf,0);
2801   int32 len = smb_len(inbuf);
2802   int nread = len + 4;
2803
2804   if (trans_num == 0) {
2805           /* on the first packet, check the global hosts allow/ hosts
2806              deny parameters before doing any parsing of the packet
2807              passed to us by the client.  This prevents attacks on our
2808              parsing code from hosts not in the hosts allow list */
2809           if (!check_access(-1)) {
2810                   /* send a negative session response "not listining on calling
2811                    name" */
2812                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2813                   DEBUG(1,("%s Connection denied from %s\n",
2814                            timestring(),client_addr(Client)));
2815                   send_smb(Client,(char *)buf);
2816                   exit_server("connection denied");
2817           }
2818   }
2819
2820   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2821   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2822
2823 #ifdef WITH_VTP
2824   if(trans_num == 1 && VT_Check(inbuf)) 
2825   {
2826     VT_Process();
2827     return;
2828   }
2829 #endif
2830
2831   if (msg_type == 0)
2832     show_msg(inbuf);
2833   else if(msg_type == 0x85)
2834     return; /* Keepalive packet. */
2835
2836   nread = construct_reply(inbuf,outbuf,nread,max_send);
2837       
2838   if(nread > 0) 
2839   {
2840     if (CVAL(outbuf,0) == 0)
2841       show_msg(outbuf);
2842         
2843     if (nread != smb_len(outbuf) + 4) 
2844     {
2845       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2846                  nread, smb_len(outbuf)));
2847     }
2848     else
2849       send_smb(Client,outbuf);
2850   }
2851   trans_num++;
2852 }
2853
2854 /****************************************************************************
2855   open the oplock IPC socket communication
2856 ****************************************************************************/
2857 static BOOL open_oplock_ipc(void)
2858 {
2859   struct sockaddr_in sock_name;
2860   int len = sizeof(sock_name);
2861
2862   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2863
2864   /* Open a lookback UDP socket on a random port. */
2865   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2866   if (oplock_sock == -1)
2867   {
2868     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2869 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2870     oplock_port = 0;
2871     return(False);
2872   }
2873
2874   /* Find out the transient UDP port we have been allocated. */
2875   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2876   {
2877     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2878             strerror(errno)));
2879     close(oplock_sock);
2880     oplock_sock = -1;
2881     oplock_port = 0;
2882     return False;
2883   }
2884   oplock_port = ntohs(sock_name.sin_port);
2885
2886   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2887             getpid(), oplock_port));
2888
2889   return True;
2890 }
2891
2892 /****************************************************************************
2893   process an oplock break message.
2894 ****************************************************************************/
2895 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2896 {
2897   int32 msg_len;
2898   uint16 from_port;
2899   char *msg_start;
2900
2901   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2902   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2903
2904   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2905
2906   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2907             msg_len, from_port));
2908
2909   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2910      only valid request. */
2911
2912   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2913   {
2914     case OPLOCK_BREAK_CMD:
2915       /* Ensure that the msg length is correct. */
2916       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2917       {
2918         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2919 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2920         return False;
2921       }
2922       {
2923         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2924         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2925         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2926         struct timeval tval;
2927         struct sockaddr_in toaddr;
2928
2929         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2930         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2931
2932         DEBUG(5,("process_local_message: oplock break request from \
2933 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2934
2935         /*
2936          * If we have no record of any currently open oplocks,
2937          * it's not an error, as a close command may have
2938          * just been issued on the file that was oplocked.
2939          * Just return success in this case.
2940          */
2941
2942         if(global_oplocks_open != 0)
2943         {
2944           if(oplock_break(dev, inode, &tval) == False)
2945           {
2946             DEBUG(0,("process_local_message: oplock break failed - \
2947 not returning udp message.\n"));
2948             return False;
2949           }
2950         }
2951         else
2952         {
2953           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2954 oplocks. Returning success.\n"));
2955         }
2956
2957         /* Send the message back after OR'ing in the 'REPLY' bit. */
2958         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2959   
2960         bzero((char *)&toaddr,sizeof(toaddr));
2961         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2962         toaddr.sin_port = htons(from_port);
2963         toaddr.sin_family = AF_INET;
2964
2965         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2966                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2967         {
2968           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2969                     remotepid, strerror(errno)));
2970           return False;
2971         }
2972
2973         DEBUG(5,("process_local_message: oplock break reply sent to \
2974 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2975                 from_port, dev, inode));
2976
2977       }
2978       break;
2979     /* 
2980      * Keep this as a debug case - eventually we can remove it.
2981      */
2982     case 0x8001:
2983       DEBUG(0,("process_local_message: Received unsolicited break \
2984 reply - dumping info.\n"));
2985
2986       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2987       {
2988         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2989 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2990         return False;
2991       }
2992
2993       {
2994         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2995         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2996         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2997
2998         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2999 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
3000
3001        }
3002        return False;
3003
3004     default:
3005       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
3006                 (unsigned int)SVAL(msg_start,0)));
3007       return False;
3008   }
3009   return True;
3010 }
3011
3012 /****************************************************************************
3013  Process an oplock break directly.
3014 ****************************************************************************/
3015 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
3016 {
3017   extern struct current_user current_user;
3018   extern int Client;
3019   char *inbuf = NULL;
3020   char *outbuf = NULL;
3021   files_struct *fsp = NULL;
3022   int fnum;
3023   time_t start_time;
3024   BOOL shutdown_server = False;
3025   int saved_cnum;
3026   int saved_vuid;
3027   pstring saved_dir; 
3028
3029   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
3030 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
3031
3032   /* We need to search the file open table for the
3033      entry containing this dev and inode, and ensure
3034      we have an oplock on it. */
3035   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
3036   {
3037     if(OPEN_FNUM(fnum))
3038     {
3039       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
3040          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
3041          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
3042               fsp = &Files[fnum];
3043               break;
3044       }
3045     }
3046   }
3047
3048   if(fsp == NULL)
3049   {
3050     /* The file could have been closed in the meantime - return success. */
3051     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
3052 allowing break to succeed.\n", timestring(), dev, inode, fnum));
3053     return True;
3054   }
3055
3056   /* Ensure we have an oplock on the file */
3057
3058   /* There is a potential race condition in that an oplock could
3059      have been broken due to another udp request, and yet there are
3060      still oplock break messages being sent in the udp message
3061      queue for this file. So return true if we don't have an oplock,
3062      as we may have just freed it.
3063    */
3064
3065   if(!fsp->granted_oplock)
3066   {
3067     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));
3068     return True;
3069   }
3070
3071   /* mark the oplock break as sent - we don't want to send twice! */
3072   if (fsp->sent_oplock_break)
3073   {
3074     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));
3075
3076     /* We have to fail the open here as we cannot send another oplock break on this
3077        file whilst we are awaiting a response from the client - neither can we
3078        allow another open to succeed while we are waiting for the client. */
3079     return False;
3080   }
3081
3082   /* Now comes the horrid part. We must send an oplock break to the client,
3083      and then process incoming messages until we get a close or oplock release.
3084      At this point we know we need a new inbuf/outbuf buffer pair.
3085      We cannot use these staticaly as we may recurse into here due to
3086      messages crossing on the wire.
3087    */
3088
3089   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3090   {
3091     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
3092     return False;
3093   }
3094
3095   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
3096   {
3097     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
3098     free(inbuf);
3099     inbuf = NULL;
3100     return False;
3101   }
3102
3103   /* Prepare the SMBlockingX message. */
3104   bzero(outbuf,smb_size);
3105   set_message(outbuf,8,0,True);
3106
3107   SCVAL(outbuf,smb_com,SMBlockingX);
3108   SSVAL(outbuf,smb_tid,fsp->cnum);
3109   SSVAL(outbuf,smb_pid,0xFFFF);
3110   SSVAL(outbuf,smb_uid,0);
3111   SSVAL(outbuf,smb_mid,0xFFFF);
3112   SCVAL(outbuf,smb_vwv0,0xFF);
3113   SSVAL(outbuf,smb_vwv2,fnum);
3114   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
3115   /* Change this when we have level II oplocks. */
3116   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
3117  
3118   send_smb(Client, outbuf);
3119
3120   /* Remember we just sent an oplock break on this file. */
3121   fsp->sent_oplock_break = True;
3122
3123   /* We need this in case a readraw crosses on the wire. */
3124   global_oplock_break = True;
3125  
3126   /* Process incoming messages. */
3127
3128   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
3129      seconds we should just die.... */
3130
3131   start_time = time(NULL);
3132
3133   /*
3134    * Save the information we need to re-become the
3135    * user, then unbecome the user whilst we're doing this.
3136    */
3137   saved_cnum = fsp->cnum;
3138   saved_vuid = current_user.vuid;
3139   GetWd(saved_dir);
3140   unbecome_user();
3141
3142   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
3143   {
3144     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
3145     {
3146       /*
3147        * Die if we got an error.
3148        */
3149
3150       if (smb_read_error == READ_EOF)
3151         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
3152  
3153       if (smb_read_error == READ_ERROR)
3154         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
3155                   timestring(), strerror(errno)));
3156
3157       if (smb_read_error == READ_TIMEOUT)
3158         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
3159                   timestring(), OPLOCK_BREAK_TIMEOUT));
3160
3161       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3162 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3163       shutdown_server = True;
3164       break;
3165     }
3166
3167     /*
3168      * There are certain SMB requests that we shouldn't allow
3169      * to recurse. opens, renames and deletes are the obvious
3170      * ones. This is handled in the switch_message() function.
3171      * If global_oplock_break is set they will push the packet onto
3172      * the pending smb queue and return -1 (no reply).
3173      * JRA.
3174      */
3175
3176     process_smb(inbuf, outbuf);
3177
3178     /*
3179      * Die if we go over the time limit.
3180      */
3181
3182     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3183     {
3184       DEBUG(0,("%s oplock_break: no break received from client within \
3185 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3186       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3187 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3188       shutdown_server = True;
3189       break;
3190     }
3191   }
3192
3193   /*
3194    * Go back to being the user who requested the oplock
3195    * break.
3196    */
3197   if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3198   {
3199     DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3200           timestring()));
3201     close_sockets();
3202     close(oplock_sock);
3203     exit_server("unable to re-become user");
3204   }
3205   /* Including the directory. */
3206   ChDir(saved_dir);
3207
3208   /* Free the buffers we've been using to recurse. */
3209   free(inbuf);
3210   free(outbuf);
3211
3212   /* We need this in case a readraw crossed on the wire. */
3213   if(global_oplock_break)
3214     global_oplock_break = False;
3215
3216   /*
3217    * If the client did not respond we must die.
3218    */
3219
3220   if(shutdown_server)
3221   {
3222     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3223           timestring()));
3224     close_sockets();
3225     close(oplock_sock);
3226     exit_server("oplock break failure");
3227   }
3228
3229   if(OPEN_FNUM(fnum))
3230   {
3231     /* The lockingX reply will have removed the oplock flag 
3232        from the sharemode. */
3233     /* Paranoia.... */
3234     fsp->granted_oplock = False;
3235     fsp->sent_oplock_break = False;
3236     global_oplocks_open--;
3237   }
3238
3239   /* Santity check - remove this later. JRA */
3240   if(global_oplocks_open < 0)
3241   {
3242     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3243               global_oplocks_open));
3244     exit_server("oplock_break: global_oplocks_open < 0");
3245   }
3246
3247   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3248 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3249
3250   return True;
3251 }
3252
3253 /****************************************************************************
3254 Send an oplock break message to another smbd process. If the oplock is held 
3255 by the local smbd then call the oplock break function directly.
3256 ****************************************************************************/
3257
3258 BOOL request_oplock_break(share_mode_entry *share_entry, 
3259                           uint32 dev, uint32 inode)
3260 {
3261   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3262   struct sockaddr_in addr_out;
3263   int pid = getpid();
3264   time_t start_time;
3265   int time_left;
3266
3267   if(pid == share_entry->pid)
3268   {
3269     /* We are breaking our own oplock, make sure it's us. */
3270     if(share_entry->op_port != oplock_port)
3271     {
3272       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3273 should be %d\n", pid, share_entry->op_port, oplock_port));
3274       return False;
3275     }
3276
3277     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3278
3279     /* Call oplock break direct. */
3280     return oplock_break(dev, inode, &share_entry->time);
3281   }
3282
3283   /* We need to send a OPLOCK_BREAK_CMD message to the
3284      port in the share mode entry. */
3285
3286   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3287   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3288   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3289   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3290   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3291   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3292
3293   /* set the address and port */
3294   bzero((char *)&addr_out,sizeof(addr_out));
3295   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3296   addr_out.sin_port = htons( share_entry->op_port );
3297   addr_out.sin_family = AF_INET;
3298    
3299   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3300 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3301
3302   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3303          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3304   {
3305     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3306 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3307          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3308          strerror(errno)));
3309     return False;
3310   }
3311
3312   /*
3313    * Now we must await the oplock broken message coming back
3314    * from the target smbd process. Timeout if it fails to
3315    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3316    * While we get messages that aren't ours, loop.
3317    */
3318
3319   start_time = time(NULL);
3320   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3321
3322   while(time_left >= 0)
3323   {
3324     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3325     int32 reply_msg_len;
3326     uint16 reply_from_port;
3327     char *reply_msg_start;
3328
3329     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3330                time_left ? time_left * 1000 : 1) == False)
3331     {
3332       if(smb_read_error == READ_TIMEOUT)
3333       {
3334         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3335 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3336                            share_entry->op_port, dev, inode));
3337         /*
3338          * This is a hack to make handling of failing clients more robust.
3339          * If a oplock break response message is not received in the timeout
3340          * period we may assume that the smbd servicing that client holding
3341          * the oplock has died and the client changes were lost anyway, so
3342          * we should continue to try and open the file.
3343          */
3344         break;
3345       }
3346       else
3347         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3348 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3349                          share_entry->op_port, dev, inode, strerror(errno)));
3350       return False;
3351     }
3352
3353     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3354     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3355
3356     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3357
3358     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3359     {
3360       /* Ignore it. */
3361       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3362              timestring()));
3363       continue;
3364     }
3365
3366     /*
3367      * Test to see if this is the reply we are awaiting.
3368      */
3369
3370     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3371        (reply_from_port == share_entry->op_port) && 
3372        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3373                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3374                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3375     {
3376       /*
3377        * This is the reply we've been waiting for.
3378        */
3379       break;
3380     }
3381     else
3382     {
3383       /*
3384        * This is another message - probably a break request.
3385        * Process it to prevent potential deadlock.
3386        * Note that the code in switch_message() prevents
3387        * us from recursing into here as any SMB requests
3388        * we might process that would cause another oplock
3389        * break request to be made will be queued.
3390        * JRA.
3391        */
3392
3393       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3394     }
3395
3396     time_left -= (time(NULL) - start_time);
3397   }
3398
3399   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3400
3401   return True;
3402 }
3403
3404 /****************************************************************************
3405 Get the next SMB packet, doing the local message processing automatically.
3406 ****************************************************************************/
3407
3408 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3409 {
3410   BOOL got_smb = False;
3411   BOOL ret;
3412
3413   do
3414   {
3415     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3416                                  timeout,&got_smb);
3417
3418     if(ret && !got_smb)
3419     {
3420       /* Deal with oplock break requests from other smbd's. */
3421       process_local_message(oplock_sock, inbuf, bufsize);
3422       continue;
3423     }
3424
3425     if(ret && (CVAL(inbuf,0) == 0x85))
3426     {
3427       /* Keepalive packet. */
3428       got_smb = False;
3429     }
3430
3431   }
3432   while(ret && !got_smb);
3433
3434   return ret;
3435 }
3436
3437 /****************************************************************************
3438 check if a snum is in use
3439 ****************************************************************************/
3440 BOOL snum_used(int snum)
3441 {
3442   int i;
3443   for (i=0;i<MAX_CONNECTIONS;i++)
3444     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3445       return(True);
3446   return(False);
3447 }
3448
3449 /****************************************************************************
3450   reload the services file
3451   **************************************************************************/
3452 BOOL reload_services(BOOL test)
3453 {
3454   BOOL ret;
3455
3456   if (lp_loaded())
3457     {
3458       pstring fname;
3459       pstrcpy(fname,lp_configfile());
3460       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3461         {
3462           pstrcpy(servicesf,fname);
3463           test = False;
3464         }
3465     }
3466
3467   reopen_logs();
3468
3469   if (test && !lp_file_list_changed())
3470     return(True);
3471
3472   lp_killunused(snum_used);
3473
3474   ret = lp_load(servicesf,False,False,True);
3475
3476   /* perhaps the config filename is now set */
3477   if (!test)
3478     reload_services(True);
3479
3480   reopen_logs();
3481
3482   load_interfaces();
3483
3484   {
3485     extern int Client;
3486     if (Client != -1) {      
3487       set_socket_options(Client,"SO_KEEPALIVE");
3488       set_socket_options(Client,user_socket_options);
3489     }
3490   }
3491
3492   reset_mangled_cache();
3493
3494   /* this forces service parameters to be flushed */
3495   become_service(-1,True);
3496
3497   return(ret);
3498 }
3499
3500
3501
3502 /****************************************************************************
3503 this prevents zombie child processes
3504 ****************************************************************************/
3505 static int sig_hup(void)
3506 {
3507   BlockSignals(True,SIGHUP);
3508   DEBUG(0,("Got SIGHUP\n"));
3509   reload_services(False);
3510 #ifndef DONT_REINSTALL_SIG
3511   signal(SIGHUP,SIGNAL_CAST sig_hup);
3512 #endif
3513   BlockSignals(False,SIGHUP);
3514   return(0);
3515 }
3516
3517
3518 /****************************************************************************
3519   make a connection to a service
3520 ****************************************************************************/
3521 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3522 {
3523   int cnum;
3524   int snum;
3525   struct passwd *pass = NULL;
3526   connection_struct *pcon;
3527   BOOL guest = False;
3528   BOOL force = False;
3529
3530   strlower(service);
3531
3532   snum = find_service(service);
3533   if (snum < 0)
3534     {
3535       extern int Client;
3536       if (strequal(service,"IPC$"))
3537         {         
3538           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3539           return(-3);
3540         }
3541
3542       DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));      
3543       return(-2);
3544     }
3545
3546   if (strequal(service,HOMES_NAME))
3547     {
3548       if (*user && Get_Pwnam(user,True))
3549         return(make_connection(user,user,password,pwlen,dev,vuid));
3550
3551       if(lp_security() != SEC_SHARE)
3552       {
3553         if (validated_username(vuid))
3554         {
3555           pstrcpy(user,validated_username(vuid));
3556           return(make_connection(user,user,password,pwlen,dev,vuid));
3557         }
3558       }
3559       else
3560       {
3561         /*
3562          * Security = share. Try with sesssetup_user as the username.
3563          */
3564         if(*sesssetup_user)
3565         {
3566           pstrcpy(user,sesssetup_user);
3567           return(make_connection(user,user,password,pwlen,dev,vuid));
3568         }
3569       }
3570     }
3571
3572   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3573     return(-4);
3574   }
3575
3576   /* you can only connect to the IPC$ service as an ipc device */
3577   if (strequal(service,"IPC$"))
3578     pstrcpy(dev,"IPC");
3579
3580   if (*dev == '?' || !*dev)
3581     {
3582       if (lp_print_ok(snum))
3583         pstrcpy(dev,"LPT1:");
3584       else
3585         pstrcpy(dev,"A:");
3586     }
3587
3588   /* if the request is as a printer and you can't print then refuse */
3589   strupper(dev);
3590   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3591     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3592     return(-6);
3593   }
3594
3595   /* lowercase the user name */
3596   strlower(user);
3597
3598   /* add it as a possible user name */
3599   add_session_user(service);
3600
3601   /* shall we let them in? */
3602   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3603     {
3604       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3605       return(-1);
3606     }
3607   
3608   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3609   if (cnum < 0)
3610     {
3611       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3612       return(-1);
3613     }
3614
3615   pcon = &Connections[cnum];
3616   bzero((char *)pcon,sizeof(*pcon));
3617
3618   /* find out some info about the user */
3619   pass = Get_Pwnam(user,True);
3620
3621   if (pass == NULL)
3622     {
3623       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3624       return(-7);
3625     }
3626
3627   pcon->read_only = lp_readonly(snum);
3628
3629   {
3630     pstring list;
3631     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3632     string_sub(list,"%S",service);
3633
3634     if (user_in_list(user,list))
3635       pcon->read_only = True;
3636
3637     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3638     string_sub(list,"%S",service);
3639
3640     if (user_in_list(user,list))
3641       pcon->read_only = False;    
3642   }
3643
3644   /* admin user check */
3645
3646   /* JRA - original code denied admin user if the share was
3647      marked read_only. Changed as I don't think this is needed,
3648      but old code left in case there is a problem here.
3649    */
3650   if (user_in_list(user,lp_admin_users(snum)) 
3651 #if 0
3652       && !pcon->read_only)
3653 #else
3654       )
3655 #endif
3656     {
3657       pcon->admin_user = True;
3658       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3659     }
3660   else
3661     pcon->admin_user = False;
3662     
3663   pcon->force_user = force;
3664   pcon->vuid = vuid;
3665   pcon->uid = pass->pw_uid;
3666   pcon->gid = pass->pw_gid;
3667   pcon->num_files_open = 0;
3668   pcon->lastused = time(NULL);
3669   pcon->service = snum;
3670   pcon->used = True;
3671   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3672   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3673   pcon->dirptr = NULL;
3674   pcon->veto_list = NULL;
3675   pcon->hide_list = NULL;
3676   pcon->veto_oplock_list = NULL;
3677   string_set(&pcon->dirpath,"");
3678   string_set(&pcon->user,user);
3679
3680 #if HAVE_GETGRNAM 
3681   if (*lp_force_group(snum))
3682     {
3683       struct group *gptr;
3684       pstring gname;
3685
3686       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3687       /* default service may be a group name            */
3688       string_sub(gname,"%S",service);
3689       gptr = (struct group *)getgrnam(gname);
3690
3691       if (gptr)
3692         {
3693           pcon->gid = gptr->gr_gid;
3694           DEBUG(3,("Forced group %s\n",gname));
3695         }
3696       else
3697         DEBUG(1,("Couldn't find group %s\n",gname));
3698     }
3699 #endif
3700
3701   if (*lp_force_user(snum))
3702     {
3703       struct passwd *pass2;
3704       fstring fuser;
3705       fstrcpy(fuser,lp_force_user(snum));
3706       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3707       if (pass2)
3708         {
3709           pcon->uid = pass2->pw_uid;
3710           string_set(&pcon->user,fuser);
3711           fstrcpy(user,fuser);
3712           pcon->force_user = True;
3713           DEBUG(3,("Forced user %s\n",fuser));    
3714         }
3715       else
3716         DEBUG(1,("Couldn't find user %s\n",fuser));
3717     }
3718
3719   {
3720     pstring s;
3721     pstrcpy(s,lp_pathname(snum));
3722     standard_sub(cnum,s);
3723     string_set(&pcon->connectpath,s);
3724     DEBUG(3,("Connect path is %s\n",s));
3725   }
3726
3727   /* groups stuff added by ih */
3728   pcon->ngroups = 0;
3729   pcon->igroups = NULL;
3730   pcon->groups = NULL;
3731   pcon->attrs = NULL;
3732
3733   if (!IS_IPC(cnum))
3734     {
3735       /* Find all the groups this uid is in and store them. Used by become_user() */
3736       setup_groups(pcon->user,pcon->uid,pcon->gid,
3737                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3738       
3739       /* check number of connections */
3740       if (!claim_connection(cnum,
3741                             lp_servicename(SNUM(cnum)),
3742                             lp_max_connections(SNUM(cnum)),False))
3743         {
3744           DEBUG(1,("too many connections - rejected\n"));
3745           return(-8);
3746         }  
3747
3748       if (lp_status(SNUM(cnum)))
3749         claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3750     } /* IS_IPC */
3751
3752   pcon->open = True;
3753
3754   /* execute any "root preexec = " line */
3755   if (*lp_rootpreexec(SNUM(cnum)))
3756     {
3757       pstring cmd;
3758       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3759       standard_sub(cnum,cmd);
3760       DEBUG(5,("cmd=%s\n",cmd));
3761       smbrun(cmd,NULL,False);
3762     }
3763
3764   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3765     {
3766       DEBUG(0,("Can't become connected user!\n"));
3767       pcon->open = False;
3768       if (!IS_IPC(cnum)) {
3769         yield_connection(cnum,
3770                          lp_servicename(SNUM(cnum)),
3771                          lp_max_connections(SNUM(cnum)));
3772         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3773       }
3774       return(-1);
3775     }
3776
3777   if (ChDir(pcon->connectpath) != 0)
3778     {
3779       DEBUG(0,("Can't change directory to %s (%s)\n",
3780                pcon->connectpath,strerror(errno)));
3781       pcon->open = False;
3782       unbecome_user();
3783       if (!IS_IPC(cnum)) {
3784         yield_connection(cnum,
3785                          lp_servicename(SNUM(cnum)),
3786                          lp_max_connections(SNUM(cnum)));
3787         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3788       }
3789       return(-5);      
3790     }
3791
3792   string_set(&pcon->origpath,pcon->connectpath);
3793
3794 #if SOFTLINK_OPTIMISATION
3795   /* resolve any soft links early */
3796   {
3797     pstring s;
3798     pstrcpy(s,pcon->connectpath);
3799     GetWd(s);
3800     string_set(&pcon->connectpath,s);
3801     ChDir(pcon->connectpath);
3802   }
3803 #endif
3804
3805   num_connections_open++;
3806   add_session_user(user);
3807   
3808   /* execute any "preexec = " line */
3809   if (*lp_preexec(SNUM(cnum)))
3810     {
3811       pstring cmd;
3812       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3813       standard_sub(cnum,cmd);
3814       smbrun(cmd,NULL,False);
3815     }
3816   
3817   /* we've finished with the sensitive stuff */
3818   unbecome_user();
3819
3820   /* Add veto/hide lists */
3821   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3822   {
3823     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3824     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3825     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3826   }
3827
3828   {
3829     extern int Client;
3830     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3831                             timestring(),
3832                             remote_machine,
3833                             client_addr(Client),
3834                             lp_servicename(SNUM(cnum)),user,
3835                             pcon->uid,
3836                             pcon->gid,
3837                             (int)getpid()));
3838   }
3839
3840   return(cnum);
3841 }
3842
3843 /****************************************************************************
3844   Attempt to break an oplock on a file (if oplocked).
3845   Returns True if the file was closed as a result of
3846   the oplock break, False otherwise.
3847   Used as a last ditch attempt to free a space in the 
3848   file table when we have run out.
3849 ****************************************************************************/
3850
3851 static BOOL attempt_close_oplocked_file(files_struct *fp)
3852 {
3853
3854   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3855
3856   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3857
3858     /* Try and break the oplock. */
3859     file_fd_struct *fsp = fp->fd_ptr;
3860     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3861       if(!fp->open) /* Did the oplock break close the file ? */
3862         return True;
3863     }
3864   }
3865
3866   return False;
3867 }
3868
3869 /****************************************************************************
3870   find first available file slot
3871 ****************************************************************************/
3872 int find_free_file(void )
3873 {
3874         int i;
3875         static int first_file;
3876
3877         /* we want to give out file handles differently on each new
3878            connection because of a common bug in MS clients where they try to
3879            reuse a file descriptor from an earlier smb connection. This code
3880            increases the chance that the errant client will get an error rather
3881            than causing corruption */
3882         if (first_file == 0) {
3883                 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3884                 if (first_file == 0) first_file = 1;
3885         }
3886
3887         if (first_file >= MAX_OPEN_FILES)
3888                 first_file = 1;
3889
3890         for (i=first_file;i<MAX_OPEN_FILES;i++)
3891                 if (!Files[i].open && !Files[i].reserved) {
3892                         memset(&Files[i], 0, sizeof(Files[i]));
3893                         first_file = i+1;
3894                         Files[i].reserved = True;
3895                         return(i);
3896                 }
3897
3898         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3899         for (i=1;i<first_file;i++)
3900                 if (!Files[i].open && !Files[i].reserved) {
3901                         memset(&Files[i], 0, sizeof(Files[i]));
3902                         first_file = i+1;
3903                         Files[i].reserved = True;
3904                         return(i);
3905                 }
3906
3907         /* 
3908          * Before we give up, go through the open files 
3909          * and see if there are any files opened with a
3910          * batch oplock. If so break the oplock and then
3911          * re-use that entry (if it becomes closed).
3912          * This may help as NT/95 clients tend to keep
3913          * files batch oplocked for quite a long time
3914          * after they have finished with them.
3915          */
3916         for (i=first_file;i<MAX_OPEN_FILES;i++) {
3917           if(attempt_close_oplocked_file( &Files[i])) {
3918             memset(&Files[i], 0, sizeof(Files[i]));
3919             first_file = i+1;
3920             Files[i].reserved = True;
3921             return(i);
3922           }
3923         }
3924
3925         for (i=1;i<MAX_OPEN_FILES;i++) {
3926           if(attempt_close_oplocked_file( &Files[i])) {
3927             memset(&Files[i], 0, sizeof(Files[i]));
3928             first_file = i+1;
3929             Files[i].reserved = True;
3930             return(i);
3931           }
3932         }
3933
3934         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3935         return(-1);
3936 }
3937
3938 /****************************************************************************
3939   find first available connection slot, starting from a random position.
3940 The randomisation stops problems with the server dieing and clients
3941 thinking the server is still available.
3942 ****************************************************************************/
3943 static int find_free_connection(int hash )
3944 {
3945   int i;
3946   BOOL used=False;
3947   hash = (hash % (MAX_CONNECTIONS-2))+1;
3948
3949  again:
3950
3951   for (i=hash+1;i!=hash;)
3952     {
3953       if (!Connections[i].open && Connections[i].used == used) 
3954         {
3955           DEBUG(3,("found free connection number %d\n",i));
3956           return(i);
3957         }
3958       i++;
3959       if (i == MAX_CONNECTIONS)
3960         i = 1;
3961     }
3962
3963   if (!used)
3964     {
3965       used = !used;
3966       goto again;
3967     }
3968
3969   DEBUG(1,("ERROR! Out of connection structures\n"));
3970   return(-1);
3971 }
3972
3973
3974 /****************************************************************************
3975 reply for the core protocol
3976 ****************************************************************************/
3977 int reply_corep(char *outbuf)
3978 {
3979   int outsize = set_message(outbuf,1,0,True);
3980
3981   Protocol = PROTOCOL_CORE;
3982
3983   return outsize;
3984 }
3985
3986
3987 /****************************************************************************
3988 reply for the coreplus protocol
3989 ****************************************************************************/
3990 int reply_coreplus(char *outbuf)
3991 {
3992   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3993   int outsize = set_message(outbuf,13,0,True);
3994   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3995                                  readbraw and writebraw (possibly) */
3996   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3997   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3998
3999   Protocol = PROTOCOL_COREPLUS;
4000
4001   return outsize;
4002 }
4003
4004
4005 /****************************************************************************
4006 reply for the lanman 1.0 protocol
4007 ****************************************************************************/
4008 int reply_lanman1(char *outbuf)
4009 {
4010   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4011   int secword=0;
4012   BOOL doencrypt = SMBENCRYPT();
4013   time_t t = time(NULL);
4014
4015   if (lp_security()>=SEC_USER) secword |= 1;
4016   if (doencrypt) secword |= 2;
4017
4018   set_message(outbuf,13,doencrypt?8:0,True);
4019   SSVAL(outbuf,smb_vwv1,secword); 
4020   /* Create a token value and add it to the outgoing packet. */
4021   if (doencrypt) 
4022     generate_next_challenge(smb_buf(outbuf));
4023
4024   Protocol = PROTOCOL_LANMAN1;
4025
4026   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4027   SSVAL(outbuf,smb_vwv2,max_recv);
4028   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
4029   SSVAL(outbuf,smb_vwv4,1);
4030   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
4031                                  readbraw writebraw (possibly) */
4032   SIVAL(outbuf,smb_vwv6,getpid());
4033   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4034
4035   put_dos_date(outbuf,smb_vwv8,t);
4036
4037   return (smb_len(outbuf)+4);
4038 }
4039
4040
4041 /****************************************************************************
4042 reply for the lanman 2.0 protocol
4043 ****************************************************************************/
4044 int reply_lanman2(char *outbuf)
4045 {
4046   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
4047   int secword=0;
4048   BOOL doencrypt = SMBENCRYPT();
4049   time_t t = time(NULL);
4050   struct cli_state *cli = NULL;
4051   char cryptkey[8];
4052   char crypt_len = 0;
4053
4054   if (lp_security() == SEC_SERVER) {
4055           cli = server_cryptkey();
4056   }
4057
4058   if (cli) {
4059           DEBUG(3,("using password server validation\n"));
4060           doencrypt = ((cli->sec_mode & 2) != 0);
4061   }
4062
4063   if (lp_security()>=SEC_USER) secword |= 1;
4064   if (doencrypt) secword |= 2;
4065
4066   if (doencrypt) {
4067           crypt_len = 8;
4068           if (!cli) {
4069                   generate_next_challenge(cryptkey);
4070           } else {
4071                   memcpy(cryptkey, cli->cryptkey, 8);
4072                   set_challenge(cli->cryptkey);
4073           }
4074   }
4075
4076   set_message(outbuf,13,crypt_len,True);
4077   SSVAL(outbuf,smb_vwv1,secword); 
4078   SIVAL(outbuf,smb_vwv6,getpid());
4079   if (doencrypt) 
4080           memcpy(smb_buf(outbuf), cryptkey, 8);
4081
4082   Protocol = PROTOCOL_LANMAN2;
4083
4084   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
4085   SSVAL(outbuf,smb_vwv2,max_recv);
4086   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
4087   SSVAL(outbuf,smb_vwv4,1);
4088   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
4089   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
4090   put_dos_date(outbuf,smb_vwv8,t);
4091
4092   return (smb_len(outbuf)+4);
4093 }
4094
4095
4096 /****************************************************************************
4097 reply for the nt protocol
4098 ****************************************************************************/
4099 int reply_nt1(char *outbuf)
4100 {
4101   /* dual names + lock_and_read + nt SMBs + remote API calls */
4102   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
4103 /*
4104   other valid capabilities which we may support at some time...
4105                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
4106                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
4107  */
4108
4109   int secword=0;
4110   BOOL doencrypt = SMBENCRYPT();
4111   time_t t = time(NULL);
4112   int data_len;
4113   struct cli_state *cli = NULL;
4114   char cryptkey[8];
4115   char crypt_len = 0;
4116
4117   if (lp_security() == SEC_SERVER) {
4118           cli = server_cryptkey();
4119   }
4120
4121   if (cli) {
4122           DEBUG(3,("using password server validation\n"));
4123           doencrypt = ((cli->sec_mode & 2) != 0);
4124   }
4125
4126   if (doencrypt) {
4127           crypt_len = 8;
4128           if (!cli) {
4129                   generate_next_challenge(cryptkey);
4130           } else {
4131                   memcpy(cryptkey, cli->cryptkey, 8);
4132                   set_challenge(cli->cryptkey);
4133           }
4134   }
4135
4136   if (lp_readraw() && lp_writeraw()) {
4137           capabilities |= CAP_RAW_MODE;
4138   }
4139
4140   if (lp_security() >= SEC_USER) secword |= 1;
4141   if (doencrypt) secword |= 2;
4142
4143   /* decide where (if) to put the encryption challenge, and
4144      follow it with the OEM'd domain name
4145    */
4146   data_len = crypt_len + strlen(global_myworkgroup) + 1;
4147
4148   set_message(outbuf,17,data_len,True);
4149   pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
4150
4151   CVAL(outbuf,smb_vwv1) = secword;
4152   SSVALS(outbuf,smb_vwv16+1,crypt_len);
4153   if (doencrypt) 
4154           memcpy(smb_buf(outbuf), cryptkey, 8);
4155
4156   Protocol = PROTOCOL_NT1;
4157
4158   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4159   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4160   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4161   SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4162   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4163   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4164   put_long_date(outbuf+smb_vwv11+1,t);
4165   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4166   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4167
4168   return (smb_len(outbuf)+4);
4169 }
4170
4171 /* these are the protocol lists used for auto architecture detection:
4172
4173 WinNT 3.51:
4174 protocol [PC NETWORK PROGRAM 1.0]
4175 protocol [XENIX CORE]
4176 protocol [MICROSOFT NETWORKS 1.03]
4177 protocol [LANMAN1.0]
4178 protocol [Windows for Workgroups 3.1a]
4179 protocol [LM1.2X002]
4180 protocol [LANMAN2.1]
4181 protocol [NT LM 0.12]
4182
4183 Win95:
4184 protocol [PC NETWORK PROGRAM 1.0]
4185 protocol [XENIX CORE]
4186 protocol [MICROSOFT NETWORKS 1.03]
4187 protocol [LANMAN1.0]
4188 protocol [Windows for Workgroups 3.1a]
4189 protocol [LM1.2X002]
4190 protocol [LANMAN2.1]
4191 protocol [NT LM 0.12]
4192
4193 OS/2:
4194 protocol [PC NETWORK PROGRAM 1.0]
4195 protocol [XENIX CORE]
4196 protocol [LANMAN1.0]
4197 protocol [LM1.2X002]
4198 protocol [LANMAN2.1]
4199 */
4200
4201 /*
4202   * Modified to recognize the architecture of the remote machine better.
4203   *
4204   * This appears to be the matrix of which protocol is used by which
4205   * MS product.
4206        Protocol                       WfWg    Win95   WinNT  OS/2
4207        PC NETWORK PROGRAM 1.0          1       1       1      1
4208        XENIX CORE                                      2      2
4209        MICROSOFT NETWORKS 3.0          2       2       
4210        DOS LM1.2X002                   3       3       
4211        MICROSOFT NETWORKS 1.03                         3
4212        DOS LANMAN2.1                   4       4       
4213        LANMAN1.0                                       4      3
4214        Windows for Workgroups 3.1a     5       5       5
4215        LM1.2X002                                       6      4
4216        LANMAN2.1                                       7      5
4217        NT LM 0.12                              6       8
4218   *
4219   *  tim@fsg.com 09/29/95
4220   */
4221   
4222 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4223 #define ARCH_WIN95    0x2
4224 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4225 #define ARCH_WINNT    0x8
4226 #define ARCH_SAMBA    0x10
4227  
4228 #define ARCH_ALL      0x1F
4229  
4230 /* List of supported protocols, most desired first */
4231 struct {
4232   char *proto_name;
4233   char *short_name;
4234   int (*proto_reply_fn)(char *);
4235   int protocol_level;
4236 } supported_protocols[] = {
4237   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4238   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4239   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4240   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4241   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4242   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4243   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4244   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4245   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4246   {NULL,NULL},
4247 };
4248
4249
4250 /****************************************************************************
4251   reply to a negprot
4252 ****************************************************************************/
4253 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4254 {
4255   int outsize = set_message(outbuf,1,0,True);
4256   int Index=0;
4257   int choice= -1;
4258   int protocol;
4259   char *p;
4260   int bcc = SVAL(smb_buf(inbuf),-2);
4261   int arch = ARCH_ALL;
4262
4263   p = smb_buf(inbuf)+1;
4264   while (p < (smb_buf(inbuf) + bcc))
4265     { 
4266       Index++;
4267       DEBUG(3,("Requested protocol [%s]\n",p));
4268       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4269         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4270       else if (strcsequal(p,"DOS LM1.2X002"))
4271         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4272       else if (strcsequal(p,"DOS LANMAN2.1"))
4273         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4274       else if (strcsequal(p,"NT LM 0.12"))
4275         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4276       else if (strcsequal(p,"LANMAN2.1"))
4277         arch &= ( ARCH_WINNT | ARCH_OS2 );
4278       else if (strcsequal(p,"LM1.2X002"))
4279         arch &= ( ARCH_WINNT | ARCH_OS2 );
4280       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4281         arch &= ARCH_WINNT;
4282       else if (strcsequal(p,"XENIX CORE"))
4283         arch &= ( ARCH_WINNT | ARCH_OS2 );
4284       else if (strcsequal(p,"Samba")) {
4285         arch = ARCH_SAMBA;
4286         break;
4287       }
4288  
4289       p += strlen(p) + 2;
4290     }
4291     
4292   switch ( arch ) {
4293   case ARCH_SAMBA:
4294     set_remote_arch(RA_SAMBA);
4295     break;
4296   case ARCH_WFWG:
4297     set_remote_arch(RA_WFWG);
4298     break;
4299   case ARCH_WIN95:
4300     set_remote_arch(RA_WIN95);
4301     break;
4302   case ARCH_WINNT:
4303     set_remote_arch(RA_WINNT);
4304     break;
4305   case ARCH_OS2:
4306     set_remote_arch(RA_OS2);
4307     break;
4308   default:
4309     set_remote_arch(RA_UNKNOWN);
4310     break;
4311   }
4312  
4313   /* possibly reload - change of architecture */
4314   reload_services(True);      
4315     
4316   /* a special case to stop password server loops */
4317   if (Index == 1 && strequal(remote_machine,myhostname) && 
4318       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4319     exit_server("Password server loop!");
4320   
4321   /* Check for protocols, most desirable first */
4322   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4323     {
4324       p = smb_buf(inbuf)+1;
4325       Index = 0;
4326       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4327         while (p < (smb_buf(inbuf) + bcc))
4328           { 
4329             if (strequal(p,supported_protocols[protocol].proto_name))
4330               choice = Index;
4331             Index++;
4332             p += strlen(p) + 2;
4333           }
4334       if(choice != -1)
4335         break;
4336     }
4337   
4338   SSVAL(outbuf,smb_vwv0,choice);
4339   if(choice != -1) {
4340     extern fstring remote_proto;
4341     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4342     reload_services(True);          
4343     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4344     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4345   }
4346   else {
4347     DEBUG(0,("No protocol supported !\n"));
4348   }
4349   SSVAL(outbuf,smb_vwv0,choice);
4350   
4351   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4352
4353   return(outsize);
4354 }
4355
4356
4357 /****************************************************************************
4358 close all open files for a connection
4359 ****************************************************************************/
4360 static void close_open_files(int cnum)
4361 {
4362   int i;
4363   for (i=0;i<MAX_OPEN_FILES;i++)
4364     if( Files[i].cnum == cnum && Files[i].open) {
4365       close_file(i,False);
4366     }
4367 }
4368
4369
4370
4371 /****************************************************************************
4372 close a cnum
4373 ****************************************************************************/
4374 void close_cnum(int cnum, uint16 vuid)
4375 {
4376   extern int Client;
4377   DirCacheFlush(SNUM(cnum));
4378
4379   unbecome_user();
4380
4381   if (!OPEN_CNUM(cnum))
4382     {
4383       DEBUG(0,("Can't close cnum %d\n",cnum));
4384       return;
4385     }
4386
4387   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4388                           timestring(),
4389                           remote_machine,client_addr(Client),
4390                           lp_servicename(SNUM(cnum))));
4391
4392   yield_connection(cnum,
4393                    lp_servicename(SNUM(cnum)),
4394                    lp_max_connections(SNUM(cnum)));
4395
4396   if (lp_status(SNUM(cnum)))
4397     yield_connection(cnum,"STATUS.",MAXSTATUS);
4398
4399   close_open_files(cnum);
4400   dptr_closecnum(cnum);
4401
4402   /* execute any "postexec = " line */
4403   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4404     {
4405       pstring cmd;
4406       pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4407       standard_sub(cnum,cmd);
4408       smbrun(cmd,NULL,False);
4409       unbecome_user();
4410     }
4411
4412   unbecome_user();
4413   /* execute any "root postexec = " line */
4414   if (*lp_rootpostexec(SNUM(cnum)))
4415     {
4416       pstring cmd;
4417       pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4418       standard_sub(cnum,cmd);
4419       smbrun(cmd,NULL,False);
4420     }
4421
4422   Connections[cnum].open = False;
4423   num_connections_open--;
4424   if (Connections[cnum].ngroups && Connections[cnum].groups)
4425     {
4426       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4427         free(Connections[cnum].groups);
4428       free(Connections[cnum].igroups);
4429       Connections[cnum].groups = NULL;
4430       Connections[cnum].igroups = NULL;
4431       Connections[cnum].ngroups = 0;
4432     }
4433
4434   free_namearray(Connections[cnum].veto_list);
4435   free_namearray(Connections[cnum].hide_list);
4436   free_namearray(Connections[cnum].veto_oplock_list);
4437
4438   string_set(&Connections[cnum].user,"");
4439   string_set(&Connections[cnum].dirpath,"");
4440   string_set(&Connections[cnum].connectpath,"");
4441 }
4442
4443
4444
4445 #if DUMP_CORE
4446 /*******************************************************************
4447 prepare to dump a core file - carefully!
4448 ********************************************************************/
4449 static BOOL dump_core(void)
4450 {
4451   char *p;
4452   pstring dname;
4453   pstrcpy(dname,debugf);
4454   if ((p=strrchr(dname,'/'))) *p=0;
4455   pstrcat(dname,"/corefiles");
4456   mkdir(dname,0700);
4457   sys_chown(dname,getuid(),getgid());
4458   chmod(dname,0700);
4459   if (chdir(dname)) return(False);
4460   umask(~(0700));
4461
4462 #ifndef NO_GETRLIMIT
4463 #ifdef RLIMIT_CORE
4464   {
4465     struct rlimit rlp;
4466     getrlimit(RLIMIT_CORE, &rlp);
4467     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4468     setrlimit(RLIMIT_CORE, &rlp);
4469     getrlimit(RLIMIT_CORE, &rlp);
4470     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4471   }
4472 #endif
4473 #endif
4474
4475
4476   DEBUG(0,("Dumping core in %s\n",dname));
4477   return(True);
4478 }
4479 #endif
4480
4481 /****************************************************************************
4482 exit the server
4483 ****************************************************************************/
4484 void exit_server(char *reason)
4485 {
4486   static int firsttime=1;
4487   int i;
4488
4489   if (!firsttime) exit(0);
4490   firsttime = 0;
4491
4492   unbecome_user();
4493   DEBUG(2,("Closing connections\n"));
4494   for (i=0;i<MAX_CONNECTIONS;i++)
4495     if (Connections[i].open)
4496       close_cnum(i,(uint16)-1);
4497 #ifdef DFS_AUTH
4498   if (dcelogin_atmost_once)
4499     dfs_unlogin();
4500 #endif
4501   if (!reason) {   
4502     int oldlevel = DEBUGLEVEL;
4503     DEBUGLEVEL = 10;
4504     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4505     if (last_inbuf)
4506       show_msg(last_inbuf);
4507     DEBUGLEVEL = oldlevel;
4508     DEBUG(0,("===============================================================\n"));
4509 #if DUMP_CORE
4510     if (dump_core()) return;
4511 #endif
4512   }    
4513
4514   locking_end();
4515
4516   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4517   exit(0);
4518 }
4519
4520 /****************************************************************************
4521 do some standard substitutions in a string
4522 ****************************************************************************/
4523 void standard_sub(int cnum,char *str)
4524 {
4525   if (VALID_CNUM(cnum)) {
4526     char *p, *s, *home;
4527
4528     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4529       switch (*(p+1)) {
4530         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4531                      string_sub(p,"%H",home);
4532                    else
4533                      p += 2;
4534                    break;
4535         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4536         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4537         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4538         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4539         /* 
4540          * Patch from jkf@soton.ac.uk
4541          * Left the %N (NIS server name) in standard_sub_basic as it
4542          * is a feature for logon servers, hence uses the username.
4543          * The %p (NIS server path) code is here as it is used
4544          * instead of the default "path =" string in [homes] and so
4545          * needs the service name, not the username. 
4546          */
4547         case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4548         case '\0' : p++; break; /* don't run off the end of the string */
4549         default  : p+=2; break;
4550       }
4551     }
4552   }
4553   standard_sub_basic(str);
4554 }
4555
4556 /*
4557 These flags determine some of the permissions required to do an operation 
4558
4559 Note that I don't set NEED_WRITE on some write operations because they
4560 are used by some brain-dead clients when printing, and I don't want to
4561 force write permissions on print services.
4562 */
4563 #define AS_USER (1<<0)
4564 #define NEED_WRITE (1<<1)
4565 #define TIME_INIT (1<<2)
4566 #define CAN_IPC (1<<3)
4567 #define AS_GUEST (1<<5)
4568 #define QUEUE_IN_OPLOCK (1<<6)
4569
4570 /* 
4571    define a list of possible SMB messages and their corresponding
4572    functions. Any message that has a NULL function is unimplemented -
4573    please feel free to contribute implementations!
4574 */
4575 struct smb_message_struct
4576 {
4577   int code;
4578   char *name;
4579   int (*fn)(char *, char *, int, int);
4580   int flags;
4581 #if PROFILING
4582   unsigned long time;
4583 #endif
4584 }
4585  smb_messages[] = {
4586
4587     /* CORE PROTOCOL */
4588
4589    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4590    {SMBtcon,"SMBtcon",reply_tcon,0},
4591    {SMBtdis,"SMBtdis",reply_tdis,0},
4592    {SMBexit,"SMBexit",reply_exit,0},
4593    {SMBioctl,"SMBioctl",reply_ioctl,0},
4594    {SMBecho,"SMBecho",reply_echo,0},
4595    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4596    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4597    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4598    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4599    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4600    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4601    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4602    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4603
4604    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4605    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4606    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4607
4608    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4609    {SMBread,"SMBread",reply_read,AS_USER},
4610    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4611    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4612    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4613    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4614    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4615    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4616
4617    /* this is a Pathworks specific call, allowing the 
4618       changing of the root path */
4619    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4620
4621    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4622    {SMBflush,"SMBflush",reply_flush,AS_USER},
4623    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4624    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4625    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4626    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4627    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4628    {SMBlock,"SMBlock",reply_lock,AS_USER},
4629    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4630    
4631    /* CORE+ PROTOCOL FOLLOWS */
4632    
4633    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4634    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4635    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4636    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4637    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4638    
4639    /* LANMAN1.0 PROTOCOL FOLLOWS */
4640    
4641    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4642    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4643    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4644    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4645    {SMBwritec,"SMBwritec",NULL,AS_USER},
4646    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4647    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4648    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4649    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4650    {SMBioctls,"SMBioctls",NULL,AS_USER},
4651    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4652    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4653    
4654    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4655    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4656    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4657    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4658    
4659    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4660    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4661    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4662
4663    /* LANMAN2.0 PROTOCOL FOLLOWS */
4664    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4665    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4666    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4667    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4668
4669    /* messaging routines */
4670    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4671    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4672    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4673    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4674
4675    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4676    
4677    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4678    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4679    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4680    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4681  };
4682
4683 /****************************************************************************
4684 return a string containing the function name of a SMB command
4685 ****************************************************************************/
4686 char *smb_fn_name(int type)
4687 {
4688   static char *unknown_name = "SMBunknown";
4689   static int num_smb_messages = 
4690     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4691   int match;
4692
4693   for (match=0;match<num_smb_messages;match++)
4694     if (smb_messages[match].code == type)
4695       break;
4696
4697   if (match == num_smb_messages)
4698     return(unknown_name);
4699
4700   return(smb_messages[match].name);
4701 }
4702
4703
4704 /****************************************************************************
4705 do a switch on the message type, and return the response size
4706 ****************************************************************************/
4707 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4708 {
4709   static int pid= -1;
4710   int outsize = 0;
4711   static int num_smb_messages = 
4712     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4713   int match;
4714
4715 #if PROFILING
4716   struct timeval msg_start_time;
4717   struct timeval msg_end_time;
4718   static unsigned long total_time = 0;
4719
4720   GetTimeOfDay(&msg_start_time);
4721 #endif
4722
4723   if (pid == -1)
4724     pid = getpid();
4725
4726   errno = 0;
4727   last_message = type;
4728
4729   /* make sure this is an SMB packet */
4730   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4731     {
4732       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4733       return(-1);
4734     }
4735
4736   for (match=0;match<num_smb_messages;match++)
4737     if (smb_messages[match].code == type)
4738       break;
4739
4740   if (match == num_smb_messages)
4741     {
4742       DEBUG(0,("Unknown message type %d!\n",type));
4743       outsize = reply_unknown(inbuf,outbuf);
4744     }
4745   else
4746     {
4747       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4748
4749       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4750       {
4751         /* 
4752          * Queue this message as we are the process of an oplock break.
4753          */
4754
4755         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4756                timestring() ));
4757
4758         push_smb_message( inbuf, size);
4759         return -1;
4760       }          
4761
4762       if (smb_messages[match].fn)
4763         {
4764           int cnum = SVAL(inbuf,smb_tid);
4765           int flags = smb_messages[match].flags;
4766           static uint16 last_session_tag = UID_FIELD_INVALID;
4767           /* In share mode security we must ignore the vuid. */
4768           uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4769           /* Ensure this value is replaced in the incoming packet. */
4770           SSVAL(inbuf,smb_uid,session_tag);
4771
4772           /*
4773            * Ensure the correct username is in sesssetup_user.
4774            * This is a really ugly bugfix for problems with
4775            * multiple session_setup_and_X's being done and
4776            * allowing %U and %G substitutions to work correctly.
4777            * There is a reason this code is done here, don't
4778            * move it unless you know what you're doing... :-).
4779            * JRA.
4780            */
4781           if(session_tag != last_session_tag ) {
4782             user_struct *vuser = NULL;
4783
4784             last_session_tag = session_tag;
4785             if(session_tag != UID_FIELD_INVALID)
4786               vuser = get_valid_user_struct(session_tag);           
4787             if(vuser != NULL)
4788               pstrcpy( sesssetup_user, vuser->requested_name);
4789           }
4790
4791           /* does this protocol need to be run as root? */
4792           if (!(flags & AS_USER))
4793             unbecome_user();
4794
4795           /* does this protocol need to be run as the connected user? */
4796           if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4797             if (flags & AS_GUEST) 
4798               flags &= ~AS_USER;
4799             else
4800               return(ERROR(ERRSRV,ERRinvnid));
4801           }
4802           /* this code is to work around a bug is MS client 3 without
4803              introducing a security hole - it needs to be able to do
4804              print queue checks as guest if it isn't logged in properly */
4805           if (flags & AS_USER)
4806             flags &= ~AS_GUEST;
4807
4808           /* does it need write permission? */
4809           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4810             return(ERROR(ERRSRV,ERRaccess));
4811
4812           /* ipc services are limited */
4813           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4814             return(ERROR(ERRSRV,ERRaccess));        
4815
4816           /* load service specific parameters */
4817           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4818             return(ERROR(ERRSRV,ERRaccess));
4819
4820           /* does this protocol need to be run as guest? */
4821           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4822             return(ERROR(ERRSRV,ERRaccess));
4823
4824           last_inbuf = inbuf;
4825
4826           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4827         }
4828       else
4829         {
4830           outsize = reply_unknown(inbuf,outbuf);
4831         }
4832     }
4833
4834 #if PROFILING
4835   GetTimeOfDay(&msg_end_time);
4836   if (!(smb_messages[match].flags & TIME_INIT))
4837     {
4838       smb_messages[match].time = 0;
4839       smb_messages[match].flags |= TIME_INIT;
4840     }
4841   {
4842     unsigned long this_time =     
4843       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4844         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4845     smb_messages[match].time += this_time;
4846     total_time += this_time;
4847   }
4848   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4849            smb_fn_name(type),smb_messages[match].time,
4850         (100.0*smb_messages[match].time) / total_time));
4851 #endif
4852
4853   return(outsize);
4854 }
4855
4856
4857 /****************************************************************************
4858   construct a chained reply and add it to the already made reply
4859   **************************************************************************/
4860 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4861 {
4862   static char *orig_inbuf;
4863   static char *orig_outbuf;
4864   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4865   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4866   char *inbuf2, *outbuf2;
4867   int outsize2;
4868   char inbuf_saved[smb_wct];
4869   char outbuf_saved[smb_wct];
4870   extern int chain_size;
4871   int wct = CVAL(outbuf,smb_wct);
4872   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4873
4874   /* maybe its not chained */
4875   if (smb_com2 == 0xFF) {
4876     CVAL(outbuf,smb_vwv0) = 0xFF;
4877     return outsize;
4878   }
4879
4880   if (chain_size == 0) {
4881     /* this is the first part of the chain */
4882     orig_inbuf = inbuf;
4883     orig_outbuf = outbuf;
4884   }
4885
4886   /* we need to tell the client where the next part of the reply will be */
4887   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4888   CVAL(outbuf,smb_vwv0) = smb_com2;
4889
4890   /* remember how much the caller added to the chain, only counting stuff
4891      after the parameter words */
4892   chain_size += outsize - smb_wct;
4893
4894   /* work out pointers into the original packets. The
4895      headers on these need to be filled in */
4896   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4897   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4898
4899   /* remember the original command type */
4900   smb_com1 = CVAL(orig_inbuf,smb_com);
4901
4902   /* save the data which will be overwritten by the new headers */
4903   memcpy(inbuf_saved,inbuf2,smb_wct);
4904   memcpy(outbuf_saved,outbuf2,smb_wct);
4905
4906   /* give the new packet the same header as the last part of the SMB */
4907   memmove(inbuf2,inbuf,smb_wct);
4908
4909   /* create the in buffer */
4910   CVAL(inbuf2,smb_com) = smb_com2;
4911
4912   /* create the out buffer */
4913   bzero(outbuf2,smb_size);
4914   set_message(outbuf2,0,0,True);
4915   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4916   
4917   memcpy(outbuf2+4,inbuf2+4,4);
4918   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4919   CVAL(outbuf2,smb_reh) = 0;
4920   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4921                                                                   means a reply */
4922   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4923   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4924   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4925   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4926   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4927   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4928
4929   DEBUG(3,("Chained message\n"));
4930   show_msg(inbuf2);
4931
4932   /* process the request */
4933   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4934                             bufsize-chain_size);
4935
4936   /* copy the new reply and request headers over the old ones, but
4937      preserve the smb_com field */
4938   memmove(orig_outbuf,outbuf2,smb_wct);
4939   CVAL(orig_outbuf,smb_com) = smb_com1;
4940
4941   /* restore the saved data, being careful not to overwrite any
4942    data from the reply header */
4943   memcpy(inbuf2,inbuf_saved,smb_wct);
4944   {
4945     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4946     if (ofs < 0) ofs = 0;
4947     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4948   }
4949
4950   return outsize2;
4951 }
4952
4953
4954
4955 /****************************************************************************
4956   construct a reply to the incoming packet
4957 ****************************************************************************/
4958 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4959 {
4960   int type = CVAL(inbuf,smb_com);
4961   int outsize = 0;
4962   int msg_type = CVAL(inbuf,0);
4963   extern int chain_size;
4964
4965   smb_last_time = time(NULL);
4966
4967   chain_size = 0;
4968   chain_fnum = -1;
4969   reset_chain_pnum();
4970
4971   bzero(outbuf,smb_size);
4972
4973   if (msg_type != 0)
4974     return(reply_special(inbuf,outbuf));  
4975
4976   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4977   set_message(outbuf,0,0,True);
4978   
4979   memcpy(outbuf+4,inbuf+4,4);
4980   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4981   CVAL(outbuf,smb_reh) = 0;
4982   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4983                                                              means a reply */
4984   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4985   SSVAL(outbuf,smb_err,SMB_SUCCESS);
4986   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4987   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4988   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4989   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4990
4991   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4992
4993   outsize += chain_size;
4994
4995   if(outsize > 4)
4996     smb_setlen(outbuf,outsize - 4);
4997   return(outsize);
4998 }
4999
5000 /****************************************************************************
5001   process commands from the client
5002 ****************************************************************************/
5003 static void process(void)
5004 {
5005   extern int Client;
5006
5007   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5008   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
5009   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
5010     return;
5011
5012   InBuffer += SMB_ALIGNMENT;
5013   OutBuffer += SMB_ALIGNMENT;
5014
5015 #if PRIME_NMBD
5016   DEBUG(3,("priming nmbd\n"));
5017   {
5018     struct in_addr ip;
5019     ip = *interpret_addr2("localhost");
5020     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
5021     *OutBuffer = 0;
5022     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
5023   }
5024 #endif    
5025
5026   /* re-initialise the timezone */
5027   TimeInit();
5028
5029   while (True)
5030   {
5031     int deadtime = lp_deadtime()*60;
5032     int counter;
5033     int last_keepalive=0;
5034     int service_load_counter = 0;
5035     BOOL got_smb = False;
5036
5037     if (deadtime <= 0)
5038       deadtime = DEFAULT_SMBD_TIMEOUT;
5039
5040 #if USE_READ_PREDICTION
5041     if (lp_readprediction())
5042       do_read_prediction();
5043 #endif
5044
5045     errno = 0;      
5046
5047     for (counter=SMBD_SELECT_LOOP; 
5048           !receive_message_or_smb(Client,oplock_sock,
5049                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
5050           counter += SMBD_SELECT_LOOP)
5051     {
5052       int i;
5053       time_t t;
5054       BOOL allidle = True;
5055       extern int keepalive;
5056
5057       if (counter > 365 * 3600) /* big number of seconds. */
5058       {
5059         counter = 0;
5060         service_load_counter = 0;
5061       }
5062
5063       if (smb_read_error == READ_EOF) 
5064       {
5065         DEBUG(3,("end of file from client\n"));
5066         return;
5067       }
5068
5069       if (smb_read_error == READ_ERROR) 
5070       {
5071         DEBUG(3,("receive_smb error (%s) exiting\n",
5072                   strerror(errno)));
5073         return;
5074       }
5075
5076       t = time(NULL);
5077
5078       /* become root again if waiting */
5079       unbecome_user();
5080
5081       /* check for smb.conf reload */
5082       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5083       {
5084         service_load_counter = counter;
5085
5086         /* reload services, if files have changed. */
5087         reload_services(True);
5088       }
5089
5090       /* automatic timeout if all connections are closed */      
5091       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
5092       {
5093         DEBUG(2,("%s Closing idle connection\n",timestring()));
5094         return;
5095       }
5096
5097       if (keepalive && (counter-last_keepalive)>keepalive) 
5098       {
5099               struct cli_state *cli = server_client();
5100               if (!send_keepalive(Client)) { 
5101                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5102                       return;
5103               }     
5104               /* also send a keepalive to the password server if its still
5105                  connected */
5106               if (cli && cli->initialised)
5107                       send_keepalive(cli->fd);
5108               last_keepalive = counter;
5109       }
5110
5111       /* check for connection timeouts */
5112       for (i=0;i<MAX_CONNECTIONS;i++)
5113         if (Connections[i].open)
5114         {
5115           /* close dirptrs on connections that are idle */
5116           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5117             dptr_idlecnum(i);
5118
5119           if (Connections[i].num_files_open > 0 ||
5120                      (t-Connections[i].lastused)<deadtime)
5121             allidle = False;
5122         }
5123
5124       if (allidle && num_connections_open>0) 
5125       {
5126         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5127         return;
5128       }
5129
5130       if(global_machine_pasword_needs_changing)
5131       {
5132         unsigned char trust_passwd_hash[16];
5133         time_t lct;
5134         pstring remote_machine_list;
5135
5136         /*
5137          * We're in domain level security, and the code that
5138          * read the machine password flagged that the machine
5139          * password needs changing.
5140          */
5141
5142         /*
5143          * First, open the machine password file with an exclusive lock.
5144          */
5145
5146         if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5147           DEBUG(0,("process: unable to open the machine account password file for \
5148 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5149           continue;
5150         }
5151
5152         if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5153           DEBUG(0,("process: unable to read the machine account password for \
5154 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5155           trust_password_unlock();
5156           continue;
5157         }
5158
5159         /*
5160          * Make sure someone else hasn't already done this.
5161          */
5162
5163         if(t < lct + lp_machine_password_timeout()) {
5164           trust_password_unlock();
5165           global_machine_pasword_needs_changing = False;
5166           continue;
5167         }
5168
5169         pstrcpy(remote_machine_list, lp_passwordserver());
5170
5171         change_trust_account_password( global_myworkgroup, remote_machine_list);
5172         trust_password_unlock();
5173         global_machine_pasword_needs_changing = False;
5174       }
5175     }
5176
5177     if(got_smb)
5178       process_smb(InBuffer, OutBuffer);
5179     else
5180       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5181   }
5182 }
5183
5184
5185 /****************************************************************************
5186   initialise connect, service and file structs
5187 ****************************************************************************/
5188 static void init_structs(void )
5189 {
5190   int i;
5191   get_myname(myhostname,NULL);
5192
5193   /*
5194    * Set the machine NETBIOS name if not already
5195    * set from the config file.
5196    */
5197
5198   if (!*global_myname)
5199   {
5200     char *p;
5201     fstrcpy( global_myname, myhostname );
5202     p = strchr( global_myname, '.' );
5203     if (p) 
5204       *p = 0;
5205   }
5206   strupper( global_myname );
5207
5208   for (i=0;i<MAX_CONNECTIONS;i++)
5209     {
5210       Connections[i].open = False;
5211       Connections[i].num_files_open=0;
5212       Connections[i].lastused=0;
5213       Connections[i].used=False;
5214       string_init(&Connections[i].user,"");
5215       string_init(&Connections[i].dirpath,"");
5216       string_init(&Connections[i].connectpath,"");
5217       string_init(&Connections[i].origpath,"");
5218     }
5219
5220   for (i=0;i<MAX_OPEN_FILES;i++)
5221     {
5222       Files[i].open = False;
5223       string_init(&Files[i].name,"");
5224     }
5225
5226   for (i=0;i<MAX_OPEN_FILES;i++)
5227     {
5228       file_fd_struct *fd_ptr = &FileFd[i];
5229       fd_ptr->ref_count = 0;
5230       fd_ptr->dev = (int32)-1;
5231       fd_ptr->inode = (int32)-1;
5232       fd_ptr->fd = -1;
5233       fd_ptr->fd_readonly = -1;
5234       fd_ptr->fd_writeonly = -1;
5235       fd_ptr->real_open_flags = -1;
5236     }
5237
5238   /* for RPC pipes */
5239   init_rpc_pipe_hnd();
5240
5241   /* for LSA handles */
5242   init_lsa_policy_hnd();
5243
5244   init_dptrs();
5245 }
5246
5247 /****************************************************************************
5248 usage on the program
5249 ****************************************************************************/
5250 static void usage(char *pname)
5251 {
5252   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5253
5254   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5255   printf("Version %s\n",VERSION);
5256   printf("\t-D                    become a daemon\n");
5257   printf("\t-p port               listen on the specified port\n");
5258   printf("\t-d debuglevel         set the debuglevel\n");
5259   printf("\t-l log basename.      Basename for log/debug files\n");
5260   printf("\t-s services file.     Filename of services file\n");
5261   printf("\t-P                    passive only\n");
5262   printf("\t-a                    overwrite log file, don't append\n");
5263   printf("\n");
5264 }
5265
5266
5267 /****************************************************************************
5268   main program
5269 ****************************************************************************/
5270  int main(int argc,char *argv[])
5271 {
5272   extern BOOL append_log;
5273   /* shall I run as a daemon */
5274   BOOL is_daemon = False;
5275   int port = SMB_PORT;
5276   int opt;
5277   extern char *optarg;
5278
5279 #ifdef NEED_AUTH_PARAMETERS
5280   set_auth_parameters(argc,argv);
5281 #endif
5282
5283 #ifdef SecureWare
5284   setluid(0);
5285 #endif
5286
5287   append_log = True;
5288
5289   TimeInit();
5290
5291   pstrcpy(debugf,SMBLOGFILE);  
5292
5293   pstrcpy(remote_machine, "smb");
5294
5295   setup_logging(argv[0],False);
5296
5297   charset_initialise();
5298
5299   /* make absolutely sure we run as root - to handle cases where people
5300      are crazy enough to have it setuid */
5301 #ifdef USE_SETRES
5302   setresuid(0,0,0);
5303 #else
5304   setuid(0);
5305   seteuid(0);
5306   setuid(0);
5307   seteuid(0);
5308 #endif
5309
5310   fault_setup((void (*)(void *))exit_server);
5311   signal(SIGTERM , SIGNAL_CAST dflt_sig);
5312
5313   /* we want total control over the permissions on created files,
5314      so set our umask to 0 */
5315   umask(0);
5316
5317   GetWd(OriginalDir);
5318
5319   init_uid();
5320
5321   /* this is for people who can't start the program correctly */
5322   while (argc > 1 && (*argv[1] != '-'))
5323     {
5324       argv++;
5325       argc--;
5326     }
5327
5328   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5329     switch (opt)
5330       {
5331       case 'O':
5332         pstrcpy(user_socket_options,optarg);
5333         break;
5334       case 'i':
5335         pstrcpy(scope,optarg);
5336         break;
5337       case 'P':
5338         {
5339           extern BOOL passive;
5340           passive = True;
5341         }
5342         break;  
5343       case 's':
5344         pstrcpy(servicesf,optarg);
5345         break;
5346       case 'l':
5347         pstrcpy(debugf,optarg);
5348         break;
5349       case 'a':
5350         {
5351           extern BOOL append_log;
5352           append_log = !append_log;
5353         }
5354         break;
5355       case 'D':
5356         is_daemon = True;
5357         break;
5358       case 'd':
5359         if (*optarg == 'A')
5360           DEBUGLEVEL = 10000;
5361         else
5362           DEBUGLEVEL = atoi(optarg);
5363         break;
5364       case 'p':
5365         port = atoi(optarg);
5366         break;
5367       case 'h':
5368         usage(argv[0]);
5369         exit(0);
5370         break;
5371       default:
5372         usage(argv[0]);
5373         exit(1);
5374       }
5375
5376   reopen_logs();
5377
5378   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5379   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5380
5381 #ifndef NO_GETRLIMIT
5382 #ifdef RLIMIT_NOFILE
5383   {
5384     struct rlimit rlp;
5385     getrlimit(RLIMIT_NOFILE, &rlp);
5386     /*
5387      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5388      * extra fd we need to read directories, as well as the log files
5389      * and standard handles etc.
5390      */
5391     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5392     setrlimit(RLIMIT_NOFILE, &rlp);
5393     getrlimit(RLIMIT_NOFILE, &rlp);
5394     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5395   }
5396 #endif
5397 #endif
5398
5399   
5400   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5401         getuid(),getgid(),geteuid(),getegid()));
5402
5403   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5404     {
5405       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5406       exit(1);
5407     }
5408
5409   init_structs();
5410
5411   if (!reload_services(False))
5412     return(-1); 
5413
5414   codepage_initialise(lp_client_code_page());
5415
5416   pstrcpy(global_myworkgroup, lp_workgroup());
5417
5418   if(!pdb_generate_machine_sid())
5419   {
5420     DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5421     exit(1);
5422   }
5423
5424 #ifndef NO_SIGNAL_TEST
5425   signal(SIGHUP,SIGNAL_CAST sig_hup);
5426 #endif
5427
5428   /* Setup the signals that allow the debug log level
5429      to by dynamically changed. */
5430  
5431   /* If we are using the malloc debug code we can't use
5432      SIGUSR1 and SIGUSR2 to do debug level changes. */
5433
5434 #ifndef MEM_MAN
5435 #if defined(SIGUSR1)
5436   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5437 #endif /* SIGUSR1 */
5438    
5439 #if defined(SIGUSR2)
5440   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5441 #endif /* SIGUSR2 */
5442 #endif /* MEM_MAN */
5443
5444   DEBUG(3,("%s loaded services\n",timestring()));
5445
5446   if (!is_daemon && !is_a_socket(0))
5447     {
5448       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5449       is_daemon = True;
5450     }
5451
5452   if (is_daemon)
5453     {
5454       DEBUG(3,("%s becoming a daemon\n",timestring()));
5455       become_daemon();
5456     }
5457
5458   if (!directory_exist(lp_lockdir(), NULL)) {
5459           mkdir(lp_lockdir(), 0755);
5460   }
5461
5462   if (is_daemon) {
5463           pidfile_create("smbd");
5464   }
5465
5466   if (!open_sockets(is_daemon,port))
5467     exit(1);
5468
5469   if (!locking_init(0))
5470     exit(1);
5471
5472   if(!initialize_password_db())
5473     exit(1);
5474
5475   /* possibly reload the services file. */
5476   reload_services(True);
5477
5478   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5479
5480   if (*lp_rootdir())
5481     {
5482       if (sys_chroot(lp_rootdir()) == 0)
5483         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5484     }
5485
5486   /* Setup the oplock IPC socket. */
5487   if(!open_oplock_ipc())
5488     exit(1);
5489
5490   process();
5491   close_sockets();
5492
5493   exit_server("normal exit");
5494   return(0);
5495 }