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