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