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