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