1c31f69389db69869e93b004d4653d870b306625
[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          int **p_attrs)
3008 {
3009   if (-1 == initgroups(user,gid))
3010     {
3011       if (getuid() == 0)
3012         {
3013           DEBUG(0,("Unable to initgroups!\n"));
3014           if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3015             DEBUG(0,("This is probably a problem with the account %s\n",user));
3016         }
3017     }
3018   else
3019     {
3020       int i,ngroups;
3021       int *igroups;
3022       int *attrs;
3023       gid_t grp = 0;
3024       ngroups = getgroups(0,&grp);
3025       if (ngroups <= 0)
3026         ngroups = 32;
3027       igroups = (int *)malloc(sizeof(int)*ngroups);
3028       attrs   = (int *)malloc(sizeof(int)*ngroups);
3029       for (i=0;i<ngroups;i++)
3030       {
3031         attrs  [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3032         igroups[i] = 0x42424242;
3033       }
3034       ngroups = getgroups(ngroups,(gid_t *)igroups);
3035
3036       if (igroups[0] == 0x42424242)
3037         ngroups = 0;
3038
3039       *p_ngroups = ngroups;
3040       *p_attrs   = attrs;
3041
3042       /* The following bit of code is very strange. It is due to the
3043          fact that some OSes use int* and some use gid_t* for
3044          getgroups, and some (like SunOS) use both, one in prototypes,
3045          and one in man pages and the actual code. Thus we detect it
3046          dynamically using some very ugly code */
3047       if (ngroups > 0)
3048         {
3049           /* does getgroups return ints or gid_t ?? */
3050           static BOOL groups_use_ints = True;
3051
3052           if (groups_use_ints && 
3053               ngroups == 1 && 
3054               SVAL(igroups,2) == 0x4242)
3055             groups_use_ints = False;
3056           
3057           for (i=0;groups_use_ints && i<ngroups;i++)
3058             if (igroups[i] == 0x42424242)
3059               groups_use_ints = False;
3060               
3061           if (groups_use_ints)
3062           {
3063               *p_igroups = igroups;
3064               *p_groups = (gid_t *)igroups;       
3065           }
3066           else
3067           {
3068               gid_t *groups = (gid_t *)igroups;
3069               igroups = (int *)malloc(sizeof(int)*ngroups);
3070               for (i=0;i<ngroups;i++)
3071           {
3072                 igroups[i] = groups[i];
3073           }
3074               *p_igroups = igroups;
3075               *p_groups = (gid_t *)groups;
3076             }
3077         }
3078       DEBUG(3,("%s is in %d groups\n",user,ngroups));
3079       for (i=0;i<ngroups;i++)
3080         DEBUG(3,("%d ",igroups[i]));
3081       DEBUG(3,("\n"));
3082     }
3083   return 0;
3084 }
3085
3086 /****************************************************************************
3087   make a connection to a service
3088 ****************************************************************************/
3089 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3090 {
3091   int cnum;
3092   int snum;
3093   struct passwd *pass = NULL;
3094   connection_struct *pcon;
3095   BOOL guest = False;
3096   BOOL force = False;
3097   static BOOL first_connection = True;
3098
3099   strlower(service);
3100
3101   snum = find_service(service);
3102   if (snum < 0)
3103     {
3104       if (strequal(service,"IPC$"))
3105         {         
3106           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3107           return(-3);
3108         }
3109
3110       DEBUG(0,("%s couldn't find service %s\n",timestring(),service));      
3111       return(-2);
3112     }
3113
3114   if (strequal(service,HOMES_NAME))
3115     {
3116       if (*user && Get_Pwnam(user,True))
3117         return(make_connection(user,user,password,pwlen,dev,vuid));
3118
3119       if (validated_username(vuid))
3120         {
3121           strcpy(user,validated_username(vuid));
3122           return(make_connection(user,user,password,pwlen,dev,vuid));
3123         }
3124     }
3125
3126   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3127     return(-4);
3128   }
3129
3130   /* you can only connect to the IPC$ service as an ipc device */
3131   if (strequal(service,"IPC$"))
3132     strcpy(dev,"IPC");
3133
3134   if (*dev == '?' || !*dev)
3135     {
3136       if (lp_print_ok(snum))
3137         strcpy(dev,"LPT1:");
3138       else
3139         strcpy(dev,"A:");
3140     }
3141
3142   /* if the request is as a printer and you can't print then refuse */
3143   strupper(dev);
3144   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3145     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3146     return(-6);
3147   }
3148
3149   /* lowercase the user name */
3150   strlower(user);
3151
3152   /* add it as a possible user name */
3153   add_session_user(service);
3154
3155   /* shall we let them in? */
3156   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3157     {
3158       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3159       return(-1);
3160     }
3161   
3162   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3163   if (cnum < 0)
3164     {
3165       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3166       return(-1);
3167     }
3168
3169   pcon = &Connections[cnum];
3170   bzero((char *)pcon,sizeof(*pcon));
3171
3172   /* find out some info about the user */
3173   pass = Get_Pwnam(user,True);
3174
3175   if (pass == NULL)
3176     {
3177       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3178       return(-7);
3179     }
3180
3181   pcon->read_only = lp_readonly(snum);
3182
3183   {
3184     pstring list;
3185     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3186     string_sub(list,"%S",service);
3187
3188     if (user_in_list(user,list))
3189       pcon->read_only = True;
3190
3191     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3192     string_sub(list,"%S",service);
3193
3194     if (user_in_list(user,list))
3195       pcon->read_only = False;    
3196   }
3197
3198   /* admin user check */
3199
3200   /* JRA - original code denied admin user if the share was
3201      marked read_only. Changed as I don't think this is needed,
3202      but old code left in case there is a problem here.
3203    */
3204   if (user_in_list(user,lp_admin_users(snum)) 
3205 #if 0
3206       && !pcon->read_only)
3207 #else
3208       )
3209 #endif
3210     {
3211       pcon->admin_user = True;
3212       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3213     }
3214   else
3215     pcon->admin_user = False;
3216     
3217   pcon->force_user = force;
3218   pcon->vuid = vuid;
3219   pcon->uid = pass->pw_uid;
3220   pcon->gid = pass->pw_gid;
3221   pcon->num_files_open = 0;
3222   pcon->lastused = time(NULL);
3223   pcon->service = snum;
3224   pcon->used = True;
3225   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3226   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3227   pcon->dirptr = NULL;
3228   pcon->veto_list = NULL;
3229   pcon->hide_list = NULL;
3230   string_set(&pcon->dirpath,"");
3231   string_set(&pcon->user,user);
3232
3233 #if HAVE_GETGRNAM 
3234   if (*lp_force_group(snum))
3235     {
3236       struct group *gptr;
3237       pstring gname;
3238
3239       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3240       /* default service may be a group name            */
3241       string_sub(gname,"%S",service);
3242       gptr = (struct group *)getgrnam(gname);
3243
3244       if (gptr)
3245         {
3246           pcon->gid = gptr->gr_gid;
3247           DEBUG(3,("Forced group %s\n",gname));
3248         }
3249       else
3250         DEBUG(1,("Couldn't find group %s\n",gname));
3251     }
3252 #endif
3253
3254   if (*lp_force_user(snum))
3255     {
3256       struct passwd *pass2;
3257       fstring fuser;
3258       fstrcpy(fuser,lp_force_user(snum));
3259       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3260       if (pass2)
3261         {
3262           pcon->uid = pass2->pw_uid;
3263           string_set(&pcon->user,fuser);
3264           fstrcpy(user,fuser);
3265           pcon->force_user = True;
3266           DEBUG(3,("Forced user %s\n",fuser));    
3267         }
3268       else
3269         DEBUG(1,("Couldn't find user %s\n",fuser));
3270     }
3271
3272   {
3273     pstring s;
3274     pstrcpy(s,lp_pathname(snum));
3275     standard_sub(cnum,s);
3276     string_set(&pcon->connectpath,s);
3277     DEBUG(3,("Connect path is %s\n",s));
3278   }
3279
3280   /* groups stuff added by ih */
3281   pcon->ngroups = 0;
3282   pcon->igroups = NULL;
3283   pcon->groups = NULL;
3284   pcon->attrs = NULL;
3285
3286   if (!IS_IPC(cnum))
3287     {
3288       /* Find all the groups this uid is in and store them. Used by become_user() */
3289       setup_groups(pcon->user,pcon->uid,pcon->gid,
3290                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3291       
3292       /* check number of connections */
3293       if (!claim_connection(cnum,
3294                             lp_servicename(SNUM(cnum)),
3295                             lp_max_connections(SNUM(cnum)),False))
3296         {
3297           DEBUG(1,("too many connections - rejected\n"));
3298           return(-8);
3299         }  
3300
3301       if (lp_status(SNUM(cnum)))
3302         claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3303
3304       first_connection = False;
3305     } /* IS_IPC */
3306
3307   pcon->open = True;
3308
3309   /* execute any "root preexec = " line */
3310   if (*lp_rootpreexec(SNUM(cnum)))
3311     {
3312       pstring cmd;
3313       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3314       standard_sub(cnum,cmd);
3315       DEBUG(5,("cmd=%s\n",cmd));
3316       smbrun(cmd,NULL,False);
3317     }
3318
3319   if (!become_user(cnum,pcon->vuid))
3320     {
3321       DEBUG(0,("Can't become connected user!\n"));
3322       pcon->open = False;
3323       if (!IS_IPC(cnum)) {
3324         yield_connection(cnum,
3325                          lp_servicename(SNUM(cnum)),
3326                          lp_max_connections(SNUM(cnum)));
3327         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3328       }
3329       return(-1);
3330     }
3331
3332   if (ChDir(pcon->connectpath) != 0)
3333     {
3334       DEBUG(0,("Can't change directory to %s (%s)\n",
3335                pcon->connectpath,strerror(errno)));
3336       pcon->open = False;
3337       unbecome_user();
3338       if (!IS_IPC(cnum)) {
3339         yield_connection(cnum,
3340                          lp_servicename(SNUM(cnum)),
3341                          lp_max_connections(SNUM(cnum)));
3342         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3343       }
3344       return(-5);      
3345     }
3346
3347   string_set(&pcon->origpath,pcon->connectpath);
3348
3349 #if SOFTLINK_OPTIMISATION
3350   /* resolve any soft links early */
3351   {
3352     pstring s;
3353     pstrcpy(s,pcon->connectpath);
3354     GetWd(s);
3355     string_set(&pcon->connectpath,s);
3356     ChDir(pcon->connectpath);
3357   }
3358 #endif
3359
3360   num_connections_open++;
3361   add_session_user(user);
3362   
3363   /* execute any "preexec = " line */
3364   if (*lp_preexec(SNUM(cnum)))
3365     {
3366       pstring cmd;
3367       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3368       standard_sub(cnum,cmd);
3369       smbrun(cmd,NULL,False);
3370     }
3371   
3372   /* we've finished with the sensitive stuff */
3373   unbecome_user();
3374
3375   /* Add veto/hide lists */
3376   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3377   {
3378     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3379     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3380   }
3381
3382   {
3383     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3384                             timestring(),
3385                             remote_machine,
3386                             client_addr(),
3387                             lp_servicename(SNUM(cnum)),user,
3388                             pcon->uid,
3389                             pcon->gid,
3390                             (int)getpid()));
3391   }
3392
3393   return(cnum);
3394 }
3395
3396
3397 /****************************************************************************
3398   find first available file slot
3399 ****************************************************************************/
3400 int find_free_file(void )
3401 {
3402   int i;
3403   /* we start at 1 here for an obscure reason I can't now remember,
3404      but I think is important :-) */
3405   for (i=1;i<MAX_OPEN_FILES;i++)
3406     if (!Files[i].open)
3407       return(i);
3408   DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3409   return(-1);
3410 }
3411
3412 /****************************************************************************
3413   find first available connection slot, starting from a random position.
3414 The randomisation stops problems with the server dieing and clients
3415 thinking the server is still available.
3416 ****************************************************************************/
3417 static int find_free_connection(int hash )
3418 {
3419   int i;
3420   BOOL used=False;
3421   hash = (hash % (MAX_CONNECTIONS-2))+1;
3422
3423  again:
3424
3425   for (i=hash+1;i!=hash;)
3426     {
3427       if (!Connections[i].open && Connections[i].used == used) 
3428         {
3429           DEBUG(3,("found free connection number %d\n",i));
3430           return(i);
3431         }
3432       i++;
3433       if (i == MAX_CONNECTIONS)
3434         i = 1;
3435     }
3436
3437   if (!used)
3438     {
3439       used = !used;
3440       goto again;
3441     }
3442
3443   DEBUG(1,("ERROR! Out of connection structures\n"));
3444   return(-1);
3445 }
3446
3447
3448 /****************************************************************************
3449 reply for the core protocol
3450 ****************************************************************************/
3451 int reply_corep(char *outbuf)
3452 {
3453   int outsize = set_message(outbuf,1,0,True);
3454
3455   Protocol = PROTOCOL_CORE;
3456
3457   return outsize;
3458 }
3459
3460
3461 /****************************************************************************
3462 reply for the coreplus protocol
3463 ****************************************************************************/
3464 int reply_coreplus(char *outbuf)
3465 {
3466   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3467   int outsize = set_message(outbuf,13,0,True);
3468   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3469                                  readbraw and writebraw (possibly) */
3470   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3471   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3472
3473   Protocol = PROTOCOL_COREPLUS;
3474
3475   return outsize;
3476 }
3477
3478
3479 /****************************************************************************
3480 reply for the lanman 1.0 protocol
3481 ****************************************************************************/
3482 int reply_lanman1(char *outbuf)
3483 {
3484   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3485   int secword=0;
3486   BOOL doencrypt = SMBENCRYPT();
3487   time_t t = time(NULL);
3488   /* We need to save and restore this as it can be destroyed
3489      if we call another server if security=server
3490      Thanks to Paul Nelson @ Thursby for pointing this out.
3491    */
3492   uint16 mid = SVAL(outbuf, smb_mid);
3493
3494   if (lp_security()>=SEC_USER) secword |= 1;
3495   if (doencrypt) secword |= 2;
3496
3497   set_message(outbuf,13,doencrypt?8:0,True);
3498   SSVAL(outbuf,smb_vwv1,secword); 
3499   /* Create a token value and add it to the outgoing packet. */
3500   if (doencrypt) 
3501     generate_next_challenge(smb_buf(outbuf));
3502
3503   Protocol = PROTOCOL_LANMAN1;
3504
3505   if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3506     DEBUG(3,("using password server validation\n"));
3507   if (doencrypt) set_challenge(smb_buf(outbuf));    
3508   }
3509
3510   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3511   SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3512   SSVAL(outbuf,smb_vwv2,max_recv);
3513   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3514   SSVAL(outbuf,smb_vwv4,1);
3515   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3516                                  readbraw writebraw (possibly) */
3517   SIVAL(outbuf,smb_vwv6,getpid());
3518   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3519
3520   put_dos_date(outbuf,smb_vwv8,t);
3521
3522   return (smb_len(outbuf)+4);
3523 }
3524
3525
3526 /****************************************************************************
3527 reply for the lanman 2.0 protocol
3528 ****************************************************************************/
3529 int reply_lanman2(char *outbuf)
3530 {
3531   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3532   int secword=0;
3533   BOOL doencrypt = SMBENCRYPT();
3534   time_t t = time(NULL);
3535   /* We need to save and restore this as it can be destroyed
3536      if we call another server if security=server
3537      Thanks to Paul Nelson @ Thursby for pointing this out.
3538    */
3539   uint16 mid = SVAL(outbuf, smb_mid);
3540
3541   if (lp_security()>=SEC_USER) secword |= 1;
3542   if (doencrypt) secword |= 2;
3543
3544   set_message(outbuf,13,doencrypt?8:0,True);
3545   SSVAL(outbuf,smb_vwv1,secword); 
3546   /* Create a token value and add it to the outgoing packet. */
3547   if (doencrypt) 
3548     generate_next_challenge(smb_buf(outbuf));
3549
3550   SIVAL(outbuf,smb_vwv6,getpid());
3551
3552   Protocol = PROTOCOL_LANMAN2;
3553
3554   if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3555     DEBUG(3,("using password server validation\n"));
3556     if (doencrypt) set_challenge(smb_buf(outbuf));    
3557   }
3558
3559   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3560   SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3561   SSVAL(outbuf,smb_vwv2,max_recv);
3562   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3563   SSVAL(outbuf,smb_vwv4,1);
3564   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3565   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3566   put_dos_date(outbuf,smb_vwv8,t);
3567
3568   return (smb_len(outbuf)+4);
3569 }
3570
3571
3572 /****************************************************************************
3573 reply for the nt protocol
3574 ****************************************************************************/
3575 int reply_nt1(char *outbuf)
3576 {
3577   /* dual names + lock_and_read + nt SMBs + remote API calls */
3578   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3579 /*
3580   other valid capabilities which we may support at some time...
3581                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3582                      CAP_LARGE_FILES|CAP_LARGE_READX|
3583                      CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3584  */
3585
3586   int secword=0;
3587   BOOL doencrypt = SMBENCRYPT();
3588   time_t t = time(NULL);
3589   int data_len;
3590   int encrypt_len;
3591   char challenge_len = 8;
3592   /* We need to save and restore this as it can be destroyed
3593      if we call another server if security=server
3594      Thanks to Paul Nelson @ Thursby for pointing this out.
3595    */
3596   uint16 mid = SVAL(outbuf, smb_mid);
3597
3598   if (lp_readraw() && lp_writeraw())
3599   {
3600     capabilities |= CAP_RAW_MODE;
3601   }
3602
3603   if (lp_security()>=SEC_USER) secword |= 1;
3604   if (doencrypt) secword |= 2;
3605
3606   /* decide where (if) to put the encryption challenge, and
3607      follow it with the OEM'd domain name
3608    */
3609   encrypt_len = doencrypt?challenge_len:0;
3610 #if UNICODE
3611   data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
3612 #else
3613   data_len = encrypt_len + strlen(myworkgroup) + 1;
3614 #endif
3615
3616   set_message(outbuf,17,data_len,True);
3617
3618 #if UNICODE
3619   /* put the OEM'd domain name */
3620   PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
3621 #else
3622   strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
3623 #endif
3624
3625   CVAL(outbuf,smb_vwv1) = secword;
3626   /* Create a token value and add it to the outgoing packet. */
3627   if (doencrypt)
3628   {
3629     generate_next_challenge(smb_buf(outbuf));
3630
3631     /* Tell the nt machine how long the challenge is. */
3632     SSVALS(outbuf,smb_vwv16+1,challenge_len);
3633   }
3634
3635   Protocol = PROTOCOL_NT1;
3636
3637   if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
3638     DEBUG(3,("using password server validation\n"));
3639     if (doencrypt) set_challenge(smb_buf(outbuf));    
3640   }
3641
3642   SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
3643   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3644   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3645   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3646   SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3647   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3648   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3649   put_long_date(outbuf+smb_vwv11+1,t);
3650   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3651   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3652
3653   return (smb_len(outbuf)+4);
3654 }
3655
3656 /* these are the protocol lists used for auto architecture detection:
3657
3658 WinNT 3.51:
3659 protocol [PC NETWORK PROGRAM 1.0]
3660 protocol [XENIX CORE]
3661 protocol [MICROSOFT NETWORKS 1.03]
3662 protocol [LANMAN1.0]
3663 protocol [Windows for Workgroups 3.1a]
3664 protocol [LM1.2X002]
3665 protocol [LANMAN2.1]
3666 protocol [NT LM 0.12]
3667
3668 Win95:
3669 protocol [PC NETWORK PROGRAM 1.0]
3670 protocol [XENIX CORE]
3671 protocol [MICROSOFT NETWORKS 1.03]
3672 protocol [LANMAN1.0]
3673 protocol [Windows for Workgroups 3.1a]
3674 protocol [LM1.2X002]
3675 protocol [LANMAN2.1]
3676 protocol [NT LM 0.12]
3677
3678 OS/2:
3679 protocol [PC NETWORK PROGRAM 1.0]
3680 protocol [XENIX CORE]
3681 protocol [LANMAN1.0]
3682 protocol [LM1.2X002]
3683 protocol [LANMAN2.1]
3684 */
3685
3686 /*
3687   * Modified to recognize the architecture of the remote machine better.
3688   *
3689   * This appears to be the matrix of which protocol is used by which
3690   * MS product.
3691        Protocol                       WfWg    Win95   WinNT  OS/2
3692        PC NETWORK PROGRAM 1.0          1       1       1      1
3693        XENIX CORE                                      2      2
3694        MICROSOFT NETWORKS 3.0          2       2       
3695        DOS LM1.2X002                   3       3       
3696        MICROSOFT NETWORKS 1.03                         3
3697        DOS LANMAN2.1                   4       4       
3698        LANMAN1.0                                       4      3
3699        Windows for Workgroups 3.1a     5       5       5
3700        LM1.2X002                                       6      4
3701        LANMAN2.1                                       7      5
3702        NT LM 0.12                              6       8
3703   *
3704   *  tim@fsg.com 09/29/95
3705   */
3706   
3707 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
3708 #define ARCH_WIN95    0x2
3709 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
3710 #define ARCH_WINNT    0x8
3711 #define ARCH_SAMBA    0x10
3712  
3713 #define ARCH_ALL      0x1F
3714  
3715 /* List of supported protocols, most desired first */
3716 struct {
3717   char *proto_name;
3718   char *short_name;
3719   int (*proto_reply_fn)(char *);
3720   int protocol_level;
3721 } supported_protocols[] = {
3722   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
3723   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
3724   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3725   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3726   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3727   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
3728   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
3729   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3730   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
3731   {NULL,NULL},
3732 };
3733
3734
3735 /****************************************************************************
3736   reply to a negprot
3737 ****************************************************************************/
3738 static int reply_negprot(char *inbuf,char *outbuf)
3739 {
3740   int outsize = set_message(outbuf,1,0,True);
3741   int Index=0;
3742   int choice= -1;
3743   int protocol;
3744   char *p;
3745   int bcc = SVAL(smb_buf(inbuf),-2);
3746   int arch = ARCH_ALL;
3747
3748   p = smb_buf(inbuf)+1;
3749   while (p < (smb_buf(inbuf) + bcc))
3750     { 
3751       Index++;
3752       DEBUG(3,("Requested protocol [%s]\n",p));
3753       if (strcsequal(p,"Windows for Workgroups 3.1a"))
3754         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3755       else if (strcsequal(p,"DOS LM1.2X002"))
3756         arch &= ( ARCH_WFWG | ARCH_WIN95 );
3757       else if (strcsequal(p,"DOS LANMAN2.1"))
3758         arch &= ( ARCH_WFWG | ARCH_WIN95 );
3759       else if (strcsequal(p,"NT LM 0.12"))
3760         arch &= ( ARCH_WIN95 | ARCH_WINNT );
3761       else if (strcsequal(p,"LANMAN2.1"))
3762         arch &= ( ARCH_WINNT | ARCH_OS2 );
3763       else if (strcsequal(p,"LM1.2X002"))
3764         arch &= ( ARCH_WINNT | ARCH_OS2 );
3765       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3766         arch &= ARCH_WINNT;
3767       else if (strcsequal(p,"XENIX CORE"))
3768         arch &= ( ARCH_WINNT | ARCH_OS2 );
3769       else if (strcsequal(p,"Samba")) {
3770         arch = ARCH_SAMBA;
3771         break;
3772       }
3773  
3774       p += strlen(p) + 2;
3775     }
3776     
3777   switch ( arch ) {
3778   case ARCH_SAMBA:
3779     set_remote_arch(RA_SAMBA);
3780     break;
3781   case ARCH_WFWG:
3782     set_remote_arch(RA_WFWG);
3783     break;
3784   case ARCH_WIN95:
3785     set_remote_arch(RA_WIN95);
3786     break;
3787   case ARCH_WINNT:
3788     set_remote_arch(RA_WINNT);
3789     break;
3790   case ARCH_OS2:
3791     set_remote_arch(RA_OS2);
3792     break;
3793   default:
3794     set_remote_arch(RA_UNKNOWN);
3795     break;
3796   }
3797  
3798   /* possibly reload - change of architecture */
3799   reload_services(True);      
3800     
3801   /* a special case to stop password server loops */
3802   if (Index == 1 && strequal(remote_machine,myhostname) && 
3803       lp_security()==SEC_SERVER)
3804     exit_server("Password server loop!");
3805   
3806   /* Check for protocols, most desirable first */
3807   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3808     {
3809       p = smb_buf(inbuf)+1;
3810       Index = 0;
3811       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3812         while (p < (smb_buf(inbuf) + bcc))
3813           { 
3814             if (strequal(p,supported_protocols[protocol].proto_name))
3815               choice = Index;
3816             Index++;
3817             p += strlen(p) + 2;
3818           }
3819       if(choice != -1)
3820         break;
3821     }
3822   
3823   SSVAL(outbuf,smb_vwv0,choice);
3824   if(choice != -1) {
3825     extern fstring remote_proto;
3826     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3827     reload_services(True);          
3828     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3829     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3830   }
3831   else {
3832     DEBUG(0,("No protocol supported !\n"));
3833   }
3834   SSVAL(outbuf,smb_vwv0,choice);
3835   
3836   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3837
3838   return(outsize);
3839 }
3840
3841
3842 /****************************************************************************
3843 close all open files for a connection
3844 ****************************************************************************/
3845 static void close_open_files(int cnum)
3846 {
3847   int i;
3848   for (i=0;i<MAX_OPEN_FILES;i++)
3849     if( Files[i].cnum == cnum && Files[i].open) {
3850       close_file(i);
3851     }
3852 }
3853
3854
3855
3856 /****************************************************************************
3857 close a cnum
3858 ****************************************************************************/
3859 void close_cnum(int cnum, uint16 vuid)
3860 {
3861   DirCacheFlush(SNUM(cnum));
3862
3863   unbecome_user();
3864
3865   if (!OPEN_CNUM(cnum))
3866     {
3867       DEBUG(0,("Can't close cnum %d\n",cnum));
3868       return;
3869     }
3870
3871   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
3872                           timestring(),
3873                           remote_machine,client_addr(),
3874                           lp_servicename(SNUM(cnum))));
3875
3876   yield_connection(cnum,
3877                    lp_servicename(SNUM(cnum)),
3878                    lp_max_connections(SNUM(cnum)));
3879
3880   if (lp_status(SNUM(cnum)))
3881     yield_connection(cnum,"STATUS.",MAXSTATUS);
3882
3883   close_open_files(cnum);
3884   dptr_closecnum(cnum);
3885
3886   /* execute any "postexec = " line */
3887   if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
3888     {
3889       pstring cmd;
3890       strcpy(cmd,lp_postexec(SNUM(cnum)));
3891       standard_sub(cnum,cmd);
3892       smbrun(cmd,NULL,False);
3893       unbecome_user();
3894     }
3895
3896   unbecome_user();
3897   /* execute any "root postexec = " line */
3898   if (*lp_rootpostexec(SNUM(cnum)))
3899     {
3900       pstring cmd;
3901       strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
3902       standard_sub(cnum,cmd);
3903       smbrun(cmd,NULL,False);
3904     }
3905
3906   Connections[cnum].open = False;
3907   num_connections_open--;
3908   if (Connections[cnum].ngroups && Connections[cnum].groups)
3909     {
3910       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
3911         free(Connections[cnum].groups);
3912       free(Connections[cnum].igroups);
3913       Connections[cnum].groups = NULL;
3914       Connections[cnum].igroups = NULL;
3915       Connections[cnum].ngroups = 0;
3916     }
3917
3918   free_namearray(Connections[cnum].veto_list);
3919   free_namearray(Connections[cnum].hide_list);
3920
3921   string_set(&Connections[cnum].user,"");
3922   string_set(&Connections[cnum].dirpath,"");
3923   string_set(&Connections[cnum].connectpath,"");
3924 }
3925
3926
3927 /****************************************************************************
3928 simple routines to do connection counting
3929 ****************************************************************************/
3930 BOOL yield_connection(int cnum,char *name,int max_connections)
3931 {
3932   struct connect_record crec;
3933   pstring fname;
3934   FILE *f;
3935   int mypid = getpid();
3936   int i;
3937
3938   DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
3939
3940   if (max_connections <= 0)
3941     return(True);
3942
3943   bzero(&crec,sizeof(crec));
3944
3945   pstrcpy(fname,lp_lockdir());
3946   standard_sub(cnum,fname);
3947   trim_string(fname,"","/");
3948
3949   strcat(fname,"/");
3950   strcat(fname,name);
3951   strcat(fname,".LCK");
3952
3953   f = fopen(fname,"r+");
3954   if (!f)
3955     {
3956       DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
3957       return(False);
3958     }
3959
3960   fseek(f,0,SEEK_SET);
3961
3962   /* find a free spot */
3963   for (i=0;i<max_connections;i++)
3964     {
3965       if (fread(&crec,sizeof(crec),1,f) != 1)
3966         {
3967           DEBUG(2,("Entry not found in lock file %s\n",fname));
3968           fclose(f);
3969           return(False);
3970         }
3971       if (crec.pid == mypid && crec.cnum == cnum)
3972         break;
3973     }
3974
3975   if (crec.pid != mypid || crec.cnum != cnum)
3976     {
3977       fclose(f);
3978       DEBUG(2,("Entry not found in lock file %s\n",fname));
3979       return(False);
3980     }
3981
3982   bzero((void *)&crec,sizeof(crec));
3983   
3984   /* remove our mark */
3985   if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
3986       fwrite(&crec,sizeof(crec),1,f) != 1)
3987     {
3988       DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
3989       fclose(f);
3990       return(False);
3991     }
3992
3993   DEBUG(3,("Yield successful\n"));
3994
3995   fclose(f);
3996   return(True);
3997 }
3998
3999
4000 /****************************************************************************
4001 simple routines to do connection counting
4002 ****************************************************************************/
4003 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4004 {
4005   struct connect_record crec;
4006   pstring fname;
4007   FILE *f;
4008   int snum = SNUM(cnum);
4009   int i,foundi= -1;
4010   int total_recs;
4011
4012   if (max_connections <= 0)
4013     return(True);
4014
4015   DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4016
4017   pstrcpy(fname,lp_lockdir());
4018   standard_sub(cnum,fname);
4019   trim_string(fname,"","/");
4020
4021   if (!directory_exist(fname,NULL))
4022     mkdir(fname,0755);
4023
4024   strcat(fname,"/");
4025   strcat(fname,name);
4026   strcat(fname,".LCK");
4027
4028   if (!file_exist(fname,NULL))
4029     {
4030       int oldmask = umask(022);
4031       f = fopen(fname,"w");
4032       if (f) fclose(f);
4033       umask(oldmask);
4034     }
4035
4036   total_recs = file_size(fname) / sizeof(crec);
4037
4038   f = fopen(fname,"r+");
4039
4040   if (!f)
4041     {
4042       DEBUG(1,("couldn't open lock file %s\n",fname));
4043       return(False);
4044     }
4045
4046   /* find a free spot */
4047   for (i=0;i<max_connections;i++)
4048     {
4049
4050       if (i>=total_recs || 
4051           fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4052           fread(&crec,sizeof(crec),1,f) != 1)
4053         {
4054           if (foundi < 0) foundi = i;
4055           break;
4056         }
4057
4058       if (Clear && crec.pid && !process_exists(crec.pid))
4059         {
4060           fseek(f,i*sizeof(crec),SEEK_SET);
4061           bzero((void *)&crec,sizeof(crec));
4062           fwrite(&crec,sizeof(crec),1,f);
4063           if (foundi < 0) foundi = i;
4064           continue;
4065         }
4066       if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4067         {
4068           foundi=i;
4069           if (!Clear) break;
4070         }
4071     }  
4072
4073   if (foundi < 0)
4074     {
4075       DEBUG(3,("no free locks in %s\n",fname));
4076       fclose(f);
4077       return(False);
4078     }      
4079
4080   /* fill in the crec */
4081   bzero((void *)&crec,sizeof(crec));
4082   crec.magic = 0x280267;
4083   crec.pid = getpid();
4084   crec.cnum = cnum;
4085   crec.uid = Connections[cnum].uid;
4086   crec.gid = Connections[cnum].gid;
4087   StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4088   crec.start = time(NULL);
4089
4090   StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4091   StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4092   
4093   /* make our mark */
4094   if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4095       fwrite(&crec,sizeof(crec),1,f) != 1)
4096     {
4097       fclose(f);
4098       return(False);
4099     }
4100
4101   fclose(f);
4102   return(True);
4103 }
4104
4105 #if DUMP_CORE
4106 /*******************************************************************
4107 prepare to dump a core file - carefully!
4108 ********************************************************************/
4109 static BOOL dump_core(void)
4110 {
4111   char *p;
4112   pstring dname;
4113   pstrcpy(dname,debugf);
4114   if ((p=strrchr(dname,'/'))) *p=0;
4115   strcat(dname,"/corefiles");
4116   mkdir(dname,0700);
4117   sys_chown(dname,getuid(),getgid());
4118   chmod(dname,0700);
4119   if (chdir(dname)) return(False);
4120   umask(~(0700));
4121
4122 #ifndef NO_GETRLIMIT
4123 #ifdef RLIMIT_CORE
4124   {
4125     struct rlimit rlp;
4126     getrlimit(RLIMIT_CORE, &rlp);
4127     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4128     setrlimit(RLIMIT_CORE, &rlp);
4129     getrlimit(RLIMIT_CORE, &rlp);
4130     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4131   }
4132 #endif
4133 #endif
4134
4135
4136   DEBUG(0,("Dumping core in %s\n",dname));
4137   return(True);
4138 }
4139 #endif
4140
4141 /****************************************************************************
4142 exit the server
4143 ****************************************************************************/
4144 void exit_server(char *reason)
4145 {
4146   static int firsttime=1;
4147   int i;
4148
4149   if (!firsttime) exit(0);
4150   firsttime = 0;
4151
4152   unbecome_user();
4153   DEBUG(2,("Closing connections\n"));
4154   for (i=0;i<MAX_CONNECTIONS;i++)
4155     if (Connections[i].open)
4156       close_cnum(i,(uint16)-1);
4157 #ifdef DFS_AUTH
4158   if (dcelogin_atmost_once)
4159     dfs_unlogin();
4160 #endif
4161   if (!reason) {   
4162     int oldlevel = DEBUGLEVEL;
4163     DEBUGLEVEL = 10;
4164     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4165     if (last_inbuf)
4166       show_msg(last_inbuf);
4167     DEBUGLEVEL = oldlevel;
4168     DEBUG(0,("===============================================================\n"));
4169 #if DUMP_CORE
4170     if (dump_core()) return;
4171 #endif
4172   }    
4173
4174 #ifdef FAST_SHARE_MODES
4175   stop_share_mode_mgmt();
4176 #endif /* FAST_SHARE_MODES */
4177
4178   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4179   exit(0);
4180 }
4181
4182 /****************************************************************************
4183 do some standard substitutions in a string
4184 ****************************************************************************/
4185 void standard_sub(int cnum,char *str)
4186 {
4187   if (VALID_CNUM(cnum)) {
4188     char *p, *s, *home;
4189
4190     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4191       switch (*(p+1)) {
4192         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4193                      string_sub(p,"%H",home);
4194                    else
4195                      p += 2;
4196                    break;
4197         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4198         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4199         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4200         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4201         case '\0' : p++; break; /* don't run off the end of the string */
4202         default  : p+=2; break;
4203       }
4204     }
4205   }
4206   standard_sub_basic(str);
4207 }
4208
4209 /*
4210 These flags determine some of the permissions required to do an operation 
4211
4212 Note that I don't set NEED_WRITE on some write operations because they
4213 are used by some brain-dead clients when printing, and I don't want to
4214 force write permissions on print services.
4215 */
4216 #define AS_USER (1<<0)
4217 #define NEED_WRITE (1<<1)
4218 #define TIME_INIT (1<<2)
4219 #define CAN_IPC (1<<3)
4220 #define AS_GUEST (1<<5)
4221
4222
4223 /* 
4224    define a list of possible SMB messages and their corresponding
4225    functions. Any message that has a NULL function is unimplemented -
4226    please feel free to contribute implementations!
4227 */
4228 struct smb_message_struct
4229 {
4230   int code;
4231   char *name;
4232   int (*fn)();
4233   int flags;
4234 #if PROFILING
4235   unsigned long time;
4236 #endif
4237 }
4238  smb_messages[] = {
4239
4240     /* CORE PROTOCOL */
4241
4242    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4243    {SMBtcon,"SMBtcon",reply_tcon,0},
4244    {SMBtdis,"SMBtdis",reply_tdis,0},
4245    {SMBexit,"SMBexit",reply_exit,0},
4246    {SMBioctl,"SMBioctl",reply_ioctl,0},
4247    {SMBecho,"SMBecho",reply_echo,0},
4248    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4249    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4250    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4251    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4252    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4253    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4254    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4255    {SMBopen,"SMBopen",reply_open,AS_USER},
4256
4257    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4258    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4259    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4260
4261    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4262    {SMBread,"SMBread",reply_read,AS_USER},
4263    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4264    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4265    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4266    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4267    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4268    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4269
4270    /* this is a Pathworks specific call, allowing the 
4271       changing of the root path */
4272    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4273
4274    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4275    {SMBflush,"SMBflush",reply_flush,AS_USER},
4276    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4277    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4278    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4279    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4280    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4281    {SMBlock,"SMBlock",reply_lock,AS_USER},
4282    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4283    
4284    /* CORE+ PROTOCOL FOLLOWS */
4285    
4286    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4287    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4288    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4289    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4290    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4291    
4292    /* LANMAN1.0 PROTOCOL FOLLOWS */
4293    
4294    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4295    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4296    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4297    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4298    {SMBwritec,"SMBwritec",NULL,AS_USER},
4299    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4300    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4301    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4302    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4303    {SMBioctls,"SMBioctls",NULL,AS_USER},
4304    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4305    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4306    
4307    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4308    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4309    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4310    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4311    
4312    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4313    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4314    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4315
4316    /* LANMAN2.0 PROTOCOL FOLLOWS */
4317    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4318    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4319    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4320    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4321
4322    /* messaging routines */
4323    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4324    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4325    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4326    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4327
4328    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4329    
4330    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4331    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4332    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4333    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4334  };
4335
4336 /****************************************************************************
4337 return a string containing the function name of a SMB command
4338 ****************************************************************************/
4339 char *smb_fn_name(int type)
4340 {
4341   static char *unknown_name = "SMBunknown";
4342   static int num_smb_messages = 
4343     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4344   int match;
4345
4346   for (match=0;match<num_smb_messages;match++)
4347     if (smb_messages[match].code == type)
4348       break;
4349
4350   if (match == num_smb_messages)
4351     return(unknown_name);
4352
4353   return(smb_messages[match].name);
4354 }
4355
4356
4357 /****************************************************************************
4358 do a switch on the message type, and return the response size
4359 ****************************************************************************/
4360 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4361 {
4362   static int pid= -1;
4363   int outsize = 0;
4364   static int num_smb_messages = 
4365     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4366   int match;
4367
4368 #if PROFILING
4369   struct timeval msg_start_time;
4370   struct timeval msg_end_time;
4371   static unsigned long total_time = 0;
4372
4373   GetTimeOfDay(&msg_start_time);
4374 #endif
4375
4376   if (pid == -1)
4377     pid = getpid();
4378
4379   errno = 0;
4380   last_message = type;
4381
4382   /* make sure this is an SMB packet */
4383   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4384     {
4385       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4386       return(-1);
4387     }
4388
4389   for (match=0;match<num_smb_messages;match++)
4390     if (smb_messages[match].code == type)
4391       break;
4392
4393   if (match == num_smb_messages)
4394     {
4395       DEBUG(0,("Unknown message type %d!\n",type));
4396       outsize = reply_unknown(inbuf,outbuf);
4397     }
4398   else
4399     {
4400       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4401       if (smb_messages[match].fn)
4402         {
4403           int cnum = SVAL(inbuf,smb_tid);
4404           int flags = smb_messages[match].flags;
4405           uint16 session_tag = SVAL(inbuf,smb_uid);
4406
4407           /* does this protocol need to be run as root? */
4408           if (!(flags & AS_USER))
4409             unbecome_user();
4410
4411           /* does this protocol need to be run as the connected user? */
4412           if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
4413             if (flags & AS_GUEST) 
4414               flags &= ~AS_USER;
4415             else
4416               return(ERROR(ERRSRV,ERRinvnid));
4417           }
4418           /* this code is to work around a bug is MS client 3 without
4419              introducing a security hole - it needs to be able to do
4420              print queue checks as guest if it isn't logged in properly */
4421           if (flags & AS_USER)
4422             flags &= ~AS_GUEST;
4423
4424           /* does it need write permission? */
4425           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4426             return(ERROR(ERRSRV,ERRaccess));
4427
4428           /* ipc services are limited */
4429           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4430             return(ERROR(ERRSRV,ERRaccess));        
4431
4432           /* load service specific parameters */
4433           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4434             return(ERROR(ERRSRV,ERRaccess));
4435
4436           /* does this protocol need to be run as guest? */
4437           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4438             return(ERROR(ERRSRV,ERRaccess));
4439
4440           last_inbuf = inbuf;
4441
4442           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4443         }
4444       else
4445         {
4446           outsize = reply_unknown(inbuf,outbuf);
4447         }
4448     }
4449
4450 #if PROFILING
4451   GetTimeOfDay(&msg_end_time);
4452   if (!(smb_messages[match].flags & TIME_INIT))
4453     {
4454       smb_messages[match].time = 0;
4455       smb_messages[match].flags |= TIME_INIT;
4456     }
4457   {
4458     unsigned long this_time =     
4459       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4460         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4461     smb_messages[match].time += this_time;
4462     total_time += this_time;
4463   }
4464   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4465            smb_fn_name(type),smb_messages[match].time,
4466         (100.0*smb_messages[match].time) / total_time));
4467 #endif
4468
4469   return(outsize);
4470 }
4471
4472
4473 /****************************************************************************
4474   construct a chained reply and add it to the already made reply
4475   **************************************************************************/
4476 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4477 {
4478   static char *orig_inbuf;
4479   static char *orig_outbuf;
4480   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4481   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4482   char *inbuf2, *outbuf2;
4483   int outsize2;
4484   char inbuf_saved[smb_wct];
4485   char outbuf_saved[smb_wct];
4486   extern int chain_size;
4487   int wct = CVAL(outbuf,smb_wct);
4488   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4489
4490   /* maybe its not chained */
4491   if (smb_com2 == 0xFF) {
4492     CVAL(outbuf,smb_vwv0) = 0xFF;
4493     return outsize;
4494   }
4495
4496   if (chain_size == 0) {
4497     /* this is the first part of the chain */
4498     orig_inbuf = inbuf;
4499     orig_outbuf = outbuf;
4500   }
4501
4502   /* we need to tell the client where the next part of the reply will be */
4503   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4504   CVAL(outbuf,smb_vwv0) = smb_com2;
4505
4506   /* remember how much the caller added to the chain, only counting stuff
4507      after the parameter words */
4508   chain_size += outsize - smb_wct;
4509
4510   /* work out pointers into the original packets. The
4511      headers on these need to be filled in */
4512   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4513   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4514
4515   /* remember the original command type */
4516   smb_com1 = CVAL(orig_inbuf,smb_com);
4517
4518   /* save the data which will be overwritten by the new headers */
4519   memcpy(inbuf_saved,inbuf2,smb_wct);
4520   memcpy(outbuf_saved,outbuf2,smb_wct);
4521
4522   /* give the new packet the same header as the last part of the SMB */
4523   memmove(inbuf2,inbuf,smb_wct);
4524
4525   /* create the in buffer */
4526   CVAL(inbuf2,smb_com) = smb_com2;
4527
4528   /* create the out buffer */
4529   bzero(outbuf2,smb_size);
4530   set_message(outbuf2,0,0,True);
4531   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4532   
4533   memcpy(outbuf2+4,inbuf2+4,4);
4534   CVAL(outbuf2,smb_rcls) = SUCCESS;
4535   CVAL(outbuf2,smb_reh) = 0;
4536   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4537                                                                   means a reply */
4538   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4539   SSVAL(outbuf2,smb_err,SUCCESS);
4540   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4541   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4542   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4543   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4544
4545   DEBUG(3,("Chained message\n"));
4546   show_msg(inbuf2);
4547
4548   /* process the request */
4549   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4550                             bufsize-chain_size);
4551
4552   /* copy the new reply and request headers over the old ones, but
4553      preserve the smb_com field */
4554   memmove(orig_outbuf,outbuf2,smb_wct);
4555   CVAL(orig_outbuf,smb_com) = smb_com1;
4556
4557   /* restore the saved data, being careful not to overwrite any
4558    data from the reply header */
4559   memcpy(inbuf2,inbuf_saved,smb_wct);
4560   {
4561     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4562     if (ofs < 0) ofs = 0;
4563     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4564   }
4565
4566   return outsize2;
4567 }
4568
4569
4570
4571 /****************************************************************************
4572   construct a reply to the incoming packet
4573 ****************************************************************************/
4574 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4575 {
4576   int type = CVAL(inbuf,smb_com);
4577   int outsize = 0;
4578   int msg_type = CVAL(inbuf,0);
4579   extern int chain_size;
4580
4581   smb_last_time = time(NULL);
4582
4583   chain_size = 0;
4584   chain_fnum = -1;
4585
4586   bzero(outbuf,smb_size);
4587
4588   if (msg_type != 0)
4589     return(reply_special(inbuf,outbuf));  
4590
4591   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4592   set_message(outbuf,0,0,True);
4593   
4594   memcpy(outbuf+4,inbuf+4,4);
4595   CVAL(outbuf,smb_rcls) = SUCCESS;
4596   CVAL(outbuf,smb_reh) = 0;
4597   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4598                                                              means a reply */
4599   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4600   SSVAL(outbuf,smb_err,SUCCESS);
4601   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4602   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4603   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4604   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4605
4606   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4607
4608   outsize += chain_size;
4609
4610   if(outsize > 4)
4611     smb_setlen(outbuf,outsize - 4);
4612   return(outsize);
4613 }
4614
4615 /****************************************************************************
4616   process commands from the client
4617 ****************************************************************************/
4618 static void process(void)
4619 {
4620   extern int Client;
4621
4622   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4623   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4624   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
4625     return;
4626
4627   InBuffer += SMB_ALIGNMENT;
4628   OutBuffer += SMB_ALIGNMENT;
4629
4630 #if PRIME_NMBD
4631   DEBUG(3,("priming nmbd\n"));
4632   {
4633     struct in_addr ip;
4634     ip = *interpret_addr2("localhost");
4635     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4636     *OutBuffer = 0;
4637     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4638   }
4639 #endif    
4640
4641   while (True)
4642   {
4643     int deadtime = lp_deadtime()*60;
4644     int counter;
4645     int last_keepalive=0;
4646     int service_load_counter = 0;
4647     BOOL got_smb = False;
4648
4649     if (deadtime <= 0)
4650       deadtime = DEFAULT_SMBD_TIMEOUT;
4651
4652     if (lp_readprediction())
4653       do_read_prediction();
4654
4655     errno = 0;      
4656
4657     for (counter=SMBD_SELECT_LOOP; 
4658           !receive_message_or_smb(Client,oplock_sock,
4659                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
4660           counter += SMBD_SELECT_LOOP)
4661     {
4662       int i;
4663       time_t t;
4664       BOOL allidle = True;
4665       extern int keepalive;
4666
4667       if (counter > 365 * 3600) /* big number of seconds. */
4668       {
4669         counter = 0;
4670         service_load_counter = 0;
4671       }
4672
4673       if (smb_read_error == READ_EOF) 
4674       {
4675         DEBUG(3,("end of file from client\n"));
4676         return;
4677       }
4678
4679       if (smb_read_error == READ_ERROR) 
4680       {
4681         DEBUG(3,("receive_smb error (%s) exiting\n",
4682                   strerror(errno)));
4683         return;
4684       }
4685
4686       t = time(NULL);
4687
4688       /* become root again if waiting */
4689       unbecome_user();
4690
4691       /* check for smb.conf reload */
4692       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4693       {
4694         service_load_counter = counter;
4695
4696         /* reload services, if files have changed. */
4697         reload_services(True);
4698       }
4699
4700       /* automatic timeout if all connections are closed */      
4701       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
4702       {
4703         DEBUG(2,("%s Closing idle connection\n",timestring()));
4704         return;
4705       }
4706
4707       if (keepalive && (counter-last_keepalive)>keepalive) 
4708       {
4709         extern int password_client;
4710         if (!send_keepalive(Client))
4711         { 
4712           DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4713           return;
4714         }           
4715         /* also send a keepalive to the password server if its still
4716            connected */
4717         if (password_client != -1)
4718           send_keepalive(password_client);
4719         last_keepalive = counter;
4720       }
4721
4722       /* check for connection timeouts */
4723       for (i=0;i<MAX_CONNECTIONS;i++)
4724         if (Connections[i].open)
4725         {
4726           /* close dirptrs on connections that are idle */
4727           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4728             dptr_idlecnum(i);
4729
4730           if (Connections[i].num_files_open > 0 ||
4731                      (t-Connections[i].lastused)<deadtime)
4732             allidle = False;
4733         }
4734
4735       if (allidle && num_connections_open>0) 
4736       {
4737         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4738         return;
4739       }
4740     }
4741
4742     if(got_smb)
4743       process_smb(InBuffer, OutBuffer);
4744     else
4745       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4746   }
4747 }
4748
4749
4750 /****************************************************************************
4751   initialise connect, service and file structs
4752 ****************************************************************************/
4753 static void init_structs(void )
4754 {
4755   int i;
4756   get_myname(myhostname,NULL);
4757
4758   for (i=0;i<MAX_CONNECTIONS;i++)
4759     {
4760       Connections[i].open = False;
4761       Connections[i].num_files_open=0;
4762       Connections[i].lastused=0;
4763       Connections[i].used=False;
4764       string_init(&Connections[i].user,"");
4765       string_init(&Connections[i].dirpath,"");
4766       string_init(&Connections[i].connectpath,"");
4767       string_init(&Connections[i].origpath,"");
4768     }
4769
4770   for (i=0;i<MAX_OPEN_FILES;i++)
4771     {
4772       Files[i].open = False;
4773       string_init(&Files[i].name,"");
4774
4775     }
4776
4777   for (i=0;i<MAX_OPEN_FILES;i++)
4778     {
4779       file_fd_struct *fd_ptr = &FileFd[i];
4780       fd_ptr->ref_count = 0;
4781       fd_ptr->dev = (int32)-1;
4782       fd_ptr->inode = (int32)-1;
4783       fd_ptr->fd = -1;
4784       fd_ptr->fd_readonly = -1;
4785       fd_ptr->fd_writeonly = -1;
4786       fd_ptr->real_open_flags = -1;
4787     }
4788
4789   init_dptrs();
4790 }
4791
4792 /****************************************************************************
4793 usage on the program
4794 ****************************************************************************/
4795 static void usage(char *pname)
4796 {
4797   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4798
4799   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4800   printf("Version %s\n",VERSION);
4801   printf("\t-D                    become a daemon\n");
4802   printf("\t-p port               listen on the specified port\n");
4803   printf("\t-d debuglevel         set the debuglevel\n");
4804   printf("\t-l log basename.      Basename for log/debug files\n");
4805   printf("\t-s services file.     Filename of services file\n");
4806   printf("\t-P                    passive only\n");
4807   printf("\t-a                    overwrite log file, don't append\n");
4808   printf("\n");
4809 }
4810
4811
4812 /****************************************************************************
4813   main program
4814 ****************************************************************************/
4815  int main(int argc,char *argv[])
4816 {
4817   extern BOOL append_log;
4818   /* shall I run as a daemon */
4819   BOOL is_daemon = False;
4820   int port = SMB_PORT;
4821   int opt;
4822   extern char *optarg;
4823   char pidFile[100] = { 0 };
4824
4825 #ifdef NEED_AUTH_PARAMETERS
4826   set_auth_parameters(argc,argv);
4827 #endif
4828
4829 #ifdef SecureWare
4830   setluid(0);
4831 #endif
4832
4833   append_log = True;
4834
4835   TimeInit();
4836
4837   strcpy(debugf,SMBLOGFILE);  
4838
4839   setup_logging(argv[0],False);
4840
4841   charset_initialise();
4842
4843   /* make absolutely sure we run as root - to handle cases whre people
4844      are crazy enough to have it setuid */
4845 #ifdef USE_SETRES
4846   setresuid(0,0,0);
4847 #else
4848   setuid(0);
4849   seteuid(0);
4850   setuid(0);
4851   seteuid(0);
4852 #endif
4853
4854   fault_setup(exit_server);
4855   signal(SIGTERM , SIGNAL_CAST dflt_sig);
4856
4857   /* we want total control over the permissions on created files,
4858      so set our umask to 0 */
4859   umask(0);
4860
4861   GetWd(OriginalDir);
4862
4863   init_uid();
4864
4865   /* this is for people who can't start the program correctly */
4866   while (argc > 1 && (*argv[1] != '-'))
4867     {
4868       argv++;
4869       argc--;
4870     }
4871
4872   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
4873     switch (opt)
4874       {
4875       case 'f':
4876         strncpy(pidFile, optarg, sizeof(pidFile));
4877         break;
4878       case 'O':
4879         strcpy(user_socket_options,optarg);
4880         break;
4881       case 'i':
4882         strcpy(scope,optarg);
4883         break;
4884       case 'P':
4885         {
4886           extern BOOL passive;
4887           passive = True;
4888         }
4889         break;  
4890       case 's':
4891         strcpy(servicesf,optarg);
4892         break;
4893       case 'l':
4894         strcpy(debugf,optarg);
4895         break;
4896       case 'a':
4897         {
4898           extern BOOL append_log;
4899           append_log = !append_log;
4900         }
4901         break;
4902       case 'D':
4903         is_daemon = True;
4904         break;
4905       case 'd':
4906         if (*optarg == 'A')
4907           DEBUGLEVEL = 10000;
4908         else
4909           DEBUGLEVEL = atoi(optarg);
4910         break;
4911       case 'p':
4912         port = atoi(optarg);
4913         break;
4914       case 'h':
4915         usage(argv[0]);
4916         exit(0);
4917         break;
4918       default:
4919         usage(argv[0]);
4920         exit(1);
4921       }
4922
4923   reopen_logs();
4924
4925   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
4926   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4927
4928 #ifndef NO_GETRLIMIT
4929 #ifdef RLIMIT_NOFILE
4930   {
4931     struct rlimit rlp;
4932     getrlimit(RLIMIT_NOFILE, &rlp);
4933     rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
4934     setrlimit(RLIMIT_NOFILE, &rlp);
4935     getrlimit(RLIMIT_NOFILE, &rlp);
4936     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
4937   }
4938 #endif
4939 #endif
4940
4941   
4942   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4943         getuid(),getgid(),geteuid(),getegid()));
4944
4945   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
4946     {
4947       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4948       exit(1);
4949     }
4950
4951   init_structs();
4952
4953   if (!reload_services(False))
4954     return(-1); 
4955
4956   codepage_initialise(lp_client_code_page());
4957
4958   strcpy(myworkgroup, lp_workgroup());
4959
4960 #ifndef NO_SIGNAL_TEST
4961   signal(SIGHUP,SIGNAL_CAST sig_hup);
4962 #endif
4963   
4964   DEBUG(3,("%s loaded services\n",timestring()));
4965
4966   if (!is_daemon && !is_a_socket(0))
4967     {
4968       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4969       is_daemon = True;
4970     }
4971
4972   if (is_daemon)
4973     {
4974       DEBUG(3,("%s becoming a daemon\n",timestring()));
4975       become_daemon();
4976     }
4977
4978   if (*pidFile)
4979     {
4980       int     fd;
4981       char    buf[20];
4982
4983       if ((fd = open(pidFile,
4984 #ifdef O_NONBLOCK
4985          O_NONBLOCK | 
4986 #endif
4987          O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
4988         {
4989            DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
4990            exit(1);
4991         }
4992       if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
4993         {
4994           DEBUG(0,("ERROR: smbd is already running\n"));
4995           exit(1);
4996         }
4997       sprintf(buf, "%u\n", (unsigned int) getpid());
4998       if (write(fd, buf, strlen(buf)) < 0)
4999         {
5000           DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5001           exit(1);
5002         }
5003       /* Leave pid file open & locked for the duration... */
5004     }
5005
5006   if (!open_sockets(is_daemon,port))
5007     exit(1);
5008
5009 #ifdef FAST_SHARE_MODES
5010   if (!start_share_mode_mgmt())
5011     exit(1);
5012 #endif /* FAST_SHARE_MODES */
5013
5014   /* possibly reload the services file. */
5015   reload_services(True);
5016
5017   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5018
5019   if (*lp_rootdir())
5020     {
5021       if (sys_chroot(lp_rootdir()) == 0)
5022         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5023     }
5024
5025   /* Setup the oplock IPC socket. */
5026   if(!open_oplock_ipc())
5027     exit(1);
5028
5029   process();
5030   close_sockets();
5031
5032   exit_server("normal exit");
5033   return(0);
5034 }
5035
5036