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