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