Makefile, loadparm.c, server.c, smb.h, util.c: Patch from
[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 (validated_username(vuid))
3357         {
3358           strcpy(user,validated_username(vuid));
3359           return(make_connection(user,user,password,pwlen,dev,vuid));
3360         }
3361     }
3362
3363   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3364     return(-4);
3365   }
3366
3367   /* you can only connect to the IPC$ service as an ipc device */
3368   if (strequal(service,"IPC$"))
3369     strcpy(dev,"IPC");
3370
3371   if (*dev == '?' || !*dev)
3372     {
3373       if (lp_print_ok(snum))
3374         strcpy(dev,"LPT1:");
3375       else
3376         strcpy(dev,"A:");
3377     }
3378
3379   /* if the request is as a printer and you can't print then refuse */
3380   strupper(dev);
3381   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3382     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3383     return(-6);
3384   }
3385
3386   /* lowercase the user name */
3387   strlower(user);
3388
3389   /* add it as a possible user name */
3390   add_session_user(service);
3391
3392   /* shall we let them in? */
3393   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3394     {
3395       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3396       return(-1);
3397     }
3398   
3399   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3400   if (cnum < 0)
3401     {
3402       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3403       return(-1);
3404     }
3405
3406   pcon = &Connections[cnum];
3407   bzero((char *)pcon,sizeof(*pcon));
3408
3409   /* find out some info about the user */
3410   pass = Get_Pwnam(user,True);
3411
3412   if (pass == NULL)
3413     {
3414       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3415       return(-7);
3416     }
3417
3418   pcon->read_only = lp_readonly(snum);
3419
3420   {
3421     pstring list;
3422     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3423     string_sub(list,"%S",service);
3424
3425     if (user_in_list(user,list))
3426       pcon->read_only = True;
3427
3428     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3429     string_sub(list,"%S",service);
3430
3431     if (user_in_list(user,list))
3432       pcon->read_only = False;    
3433   }
3434
3435   /* admin user check */
3436
3437   /* JRA - original code denied admin user if the share was
3438      marked read_only. Changed as I don't think this is needed,
3439      but old code left in case there is a problem here.
3440    */
3441   if (user_in_list(user,lp_admin_users(snum)) 
3442 #if 0
3443       && !pcon->read_only)
3444 #else
3445       )
3446 #endif
3447     {
3448       pcon->admin_user = True;
3449       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3450     }
3451   else
3452     pcon->admin_user = False;
3453     
3454   pcon->force_user = force;
3455   pcon->vuid = vuid;
3456   pcon->uid = pass->pw_uid;
3457   pcon->gid = pass->pw_gid;
3458   pcon->num_files_open = 0;
3459   pcon->lastused = time(NULL);
3460   pcon->service = snum;
3461   pcon->used = True;
3462   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3463   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3464   pcon->dirptr = NULL;
3465   pcon->veto_list = NULL;
3466   pcon->hide_list = NULL;
3467   pcon->veto_oplock_list = NULL;
3468   string_set(&pcon->dirpath,"");
3469   string_set(&pcon->user,user);
3470
3471 #if HAVE_GETGRNAM 
3472   if (*lp_force_group(snum))
3473     {
3474       struct group *gptr;
3475       pstring gname;
3476
3477       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3478       /* default service may be a group name            */
3479       string_sub(gname,"%S",service);
3480       gptr = (struct group *)getgrnam(gname);
3481
3482       if (gptr)
3483         {
3484           pcon->gid = gptr->gr_gid;
3485           DEBUG(3,("Forced group %s\n",gname));
3486         }
3487       else
3488         DEBUG(1,("Couldn't find group %s\n",gname));
3489     }
3490 #endif
3491
3492   if (*lp_force_user(snum))
3493     {
3494       struct passwd *pass2;
3495       fstring fuser;
3496       fstrcpy(fuser,lp_force_user(snum));
3497       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3498       if (pass2)
3499         {
3500           pcon->uid = pass2->pw_uid;
3501           string_set(&pcon->user,fuser);
3502           fstrcpy(user,fuser);
3503           pcon->force_user = True;
3504           DEBUG(3,("Forced user %s\n",fuser));    
3505         }
3506       else
3507         DEBUG(1,("Couldn't find user %s\n",fuser));
3508     }
3509
3510   {
3511     pstring s;
3512     pstrcpy(s,lp_pathname(snum));
3513     standard_sub(cnum,s);
3514     string_set(&pcon->connectpath,s);
3515     DEBUG(3,("Connect path is %s\n",s));
3516   }
3517
3518   /* groups stuff added by ih */
3519   pcon->ngroups = 0;
3520   pcon->igroups = NULL;
3521   pcon->groups = NULL;
3522   pcon->attrs = NULL;
3523
3524   if (!IS_IPC(cnum))
3525     {
3526       /* Find all the groups this uid is in and store them. Used by become_user() */
3527       setup_groups(pcon->user,pcon->uid,pcon->gid,
3528                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3529       
3530       /* check number of connections */
3531       if (!claim_connection(cnum,
3532                             lp_servicename(SNUM(cnum)),
3533                             lp_max_connections(SNUM(cnum)),False))
3534         {
3535           DEBUG(1,("too many connections - rejected\n"));
3536           return(-8);
3537         }  
3538
3539       if (lp_status(SNUM(cnum)))
3540         claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3541     } /* IS_IPC */
3542
3543   pcon->open = True;
3544
3545   /* execute any "root preexec = " line */
3546   if (*lp_rootpreexec(SNUM(cnum)))
3547     {
3548       pstring cmd;
3549       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3550       standard_sub(cnum,cmd);
3551       DEBUG(5,("cmd=%s\n",cmd));
3552       smbrun(cmd,NULL,False);
3553     }
3554
3555   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3556     {
3557       DEBUG(0,("Can't become connected user!\n"));
3558       pcon->open = False;
3559       if (!IS_IPC(cnum)) {
3560         yield_connection(cnum,
3561                          lp_servicename(SNUM(cnum)),
3562                          lp_max_connections(SNUM(cnum)));
3563         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3564       }
3565       return(-1);
3566     }
3567
3568   if (ChDir(pcon->connectpath) != 0)
3569     {
3570       DEBUG(0,("Can't change directory to %s (%s)\n",
3571                pcon->connectpath,strerror(errno)));
3572       pcon->open = False;
3573       unbecome_user();
3574       if (!IS_IPC(cnum)) {
3575         yield_connection(cnum,
3576                          lp_servicename(SNUM(cnum)),
3577                          lp_max_connections(SNUM(cnum)));
3578         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3579       }
3580       return(-5);      
3581     }
3582
3583   string_set(&pcon->origpath,pcon->connectpath);
3584
3585 #if SOFTLINK_OPTIMISATION
3586   /* resolve any soft links early */
3587   {
3588     pstring s;
3589     pstrcpy(s,pcon->connectpath);
3590     GetWd(s);
3591     string_set(&pcon->connectpath,s);
3592     ChDir(pcon->connectpath);
3593   }
3594 #endif
3595
3596   num_connections_open++;
3597   add_session_user(user);
3598   
3599   /* execute any "preexec = " line */
3600   if (*lp_preexec(SNUM(cnum)))
3601     {
3602       pstring cmd;
3603       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3604       standard_sub(cnum,cmd);
3605       smbrun(cmd,NULL,False);
3606     }
3607   
3608   /* we've finished with the sensitive stuff */
3609   unbecome_user();
3610
3611   /* Add veto/hide lists */
3612   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3613   {
3614     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3615     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3616     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3617   }
3618
3619   {
3620     extern int Client;
3621     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3622                             timestring(),
3623                             remote_machine,
3624                             client_addr(Client),
3625                             lp_servicename(SNUM(cnum)),user,
3626                             pcon->uid,
3627                             pcon->gid,
3628                             (int)getpid()));
3629   }
3630
3631   return(cnum);
3632 }
3633
3634 /****************************************************************************
3635   Attempt to break an oplock on a file (if oplocked).
3636   Returns True if the file was closed as a result of
3637   the oplock break, False otherwise.
3638   Used as a last ditch attempt to free a space in the 
3639   file table when we have run out.
3640 ****************************************************************************/
3641
3642 static BOOL attempt_close_oplocked_file(files_struct *fp)
3643 {
3644
3645   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3646
3647   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3648
3649     /* Try and break the oplock. */
3650     file_fd_struct *fsp = fp->fd_ptr;
3651     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3652       if(!fp->open) /* Did the oplock break close the file ? */
3653         return True;
3654     }
3655   }
3656
3657   return False;
3658 }
3659
3660 /****************************************************************************
3661   find first available file slot
3662 ****************************************************************************/
3663 int find_free_file(void )
3664 {
3665         int i;
3666         static int first_file;
3667
3668         /* we want to give out file handles differently on each new
3669            connection because of a common bug in MS clients where they try to
3670            reuse a file descriptor from an earlier smb connection. This code
3671            increases the chance that the errant client will get an error rather
3672            than causing corruption */
3673         if (first_file == 0) {
3674                 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3675                 if (first_file == 0) first_file = 1;
3676         }
3677
3678         if (first_file >= MAX_OPEN_FILES)
3679                 first_file = 1;
3680
3681         for (i=first_file;i<MAX_OPEN_FILES;i++)
3682                 if (!Files[i].open && !Files[i].reserved) {
3683                         memset(&Files[i], 0, sizeof(Files[i]));
3684                         first_file = i+1;
3685                         Files[i].reserved = True;
3686                         return(i);
3687                 }
3688
3689         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3690         for (i=1;i<first_file;i++)
3691                 if (!Files[i].open && !Files[i].reserved) {
3692                         memset(&Files[i], 0, sizeof(Files[i]));
3693                         first_file = i+1;
3694                         Files[i].reserved = True;
3695                         return(i);
3696                 }
3697
3698         /* 
3699          * Before we give up, go through the open files 
3700          * and see if there are any files opened with a
3701          * batch oplock. If so break the oplock and then
3702          * re-use that entry (if it becomes closed).
3703          * This may help as NT/95 clients tend to keep
3704          * files batch oplocked for quite a long time
3705          * after they have finished with them.
3706          */
3707         for (i=first_file;i<MAX_OPEN_FILES;i++) {
3708           if(attempt_close_oplocked_file( &Files[i])) {
3709             memset(&Files[i], 0, sizeof(Files[i]));
3710             first_file = i+1;
3711             Files[i].reserved = True;
3712             return(i);
3713           }
3714         }
3715
3716         for (i=1;i<MAX_OPEN_FILES;i++) {
3717           if(attempt_close_oplocked_file( &Files[i])) {
3718             memset(&Files[i], 0, sizeof(Files[i]));
3719             first_file = i+1;
3720             Files[i].reserved = True;
3721             return(i);
3722           }
3723         }
3724
3725         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3726         return(-1);
3727 }
3728
3729 /****************************************************************************
3730   find first available connection slot, starting from a random position.
3731 The randomisation stops problems with the server dieing and clients
3732 thinking the server is still available.
3733 ****************************************************************************/
3734 static int find_free_connection(int hash )
3735 {
3736   int i;
3737   BOOL used=False;
3738   hash = (hash % (MAX_CONNECTIONS-2))+1;
3739
3740  again:
3741
3742   for (i=hash+1;i!=hash;)
3743     {
3744       if (!Connections[i].open && Connections[i].used == used) 
3745         {
3746           DEBUG(3,("found free connection number %d\n",i));
3747           return(i);
3748         }
3749       i++;
3750       if (i == MAX_CONNECTIONS)
3751         i = 1;
3752     }
3753
3754   if (!used)
3755     {
3756       used = !used;
3757       goto again;
3758     }
3759
3760   DEBUG(1,("ERROR! Out of connection structures\n"));
3761   return(-1);
3762 }
3763
3764
3765 /****************************************************************************
3766 reply for the core protocol
3767 ****************************************************************************/
3768 int reply_corep(char *outbuf)
3769 {
3770   int outsize = set_message(outbuf,1,0,True);
3771
3772   Protocol = PROTOCOL_CORE;
3773
3774   return outsize;
3775 }
3776
3777
3778 /****************************************************************************
3779 reply for the coreplus protocol
3780 ****************************************************************************/
3781 int reply_coreplus(char *outbuf)
3782 {
3783   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3784   int outsize = set_message(outbuf,13,0,True);
3785   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3786                                  readbraw and writebraw (possibly) */
3787   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3788   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3789
3790   Protocol = PROTOCOL_COREPLUS;
3791
3792   return outsize;
3793 }
3794
3795
3796 /****************************************************************************
3797 reply for the lanman 1.0 protocol
3798 ****************************************************************************/
3799 int reply_lanman1(char *outbuf)
3800 {
3801   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3802   int secword=0;
3803   BOOL doencrypt = SMBENCRYPT();
3804   time_t t = time(NULL);
3805
3806   if (lp_security()>=SEC_USER) secword |= 1;
3807   if (doencrypt) secword |= 2;
3808
3809   set_message(outbuf,13,doencrypt?8:0,True);
3810   SSVAL(outbuf,smb_vwv1,secword); 
3811   /* Create a token value and add it to the outgoing packet. */
3812   if (doencrypt) 
3813     generate_next_challenge(smb_buf(outbuf));
3814
3815   Protocol = PROTOCOL_LANMAN1;
3816
3817   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3818   SSVAL(outbuf,smb_vwv2,max_recv);
3819   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3820   SSVAL(outbuf,smb_vwv4,1);
3821   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3822                                  readbraw writebraw (possibly) */
3823   SIVAL(outbuf,smb_vwv6,getpid());
3824   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3825
3826   put_dos_date(outbuf,smb_vwv8,t);
3827
3828   return (smb_len(outbuf)+4);
3829 }
3830
3831
3832 /****************************************************************************
3833 reply for the lanman 2.0 protocol
3834 ****************************************************************************/
3835 int reply_lanman2(char *outbuf)
3836 {
3837   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3838   int secword=0;
3839   BOOL doencrypt = SMBENCRYPT();
3840   time_t t = time(NULL);
3841   struct cli_state *cli = NULL;
3842   char cryptkey[8];
3843   char crypt_len = 0;
3844
3845   if (lp_security() == SEC_SERVER) {
3846           cli = server_cryptkey();
3847   }
3848
3849   if (cli) {
3850           DEBUG(3,("using password server validation\n"));
3851           doencrypt = ((cli->sec_mode & 2) != 0);
3852   }
3853
3854   if (lp_security()>=SEC_USER) secword |= 1;
3855   if (doencrypt) secword |= 2;
3856
3857   if (doencrypt) {
3858           crypt_len = 8;
3859           if (!cli) {
3860                   generate_next_challenge(cryptkey);
3861           } else {
3862                   memcpy(cryptkey, cli->cryptkey, 8);
3863                   set_challenge(cli->cryptkey);
3864           }
3865   }
3866
3867   set_message(outbuf,13,crypt_len,True);
3868   SSVAL(outbuf,smb_vwv1,secword); 
3869   SIVAL(outbuf,smb_vwv6,getpid());
3870   if (doencrypt) 
3871           memcpy(smb_buf(outbuf), cryptkey, 8);
3872
3873   Protocol = PROTOCOL_LANMAN2;
3874
3875   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3876   SSVAL(outbuf,smb_vwv2,max_recv);
3877   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3878   SSVAL(outbuf,smb_vwv4,1);
3879   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3880   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3881   put_dos_date(outbuf,smb_vwv8,t);
3882
3883   return (smb_len(outbuf)+4);
3884 }
3885
3886
3887 /****************************************************************************
3888 reply for the nt protocol
3889 ****************************************************************************/
3890 int reply_nt1(char *outbuf)
3891 {
3892   /* dual names + lock_and_read + nt SMBs + remote API calls */
3893   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
3894 /*
3895   other valid capabilities which we may support at some time...
3896                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3897                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3898  */
3899
3900   int secword=0;
3901   BOOL doencrypt = SMBENCRYPT();
3902   time_t t = time(NULL);
3903   int data_len;
3904   struct cli_state *cli = NULL;
3905   char cryptkey[8];
3906   char crypt_len = 0;
3907
3908   if (lp_security() == SEC_SERVER) {
3909           cli = server_cryptkey();
3910   }
3911
3912   if (cli) {
3913           DEBUG(3,("using password server validation\n"));
3914           doencrypt = ((cli->sec_mode & 2) != 0);
3915   }
3916
3917   if (doencrypt) {
3918           crypt_len = 8;
3919           if (!cli) {
3920                   generate_next_challenge(cryptkey);
3921           } else {
3922                   memcpy(cryptkey, cli->cryptkey, 8);
3923                   set_challenge(cli->cryptkey);
3924           }
3925   }
3926
3927   if (lp_readraw() && lp_writeraw()) {
3928           capabilities |= CAP_RAW_MODE;
3929   }
3930
3931   if (lp_security() >= SEC_USER) secword |= 1;
3932   if (doencrypt) secword |= 2;
3933
3934   /* decide where (if) to put the encryption challenge, and
3935      follow it with the OEM'd domain name
3936    */
3937   data_len = crypt_len + strlen(myworkgroup) + 1;
3938
3939   set_message(outbuf,17,data_len,True);
3940   strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3941
3942   CVAL(outbuf,smb_vwv1) = secword;
3943   SSVALS(outbuf,smb_vwv16+1,crypt_len);
3944   if (doencrypt) 
3945           memcpy(smb_buf(outbuf), cryptkey, 8);
3946
3947   Protocol = PROTOCOL_NT1;
3948
3949   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3950   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3951   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3952   SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
3953   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3954   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3955   put_long_date(outbuf+smb_vwv11+1,t);
3956   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3957   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3958
3959   return (smb_len(outbuf)+4);
3960 }
3961
3962 /* these are the protocol lists used for auto architecture detection:
3963
3964 WinNT 3.51:
3965 protocol [PC NETWORK PROGRAM 1.0]
3966 protocol [XENIX CORE]
3967 protocol [MICROSOFT NETWORKS 1.03]
3968 protocol [LANMAN1.0]
3969 protocol [Windows for Workgroups 3.1a]
3970 protocol [LM1.2X002]
3971 protocol [LANMAN2.1]
3972 protocol [NT LM 0.12]
3973
3974 Win95:
3975 protocol [PC NETWORK PROGRAM 1.0]
3976 protocol [XENIX CORE]
3977 protocol [MICROSOFT NETWORKS 1.03]
3978 protocol [LANMAN1.0]
3979 protocol [Windows for Workgroups 3.1a]
3980 protocol [LM1.2X002]
3981 protocol [LANMAN2.1]
3982 protocol [NT LM 0.12]
3983
3984 OS/2:
3985 protocol [PC NETWORK PROGRAM 1.0]
3986 protocol [XENIX CORE]
3987 protocol [LANMAN1.0]
3988 protocol [LM1.2X002]
3989 protocol [LANMAN2.1]
3990 */
3991
3992 /*
3993   * Modified to recognize the architecture of the remote machine better.
3994   *
3995   * This appears to be the matrix of which protocol is used by which
3996   * MS product.
3997        Protocol                       WfWg    Win95   WinNT  OS/2
3998        PC NETWORK PROGRAM 1.0          1       1       1      1
3999        XENIX CORE                                      2      2
4000        MICROSOFT NETWORKS 3.0          2       2       
4001        DOS LM1.2X002                   3       3       
4002        MICROSOFT NETWORKS 1.03                         3
4003        DOS LANMAN2.1                   4       4       
4004        LANMAN1.0                                       4      3
4005        Windows for Workgroups 3.1a     5       5       5
4006        LM1.2X002                                       6      4
4007        LANMAN2.1                                       7      5
4008        NT LM 0.12                              6       8
4009   *
4010   *  tim@fsg.com 09/29/95
4011   */
4012   
4013 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4014 #define ARCH_WIN95    0x2
4015 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4016 #define ARCH_WINNT    0x8
4017 #define ARCH_SAMBA    0x10
4018  
4019 #define ARCH_ALL      0x1F
4020  
4021 /* List of supported protocols, most desired first */
4022 struct {
4023   char *proto_name;
4024   char *short_name;
4025   int (*proto_reply_fn)(char *);
4026   int protocol_level;
4027 } supported_protocols[] = {
4028   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4029   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4030   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4031   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4032   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4033   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4034   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4035   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4036   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4037   {NULL,NULL},
4038 };
4039
4040
4041 /****************************************************************************
4042   reply to a negprot
4043 ****************************************************************************/
4044 static int reply_negprot(char *inbuf,char *outbuf)
4045 {
4046   int outsize = set_message(outbuf,1,0,True);
4047   int Index=0;
4048   int choice= -1;
4049   int protocol;
4050   char *p;
4051   int bcc = SVAL(smb_buf(inbuf),-2);
4052   int arch = ARCH_ALL;
4053
4054   p = smb_buf(inbuf)+1;
4055   while (p < (smb_buf(inbuf) + bcc))
4056     { 
4057       Index++;
4058       DEBUG(3,("Requested protocol [%s]\n",p));
4059       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4060         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4061       else if (strcsequal(p,"DOS LM1.2X002"))
4062         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4063       else if (strcsequal(p,"DOS LANMAN2.1"))
4064         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4065       else if (strcsequal(p,"NT LM 0.12"))
4066         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4067       else if (strcsequal(p,"LANMAN2.1"))
4068         arch &= ( ARCH_WINNT | ARCH_OS2 );
4069       else if (strcsequal(p,"LM1.2X002"))
4070         arch &= ( ARCH_WINNT | ARCH_OS2 );
4071       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4072         arch &= ARCH_WINNT;
4073       else if (strcsequal(p,"XENIX CORE"))
4074         arch &= ( ARCH_WINNT | ARCH_OS2 );
4075       else if (strcsequal(p,"Samba")) {
4076         arch = ARCH_SAMBA;
4077         break;
4078       }
4079  
4080       p += strlen(p) + 2;
4081     }
4082     
4083   switch ( arch ) {
4084   case ARCH_SAMBA:
4085     set_remote_arch(RA_SAMBA);
4086     break;
4087   case ARCH_WFWG:
4088     set_remote_arch(RA_WFWG);
4089     break;
4090   case ARCH_WIN95:
4091     set_remote_arch(RA_WIN95);
4092     break;
4093   case ARCH_WINNT:
4094     set_remote_arch(RA_WINNT);
4095     break;
4096   case ARCH_OS2:
4097     set_remote_arch(RA_OS2);
4098     break;
4099   default:
4100     set_remote_arch(RA_UNKNOWN);
4101     break;
4102   }
4103  
4104   /* possibly reload - change of architecture */
4105   reload_services(True);      
4106     
4107   /* a special case to stop password server loops */
4108   if (Index == 1 && strequal(remote_machine,myhostname) && 
4109       lp_security()==SEC_SERVER)
4110     exit_server("Password server loop!");
4111   
4112   /* Check for protocols, most desirable first */
4113   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4114     {
4115       p = smb_buf(inbuf)+1;
4116       Index = 0;
4117       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4118         while (p < (smb_buf(inbuf) + bcc))
4119           { 
4120             if (strequal(p,supported_protocols[protocol].proto_name))
4121               choice = Index;
4122             Index++;
4123             p += strlen(p) + 2;
4124           }
4125       if(choice != -1)
4126         break;
4127     }
4128   
4129   SSVAL(outbuf,smb_vwv0,choice);
4130   if(choice != -1) {
4131     extern fstring remote_proto;
4132     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4133     reload_services(True);          
4134     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4135     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4136   }
4137   else {
4138     DEBUG(0,("No protocol supported !\n"));
4139   }
4140   SSVAL(outbuf,smb_vwv0,choice);
4141   
4142   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4143
4144   return(outsize);
4145 }
4146
4147
4148 /****************************************************************************
4149 close all open files for a connection
4150 ****************************************************************************/
4151 static void close_open_files(int cnum)
4152 {
4153   int i;
4154   for (i=0;i<MAX_OPEN_FILES;i++)
4155     if( Files[i].cnum == cnum && Files[i].open) {
4156       close_file(i,False);
4157     }
4158 }
4159
4160
4161
4162 /****************************************************************************
4163 close a cnum
4164 ****************************************************************************/
4165 void close_cnum(int cnum, uint16 vuid)
4166 {
4167   extern int Client;
4168   DirCacheFlush(SNUM(cnum));
4169
4170   unbecome_user();
4171
4172   if (!OPEN_CNUM(cnum))
4173     {
4174       DEBUG(0,("Can't close cnum %d\n",cnum));
4175       return;
4176     }
4177
4178   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4179                           timestring(),
4180                           remote_machine,client_addr(Client),
4181                           lp_servicename(SNUM(cnum))));
4182
4183   yield_connection(cnum,
4184                    lp_servicename(SNUM(cnum)),
4185                    lp_max_connections(SNUM(cnum)));
4186
4187   if (lp_status(SNUM(cnum)))
4188     yield_connection(cnum,"STATUS.",MAXSTATUS);
4189
4190   close_open_files(cnum);
4191   dptr_closecnum(cnum);
4192
4193   /* execute any "postexec = " line */
4194   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4195     {
4196       pstring cmd;
4197       strcpy(cmd,lp_postexec(SNUM(cnum)));
4198       standard_sub(cnum,cmd);
4199       smbrun(cmd,NULL,False);
4200       unbecome_user();
4201     }
4202
4203   unbecome_user();
4204   /* execute any "root postexec = " line */
4205   if (*lp_rootpostexec(SNUM(cnum)))
4206     {
4207       pstring cmd;
4208       strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4209       standard_sub(cnum,cmd);
4210       smbrun(cmd,NULL,False);
4211     }
4212
4213   Connections[cnum].open = False;
4214   num_connections_open--;
4215   if (Connections[cnum].ngroups && Connections[cnum].groups)
4216     {
4217       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4218         free(Connections[cnum].groups);
4219       free(Connections[cnum].igroups);
4220       Connections[cnum].groups = NULL;
4221       Connections[cnum].igroups = NULL;
4222       Connections[cnum].ngroups = 0;
4223     }
4224
4225   free_namearray(Connections[cnum].veto_list);
4226   free_namearray(Connections[cnum].hide_list);
4227   free_namearray(Connections[cnum].veto_oplock_list);
4228
4229   string_set(&Connections[cnum].user,"");
4230   string_set(&Connections[cnum].dirpath,"");
4231   string_set(&Connections[cnum].connectpath,"");
4232 }
4233
4234
4235
4236 #if DUMP_CORE
4237 /*******************************************************************
4238 prepare to dump a core file - carefully!
4239 ********************************************************************/
4240 static BOOL dump_core(void)
4241 {
4242   char *p;
4243   pstring dname;
4244   pstrcpy(dname,debugf);
4245   if ((p=strrchr(dname,'/'))) *p=0;
4246   strcat(dname,"/corefiles");
4247   mkdir(dname,0700);
4248   sys_chown(dname,getuid(),getgid());
4249   chmod(dname,0700);
4250   if (chdir(dname)) return(False);
4251   umask(~(0700));
4252
4253 #ifndef NO_GETRLIMIT
4254 #ifdef RLIMIT_CORE
4255   {
4256     struct rlimit rlp;
4257     getrlimit(RLIMIT_CORE, &rlp);
4258     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4259     setrlimit(RLIMIT_CORE, &rlp);
4260     getrlimit(RLIMIT_CORE, &rlp);
4261     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4262   }
4263 #endif
4264 #endif
4265
4266
4267   DEBUG(0,("Dumping core in %s\n",dname));
4268   return(True);
4269 }
4270 #endif
4271
4272 /****************************************************************************
4273 exit the server
4274 ****************************************************************************/
4275 void exit_server(char *reason)
4276 {
4277   static int firsttime=1;
4278   int i;
4279
4280   if (!firsttime) exit(0);
4281   firsttime = 0;
4282
4283   unbecome_user();
4284   DEBUG(2,("Closing connections\n"));
4285   for (i=0;i<MAX_CONNECTIONS;i++)
4286     if (Connections[i].open)
4287       close_cnum(i,(uint16)-1);
4288 #ifdef DFS_AUTH
4289   if (dcelogin_atmost_once)
4290     dfs_unlogin();
4291 #endif
4292   if (!reason) {   
4293     int oldlevel = DEBUGLEVEL;
4294     DEBUGLEVEL = 10;
4295     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4296     if (last_inbuf)
4297       show_msg(last_inbuf);
4298     DEBUGLEVEL = oldlevel;
4299     DEBUG(0,("===============================================================\n"));
4300 #if DUMP_CORE
4301     if (dump_core()) return;
4302 #endif
4303   }    
4304
4305   locking_end();
4306
4307   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4308   exit(0);
4309 }
4310
4311 /****************************************************************************
4312 do some standard substitutions in a string
4313 ****************************************************************************/
4314 void standard_sub(int cnum,char *str)
4315 {
4316   if (VALID_CNUM(cnum)) {
4317     char *p, *s, *home;
4318
4319     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4320       switch (*(p+1)) {
4321         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4322                      string_sub(p,"%H",home);
4323                    else
4324                      p += 2;
4325                    break;
4326         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4327         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4328         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4329         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4330         /* 
4331          * Patch from jkf@soton.ac.uk
4332          * Left the %N (NIS server name) in standard_sub_basic as it 
4333          * is a feature for logon servers, hence uses the username. 
4334          * The %p (NIS server path) code is here as it is used
4335          * instead of the default "path =" string in [homes] and so
4336          * needs the service name, not the username. 
4337          */
4338         case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4339         case '\0' : p++; break; /* don't run off the end of the string */
4340         default  : p+=2; break;
4341       }
4342     }
4343   }
4344   standard_sub_basic(str);
4345 }
4346
4347 /*
4348 These flags determine some of the permissions required to do an operation 
4349
4350 Note that I don't set NEED_WRITE on some write operations because they
4351 are used by some brain-dead clients when printing, and I don't want to
4352 force write permissions on print services.
4353 */
4354 #define AS_USER (1<<0)
4355 #define NEED_WRITE (1<<1)
4356 #define TIME_INIT (1<<2)
4357 #define CAN_IPC (1<<3)
4358 #define AS_GUEST (1<<5)
4359 #define QUEUE_IN_OPLOCK (1<<6)
4360
4361 /* 
4362    define a list of possible SMB messages and their corresponding
4363    functions. Any message that has a NULL function is unimplemented -
4364    please feel free to contribute implementations!
4365 */
4366 struct smb_message_struct
4367 {
4368   int code;
4369   char *name;
4370   int (*fn)();
4371   int flags;
4372 #if PROFILING
4373   unsigned long time;
4374 #endif
4375 }
4376  smb_messages[] = {
4377
4378     /* CORE PROTOCOL */
4379
4380    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4381    {SMBtcon,"SMBtcon",reply_tcon,0},
4382    {SMBtdis,"SMBtdis",reply_tdis,0},
4383    {SMBexit,"SMBexit",reply_exit,0},
4384    {SMBioctl,"SMBioctl",reply_ioctl,0},
4385    {SMBecho,"SMBecho",reply_echo,0},
4386    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4387    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4388    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4389    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4390    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4391    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4392    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4393    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4394
4395    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4396    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4397    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4398
4399    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4400    {SMBread,"SMBread",reply_read,AS_USER},
4401    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4402    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4403    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4404    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4405    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4406    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4407
4408    /* this is a Pathworks specific call, allowing the 
4409       changing of the root path */
4410    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4411
4412    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4413    {SMBflush,"SMBflush",reply_flush,AS_USER},
4414    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4415    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4416    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4417    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4418    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4419    {SMBlock,"SMBlock",reply_lock,AS_USER},
4420    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4421    
4422    /* CORE+ PROTOCOL FOLLOWS */
4423    
4424    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4425    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4426    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4427    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4428    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4429    
4430    /* LANMAN1.0 PROTOCOL FOLLOWS */
4431    
4432    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4433    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4434    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4435    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4436    {SMBwritec,"SMBwritec",NULL,AS_USER},
4437    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4438    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4439    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4440    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4441    {SMBioctls,"SMBioctls",NULL,AS_USER},
4442    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4443    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4444    
4445    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4446    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4447    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4448    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4449    
4450    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4451    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4452    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4453
4454    /* LANMAN2.0 PROTOCOL FOLLOWS */
4455    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4456    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4457    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4458    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4459
4460    /* messaging routines */
4461    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4462    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4463    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4464    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4465
4466    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4467    
4468    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4469    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4470    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4471    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4472  };
4473
4474 /****************************************************************************
4475 return a string containing the function name of a SMB command
4476 ****************************************************************************/
4477 char *smb_fn_name(int type)
4478 {
4479   static char *unknown_name = "SMBunknown";
4480   static int num_smb_messages = 
4481     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4482   int match;
4483
4484   for (match=0;match<num_smb_messages;match++)
4485     if (smb_messages[match].code == type)
4486       break;
4487
4488   if (match == num_smb_messages)
4489     return(unknown_name);
4490
4491   return(smb_messages[match].name);
4492 }
4493
4494
4495 /****************************************************************************
4496 do a switch on the message type, and return the response size
4497 ****************************************************************************/
4498 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4499 {
4500   static int pid= -1;
4501   int outsize = 0;
4502   static int num_smb_messages = 
4503     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4504   int match;
4505
4506 #if PROFILING
4507   struct timeval msg_start_time;
4508   struct timeval msg_end_time;
4509   static unsigned long total_time = 0;
4510
4511   GetTimeOfDay(&msg_start_time);
4512 #endif
4513
4514   if (pid == -1)
4515     pid = getpid();
4516
4517   errno = 0;
4518   last_message = type;
4519
4520   /* make sure this is an SMB packet */
4521   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4522     {
4523       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4524       return(-1);
4525     }
4526
4527   for (match=0;match<num_smb_messages;match++)
4528     if (smb_messages[match].code == type)
4529       break;
4530
4531   if (match == num_smb_messages)
4532     {
4533       DEBUG(0,("Unknown message type %d!\n",type));
4534       outsize = reply_unknown(inbuf,outbuf);
4535     }
4536   else
4537     {
4538       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4539
4540       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4541       {
4542         /* 
4543          * Queue this message as we are the process of an oplock break.
4544          */
4545
4546         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4547                timestring() ));
4548
4549         push_smb_message( inbuf, size);
4550         return -1;
4551       }          
4552
4553       if (smb_messages[match].fn)
4554         {
4555           int cnum = SVAL(inbuf,smb_tid);
4556           int flags = smb_messages[match].flags;
4557           /* In share mode security we must ignore the vuid. */
4558           uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4559           /* Ensure this value is replaced in the incoming packet. */
4560           SSVAL(inbuf,smb_uid,session_tag);
4561
4562           /* does this protocol need to be run as root? */
4563           if (!(flags & AS_USER))
4564             unbecome_user();
4565
4566           /* does this protocol need to be run as the connected user? */
4567           if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4568             if (flags & AS_GUEST) 
4569               flags &= ~AS_USER;
4570             else
4571               return(ERROR(ERRSRV,ERRinvnid));
4572           }
4573           /* this code is to work around a bug is MS client 3 without
4574              introducing a security hole - it needs to be able to do
4575              print queue checks as guest if it isn't logged in properly */
4576           if (flags & AS_USER)
4577             flags &= ~AS_GUEST;
4578
4579           /* does it need write permission? */
4580           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4581             return(ERROR(ERRSRV,ERRaccess));
4582
4583           /* ipc services are limited */
4584           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4585             return(ERROR(ERRSRV,ERRaccess));        
4586
4587           /* load service specific parameters */
4588           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4589             return(ERROR(ERRSRV,ERRaccess));
4590
4591           /* does this protocol need to be run as guest? */
4592           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4593             return(ERROR(ERRSRV,ERRaccess));
4594
4595           last_inbuf = inbuf;
4596
4597           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4598         }
4599       else
4600         {
4601           outsize = reply_unknown(inbuf,outbuf);
4602         }
4603     }
4604
4605 #if PROFILING
4606   GetTimeOfDay(&msg_end_time);
4607   if (!(smb_messages[match].flags & TIME_INIT))
4608     {
4609       smb_messages[match].time = 0;
4610       smb_messages[match].flags |= TIME_INIT;
4611     }
4612   {
4613     unsigned long this_time =     
4614       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4615         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4616     smb_messages[match].time += this_time;
4617     total_time += this_time;
4618   }
4619   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4620            smb_fn_name(type),smb_messages[match].time,
4621         (100.0*smb_messages[match].time) / total_time));
4622 #endif
4623
4624   return(outsize);
4625 }
4626
4627
4628 /****************************************************************************
4629   construct a chained reply and add it to the already made reply
4630   **************************************************************************/
4631 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4632 {
4633   static char *orig_inbuf;
4634   static char *orig_outbuf;
4635   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4636   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4637   char *inbuf2, *outbuf2;
4638   int outsize2;
4639   char inbuf_saved[smb_wct];
4640   char outbuf_saved[smb_wct];
4641   extern int chain_size;
4642   int wct = CVAL(outbuf,smb_wct);
4643   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4644
4645   /* maybe its not chained */
4646   if (smb_com2 == 0xFF) {
4647     CVAL(outbuf,smb_vwv0) = 0xFF;
4648     return outsize;
4649   }
4650
4651   if (chain_size == 0) {
4652     /* this is the first part of the chain */
4653     orig_inbuf = inbuf;
4654     orig_outbuf = outbuf;
4655   }
4656
4657   /* we need to tell the client where the next part of the reply will be */
4658   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4659   CVAL(outbuf,smb_vwv0) = smb_com2;
4660
4661   /* remember how much the caller added to the chain, only counting stuff
4662      after the parameter words */
4663   chain_size += outsize - smb_wct;
4664
4665   /* work out pointers into the original packets. The
4666      headers on these need to be filled in */
4667   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4668   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4669
4670   /* remember the original command type */
4671   smb_com1 = CVAL(orig_inbuf,smb_com);
4672
4673   /* save the data which will be overwritten by the new headers */
4674   memcpy(inbuf_saved,inbuf2,smb_wct);
4675   memcpy(outbuf_saved,outbuf2,smb_wct);
4676
4677   /* give the new packet the same header as the last part of the SMB */
4678   memmove(inbuf2,inbuf,smb_wct);
4679
4680   /* create the in buffer */
4681   CVAL(inbuf2,smb_com) = smb_com2;
4682
4683   /* create the out buffer */
4684   bzero(outbuf2,smb_size);
4685   set_message(outbuf2,0,0,True);
4686   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4687   
4688   memcpy(outbuf2+4,inbuf2+4,4);
4689   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4690   CVAL(outbuf2,smb_reh) = 0;
4691   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4692                                                                   means a reply */
4693   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4694   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4695   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4696   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4697   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4698   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4699
4700   DEBUG(3,("Chained message\n"));
4701   show_msg(inbuf2);
4702
4703   /* process the request */
4704   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4705                             bufsize-chain_size);
4706
4707   /* copy the new reply and request headers over the old ones, but
4708      preserve the smb_com field */
4709   memmove(orig_outbuf,outbuf2,smb_wct);
4710   CVAL(orig_outbuf,smb_com) = smb_com1;
4711
4712   /* restore the saved data, being careful not to overwrite any
4713    data from the reply header */
4714   memcpy(inbuf2,inbuf_saved,smb_wct);
4715   {
4716     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4717     if (ofs < 0) ofs = 0;
4718     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4719   }
4720
4721   return outsize2;
4722 }
4723
4724
4725
4726 /****************************************************************************
4727   construct a reply to the incoming packet
4728 ****************************************************************************/
4729 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4730 {
4731   int type = CVAL(inbuf,smb_com);
4732   int outsize = 0;
4733   int msg_type = CVAL(inbuf,0);
4734   extern int chain_size;
4735
4736   smb_last_time = time(NULL);
4737
4738   chain_size = 0;
4739   chain_fnum = -1;
4740   reset_chain_pnum();
4741
4742   bzero(outbuf,smb_size);
4743
4744   if (msg_type != 0)
4745     return(reply_special(inbuf,outbuf));  
4746
4747   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4748   set_message(outbuf,0,0,True);
4749   
4750   memcpy(outbuf+4,inbuf+4,4);
4751   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4752   CVAL(outbuf,smb_reh) = 0;
4753   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4754                                                              means a reply */
4755   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4756   SSVAL(outbuf,smb_err,SMB_SUCCESS);
4757   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4758   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4759   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4760   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4761
4762   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4763
4764   outsize += chain_size;
4765
4766   if(outsize > 4)
4767     smb_setlen(outbuf,outsize - 4);
4768   return(outsize);
4769 }
4770
4771 /****************************************************************************
4772   process commands from the client
4773 ****************************************************************************/
4774 static void process(void)
4775 {
4776   extern int Client;
4777
4778   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4779   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4780   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
4781     return;
4782
4783   InBuffer += SMB_ALIGNMENT;
4784   OutBuffer += SMB_ALIGNMENT;
4785
4786 #if PRIME_NMBD
4787   DEBUG(3,("priming nmbd\n"));
4788   {
4789     struct in_addr ip;
4790     ip = *interpret_addr2("localhost");
4791     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4792     *OutBuffer = 0;
4793     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4794   }
4795 #endif    
4796
4797   /* re-initialise the timezone */
4798   TimeInit();
4799
4800   while (True)
4801   {
4802     int deadtime = lp_deadtime()*60;
4803     int counter;
4804     int last_keepalive=0;
4805     int service_load_counter = 0;
4806     BOOL got_smb = False;
4807
4808     if (deadtime <= 0)
4809       deadtime = DEFAULT_SMBD_TIMEOUT;
4810
4811 #if USE_READ_PREDICTION
4812     if (lp_readprediction())
4813       do_read_prediction();
4814 #endif
4815
4816     errno = 0;      
4817
4818     for (counter=SMBD_SELECT_LOOP; 
4819           !receive_message_or_smb(Client,oplock_sock,
4820                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
4821           counter += SMBD_SELECT_LOOP)
4822     {
4823       int i;
4824       time_t t;
4825       BOOL allidle = True;
4826       extern int keepalive;
4827
4828       if (counter > 365 * 3600) /* big number of seconds. */
4829       {
4830         counter = 0;
4831         service_load_counter = 0;
4832       }
4833
4834       if (smb_read_error == READ_EOF) 
4835       {
4836         DEBUG(3,("end of file from client\n"));
4837         return;
4838       }
4839
4840       if (smb_read_error == READ_ERROR) 
4841       {
4842         DEBUG(3,("receive_smb error (%s) exiting\n",
4843                   strerror(errno)));
4844         return;
4845       }
4846
4847       t = time(NULL);
4848
4849       /* become root again if waiting */
4850       unbecome_user();
4851
4852       /* check for smb.conf reload */
4853       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4854       {
4855         service_load_counter = counter;
4856
4857         /* reload services, if files have changed. */
4858         reload_services(True);
4859       }
4860
4861       /* automatic timeout if all connections are closed */      
4862       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
4863       {
4864         DEBUG(2,("%s Closing idle connection\n",timestring()));
4865         return;
4866       }
4867
4868       if (keepalive && (counter-last_keepalive)>keepalive) 
4869       {
4870               struct cli_state *cli = server_client();
4871               if (!send_keepalive(Client)) { 
4872                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4873                       return;
4874               }     
4875               /* also send a keepalive to the password server if its still
4876                  connected */
4877               if (cli && cli->initialised)
4878                       send_keepalive(cli->fd);
4879               last_keepalive = counter;
4880       }
4881
4882       /* check for connection timeouts */
4883       for (i=0;i<MAX_CONNECTIONS;i++)
4884         if (Connections[i].open)
4885         {
4886           /* close dirptrs on connections that are idle */
4887           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4888             dptr_idlecnum(i);
4889
4890           if (Connections[i].num_files_open > 0 ||
4891                      (t-Connections[i].lastused)<deadtime)
4892             allidle = False;
4893         }
4894
4895       if (allidle && num_connections_open>0) 
4896       {
4897         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4898         return;
4899       }
4900     }
4901
4902     if(got_smb)
4903       process_smb(InBuffer, OutBuffer);
4904     else
4905       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4906   }
4907 }
4908
4909
4910 /****************************************************************************
4911   initialise connect, service and file structs
4912 ****************************************************************************/
4913 static void init_structs(void )
4914 {
4915   int i;
4916   get_myname(myhostname,NULL);
4917
4918   for (i=0;i<MAX_CONNECTIONS;i++)
4919     {
4920       Connections[i].open = False;
4921       Connections[i].num_files_open=0;
4922       Connections[i].lastused=0;
4923       Connections[i].used=False;
4924       string_init(&Connections[i].user,"");
4925       string_init(&Connections[i].dirpath,"");
4926       string_init(&Connections[i].connectpath,"");
4927       string_init(&Connections[i].origpath,"");
4928     }
4929
4930   for (i=0;i<MAX_OPEN_FILES;i++)
4931     {
4932       Files[i].open = False;
4933       string_init(&Files[i].name,"");
4934
4935     }
4936
4937   for (i=0;i<MAX_OPEN_FILES;i++)
4938     {
4939       file_fd_struct *fd_ptr = &FileFd[i];
4940       fd_ptr->ref_count = 0;
4941       fd_ptr->dev = (int32)-1;
4942       fd_ptr->inode = (int32)-1;
4943       fd_ptr->fd = -1;
4944       fd_ptr->fd_readonly = -1;
4945       fd_ptr->fd_writeonly = -1;
4946       fd_ptr->real_open_flags = -1;
4947     }
4948
4949   /* for RPC pipes */
4950   init_rpc_pipe_hnd();
4951
4952   /* for LSA handles */
4953   init_lsa_policy_hnd();
4954
4955   init_dptrs();
4956 }
4957
4958 /****************************************************************************
4959 usage on the program
4960 ****************************************************************************/
4961 static void usage(char *pname)
4962 {
4963   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4964
4965   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4966   printf("Version %s\n",VERSION);
4967   printf("\t-D                    become a daemon\n");
4968   printf("\t-p port               listen on the specified port\n");
4969   printf("\t-d debuglevel         set the debuglevel\n");
4970   printf("\t-l log basename.      Basename for log/debug files\n");
4971   printf("\t-s services file.     Filename of services file\n");
4972   printf("\t-P                    passive only\n");
4973   printf("\t-a                    overwrite log file, don't append\n");
4974   printf("\n");
4975 }
4976
4977
4978 /****************************************************************************
4979   main program
4980 ****************************************************************************/
4981  int main(int argc,char *argv[])
4982 {
4983   extern BOOL append_log;
4984   /* shall I run as a daemon */
4985   BOOL is_daemon = False;
4986   int port = SMB_PORT;
4987   int opt;
4988   extern char *optarg;
4989
4990 #ifdef NEED_AUTH_PARAMETERS
4991   set_auth_parameters(argc,argv);
4992 #endif
4993
4994 #ifdef SecureWare
4995   setluid(0);
4996 #endif
4997
4998   append_log = True;
4999
5000   TimeInit();
5001
5002   strcpy(debugf,SMBLOGFILE);  
5003
5004   strcpy(remote_machine, "smb");
5005
5006   setup_logging(argv[0],False);
5007
5008   charset_initialise();
5009
5010   /* make absolutely sure we run as root - to handle cases where people
5011      are crazy enough to have it setuid */
5012 #ifdef USE_SETRES
5013   setresuid(0,0,0);
5014 #else
5015   setuid(0);
5016   seteuid(0);
5017   setuid(0);
5018   seteuid(0);
5019 #endif
5020
5021   fault_setup(exit_server);
5022   signal(SIGTERM , SIGNAL_CAST dflt_sig);
5023
5024   /* we want total control over the permissions on created files,
5025      so set our umask to 0 */
5026   umask(0);
5027
5028   GetWd(OriginalDir);
5029
5030   init_uid();
5031
5032   /* this is for people who can't start the program correctly */
5033   while (argc > 1 && (*argv[1] != '-'))
5034     {
5035       argv++;
5036       argc--;
5037     }
5038
5039   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5040     switch (opt)
5041       {
5042       case 'O':
5043         strcpy(user_socket_options,optarg);
5044         break;
5045       case 'i':
5046         strcpy(scope,optarg);
5047         break;
5048       case 'P':
5049         {
5050           extern BOOL passive;
5051           passive = True;
5052         }
5053         break;  
5054       case 's':
5055         strcpy(servicesf,optarg);
5056         break;
5057       case 'l':
5058         strcpy(debugf,optarg);
5059         break;
5060       case 'a':
5061         {
5062           extern BOOL append_log;
5063           append_log = !append_log;
5064         }
5065         break;
5066       case 'D':
5067         is_daemon = True;
5068         break;
5069       case 'd':
5070         if (*optarg == 'A')
5071           DEBUGLEVEL = 10000;
5072         else
5073           DEBUGLEVEL = atoi(optarg);
5074         break;
5075       case 'p':
5076         port = atoi(optarg);
5077         break;
5078       case 'h':
5079         usage(argv[0]);
5080         exit(0);
5081         break;
5082       default:
5083         usage(argv[0]);
5084         exit(1);
5085       }
5086
5087   reopen_logs();
5088
5089   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5090   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5091
5092 #ifndef NO_GETRLIMIT
5093 #ifdef RLIMIT_NOFILE
5094   {
5095     struct rlimit rlp;
5096     getrlimit(RLIMIT_NOFILE, &rlp);
5097     /*
5098      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5099      * extra fd we need to read directories, as well as the log files
5100      * and standard handles etc.
5101      */
5102     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5103     setrlimit(RLIMIT_NOFILE, &rlp);
5104     getrlimit(RLIMIT_NOFILE, &rlp);
5105     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5106   }
5107 #endif
5108 #endif
5109
5110   
5111   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5112         getuid(),getgid(),geteuid(),getegid()));
5113
5114   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5115     {
5116       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5117       exit(1);
5118     }
5119
5120   init_structs();
5121
5122   if (!reload_services(False))
5123     return(-1); 
5124
5125   codepage_initialise(lp_client_code_page());
5126
5127   strcpy(myworkgroup, lp_workgroup());
5128
5129 #ifndef NO_SIGNAL_TEST
5130   signal(SIGHUP,SIGNAL_CAST sig_hup);
5131 #endif
5132
5133   /* Setup the signals that allow the debug log level
5134      to by dynamically changed. */
5135  
5136   /* If we are using the malloc debug code we can't use
5137      SIGUSR1 and SIGUSR2 to do debug level changes. */
5138
5139 #ifndef MEM_MAN
5140 #if defined(SIGUSR1)
5141   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5142 #endif /* SIGUSR1 */
5143    
5144 #if defined(SIGUSR2)
5145   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5146 #endif /* SIGUSR2 */
5147 #endif /* MEM_MAN */
5148
5149   DEBUG(3,("%s loaded services\n",timestring()));
5150
5151   if (!is_daemon && !is_a_socket(0))
5152     {
5153       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5154       is_daemon = True;
5155     }
5156
5157   if (is_daemon)
5158     {
5159       DEBUG(3,("%s becoming a daemon\n",timestring()));
5160       become_daemon();
5161     }
5162
5163   if (!directory_exist(lp_lockdir(), NULL)) {
5164           mkdir(lp_lockdir(), 0755);
5165   }
5166
5167   if (is_daemon) {
5168           pidfile_create("smbd");
5169   }
5170
5171   if (!open_sockets(is_daemon,port))
5172     exit(1);
5173
5174   if (!locking_init(0))
5175     exit(1);
5176
5177   /* possibly reload the services file. */
5178   reload_services(True);
5179
5180   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5181
5182   if (*lp_rootdir())
5183     {
5184       if (sys_chroot(lp_rootdir()) == 0)
5185         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5186     }
5187
5188   /* Setup the oplock IPC socket. */
5189   if(!open_oplock_ipc())
5190     exit(1);
5191
5192   process();
5193   close_sockets();
5194
5195   exit_server("normal exit");
5196   return(0);
5197 }
5198
5199