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