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