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