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