This is *not* a big change (although it looks like one).
[kai/samba.git] / source3 / smbd / server.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Main SMB server routines
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "trans2.h"
24
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
29
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
33
34 int am_parent = 1;
35 int atexit_set = 0;
36
37 /* the last message the was processed */
38 int last_message = -1;
39
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
42
43 extern pstring scope;
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 time_t smb_last_time=(time_t)0;
52
53 extern int smb_read_error;
54
55 extern pstring user_socket_options;
56
57 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, BOOL rename_op)
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           /*
1625            * It appears that the NT redirector may have a bug, in that
1626            * it tries to do an SMBmv on a file that it has open with a
1627            * batch oplock, and then fails to respond to the oplock break
1628            * request. This only seems to occur when the client is doing an
1629            * SMBmv to the smbd it is using - thus we try and detect this
1630            * condition by checking if the file being moved is open and oplocked by
1631            * this smbd process, and then not sending the oplock break in this
1632            * special case. If the file was open with a deny mode that 
1633            * prevents the move the SMBmv will fail anyway with a share
1634            * violation error. JRA.
1635            */
1636           if(rename_op && (share_entry->pid == pid))
1637           {
1638             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1639 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1640 #if 0
1641             /* 
1642              * This next line is a test that allows the deny-mode
1643              * processing to be skipped. JRA.
1644              */ 
1645             continue;
1646 #endif
1647           }
1648           else
1649           {
1650             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1651 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1652
1653             /* Oplock break.... */
1654             unlock_share_entry(cnum, dev, inode, token);
1655             if(request_oplock_break(share_entry, dev, inode) == False)
1656             {
1657               free((char *)old_shares);
1658               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1659 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1660               return False;
1661             }
1662             lock_share_entry(cnum, dev, inode, &token);
1663             broke_oplock = True;
1664             break;
1665           }
1666         }
1667
1668         /* someone else has a share lock on it, check to see 
1669            if we can too */
1670         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1671           goto free_and_exit;
1672
1673       } /* end for */
1674
1675       if(broke_oplock)
1676       {
1677         free((char *)old_shares);
1678         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1679       }
1680     } while(broke_oplock);
1681   }
1682
1683   /* XXXX exactly what share mode combinations should be allowed for
1684      deleting/renaming? */
1685   /* If we got here then either there were no share modes or
1686      all share modes were DENY_DOS and the pid == getpid() */
1687   ret = True;
1688
1689 free_and_exit:
1690
1691   unlock_share_entry(cnum, dev, inode, token);
1692   if(old_shares != NULL)
1693     free((char *)old_shares);
1694   return(ret);
1695 }
1696
1697 /****************************************************************************
1698   C. Hoch 11/22/95
1699   Helper for open_file_shared. 
1700   Truncate a file after checking locking; close file if locked.
1701   **************************************************************************/
1702 static void truncate_unless_locked(int fnum, int cnum, int token, 
1703                                    BOOL *share_locked)
1704 {
1705   if (Files[fnum].can_write){
1706     if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1707       /* If share modes are in force for this connection we
1708          have the share entry locked. Unlock it before closing. */
1709       if (*share_locked && lp_share_modes(SNUM(cnum)))
1710         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
1711                             Files[fnum].fd_ptr->inode, token);
1712       close_file(fnum,False);   
1713       /* Share mode no longer locked. */
1714       *share_locked = False;
1715       errno = EACCES;
1716       unix_ERR_class = ERRDOS;
1717       unix_ERR_code = ERRlock;
1718     }
1719     else
1720       ftruncate(Files[fnum].fd_ptr->fd,0); 
1721   }
1722 }
1723
1724 /****************************************************************************
1725 check if we can open a file with a share mode
1726 ****************************************************************************/
1727 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1728                       BOOL fcbopen, int *flags)
1729 {
1730   int old_open_mode = share->share_mode &0xF;
1731   int old_deny_mode = (share->share_mode >>4)&7;
1732
1733   if (old_deny_mode > 4 || old_open_mode > 2)
1734   {
1735     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1736                deny_mode,old_deny_mode,old_open_mode,fname));
1737     return False;
1738   }
1739
1740   {
1741     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1742                                 share->pid,fname);
1743
1744     if ((access_allowed == AFAIL) ||
1745         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1746         (access_allowed == AREAD && *flags == O_WRONLY) ||
1747         (access_allowed == AWRITE && *flags == O_RDONLY))
1748     {
1749       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1750                 deny_mode,old_deny_mode,old_open_mode,
1751                 share->pid,fname, fcbopen, *flags, access_allowed));
1752       return False;
1753     }
1754
1755     if (access_allowed == AREAD)
1756       *flags = O_RDONLY;
1757
1758     if (access_allowed == AWRITE)
1759       *flags = O_WRONLY;
1760
1761   }
1762   return True;
1763 }
1764
1765 /****************************************************************************
1766 open a file with a share mode
1767 ****************************************************************************/
1768 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1769                       int mode,int oplock_request, int *Access,int *action)
1770 {
1771   files_struct *fs_p = &Files[fnum];
1772   int flags=0;
1773   int flags2=0;
1774   int deny_mode = (share_mode>>4)&7;
1775   struct stat sbuf;
1776   BOOL file_existed = file_exist(fname,&sbuf);
1777   BOOL share_locked = False;
1778   BOOL fcbopen = False;
1779   int token;
1780   uint32 dev = 0;
1781   uint32 inode = 0;
1782   int num_share_modes = 0;
1783
1784   fs_p->open = False;
1785   fs_p->fd_ptr = 0;
1786
1787   /* this is for OS/2 EAs - try and say we don't support them */
1788   if (strstr(fname,".+,;=[].")) 
1789   {
1790     unix_ERR_class = ERRDOS;
1791     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1792 #ifdef OS2_WPS_FIX
1793     unix_ERR_code = ERRcannotopen;
1794 #else /* OS2_WPS_FIX */
1795     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1796 #endif /* OS2_WPS_FIX */
1797
1798     return;
1799   }
1800
1801   if ((ofun & 0x3) == 0 && file_existed)  
1802   {
1803     errno = EEXIST;
1804     return;
1805   }
1806       
1807   if (ofun & 0x10)
1808     flags2 |= O_CREAT;
1809   if ((ofun & 0x3) == 2)
1810     flags2 |= O_TRUNC;
1811
1812   /* note that we ignore the append flag as 
1813      append does not mean the same thing under dos and unix */
1814
1815   switch (share_mode&0xF)
1816   {
1817     case 1: 
1818       flags = O_WRONLY; 
1819       break;
1820     case 0xF: 
1821       fcbopen = True;
1822       flags = O_RDWR; 
1823       break;
1824     case 2: 
1825       flags = O_RDWR; 
1826       break;
1827     default:
1828       flags = O_RDONLY;
1829       break;
1830   }
1831   
1832   if (flags != O_RDONLY && file_existed && 
1833       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
1834   {
1835     if (!fcbopen) 
1836     {
1837       errno = EACCES;
1838       return;
1839     }
1840     flags = O_RDONLY;
1841   }
1842
1843   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
1844   {
1845     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1846     errno = EINVAL;
1847     return;
1848   }
1849
1850   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1851
1852   if (lp_share_modes(SNUM(cnum))) 
1853   {
1854     int i;
1855     share_mode_entry *old_shares = 0;
1856
1857     if (file_existed)
1858     {
1859       dev = (uint32)sbuf.st_dev;
1860       inode = (uint32)sbuf.st_ino;
1861       lock_share_entry(cnum, dev, inode, &token);
1862       share_locked = True;
1863       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1864     }
1865
1866     /*
1867      * Check if the share modes will give us access.
1868      */
1869
1870     if(share_locked && (num_share_modes != 0))
1871     {
1872       BOOL broke_oplock;
1873
1874       do
1875       {
1876
1877         broke_oplock = False;
1878         for(i = 0; i < num_share_modes; i++)
1879         {
1880           share_mode_entry *share_entry = &old_shares[i];
1881
1882           /* 
1883            * By observation of NetBench, oplocks are broken *before* share
1884            * modes are checked. This allows a file to be closed by the client
1885            * if the share mode would deny access and the client has an oplock. 
1886            * Check if someone has an oplock on this file. If so we must break 
1887            * it before continuing. 
1888            */
1889           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1890           {
1891
1892             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1893 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1894
1895             /* Oplock break.... */
1896             unlock_share_entry(cnum, dev, inode, token);
1897             if(request_oplock_break(share_entry, dev, inode) == False)
1898             {
1899               free((char *)old_shares);
1900               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1901 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1902               errno = EACCES;
1903               unix_ERR_class = ERRDOS;
1904               unix_ERR_code = ERRbadshare;
1905               return;
1906             }
1907             lock_share_entry(cnum, dev, inode, &token);
1908             broke_oplock = True;
1909             break;
1910           }
1911
1912           /* someone else has a share lock on it, check to see 
1913              if we can too */
1914           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1915           {
1916             free((char *)old_shares);
1917             unlock_share_entry(cnum, dev, inode, token);
1918             errno = EACCES;
1919             unix_ERR_class = ERRDOS;
1920             unix_ERR_code = ERRbadshare;
1921             return;
1922           }
1923
1924         } /* end for */
1925
1926         if(broke_oplock)
1927         {
1928           free((char *)old_shares);
1929           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1930         }
1931       } while(broke_oplock);
1932     }
1933
1934     if(old_shares != 0)
1935       free((char *)old_shares);
1936   }
1937
1938   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1939            flags,flags2,mode));
1940
1941   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1942   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
1943   {
1944     flags = O_RDONLY;
1945     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1946   }
1947
1948   if (fs_p->open) 
1949   {
1950     int open_mode=0;
1951
1952     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1953     {
1954       /* We created the file - thus we must now lock the share entry before creating it. */
1955       dev = fs_p->fd_ptr->dev;
1956       inode = fs_p->fd_ptr->inode;
1957       lock_share_entry(cnum, dev, inode, &token);
1958       share_locked = True;
1959     }
1960
1961     switch (flags) 
1962     {
1963       case O_RDONLY:
1964         open_mode = 0;
1965         break;
1966       case O_RDWR:
1967         open_mode = 2;
1968         break;
1969       case O_WRONLY:
1970         open_mode = 1;
1971         break;
1972     }
1973
1974     fs_p->share_mode = (deny_mode<<4) | open_mode;
1975
1976     if (Access)
1977       (*Access) = open_mode;
1978
1979     if (action) 
1980     {
1981       if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1982       if (!file_existed) *action = 2;
1983       if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1984     }
1985     /* We must create the share mode entry before truncate as
1986        truncate can fail due to locking and have to close the
1987        file (which expects the share_mode_entry to be there).
1988      */
1989     if (lp_share_modes(SNUM(cnum)))
1990     {
1991       uint16 port = 0;
1992       /* JRA. Currently this only services Exlcusive and batch
1993          oplocks (no other opens on this file). This needs to
1994          be extended to level II oplocks (multiple reader
1995          oplocks). */
1996
1997       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
1998               !IS_VETO_OPLOCK_PATH(cnum,fname))
1999       {
2000         fs_p->granted_oplock = True;
2001         fs_p->sent_oplock_break = False;
2002         global_oplocks_open++;
2003         port = oplock_port;
2004
2005         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2006 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2007
2008       }
2009       else
2010       {
2011         port = 0;
2012         oplock_request = 0;
2013       }
2014       set_share_mode(token, fnum, port, oplock_request);
2015     }
2016
2017     if ((flags2&O_TRUNC) && file_existed)
2018       truncate_unless_locked(fnum,cnum,token,&share_locked);
2019   }
2020
2021   if (share_locked && lp_share_modes(SNUM(cnum)))
2022     unlock_share_entry( cnum, dev, inode, token);
2023 }
2024
2025 /****************************************************************************
2026 seek a file. Try to avoid the seek if possible
2027 ****************************************************************************/
2028 int seek_file(int fnum,uint32 pos)
2029 {
2030   uint32 offset = 0;
2031   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2032     offset = 3;
2033
2034   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
2035                                   - offset);
2036   return(Files[fnum].pos);
2037 }
2038
2039 /****************************************************************************
2040 read from a file
2041 ****************************************************************************/
2042 int read_file(int fnum,char *data,uint32 pos,int n)
2043 {
2044   int ret=0,readret;
2045
2046 #if USE_READ_PREDICTION
2047   if (!Files[fnum].can_write)
2048     {
2049       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2050
2051       data += ret;
2052       n -= ret;
2053       pos += ret;
2054     }
2055 #endif
2056
2057 #if USE_MMAP
2058   if (Files[fnum].mmap_ptr)
2059     {
2060       int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
2061       if (num > 0)
2062         {
2063           memcpy(data,Files[fnum].mmap_ptr+pos,num);
2064           data += num;
2065           pos += num;
2066           n -= num;
2067           ret += num;
2068         }
2069     }
2070 #endif
2071
2072   if (n <= 0)
2073     return(ret);
2074
2075   if (seek_file(fnum,pos) != pos)
2076     {
2077       DEBUG(3,("Failed to seek to %d\n",pos));
2078       return(ret);
2079     }
2080   
2081   if (n > 0) {
2082     readret = read(Files[fnum].fd_ptr->fd,data,n);
2083     if (readret > 0) ret += readret;
2084   }
2085
2086   return(ret);
2087 }
2088
2089
2090 /****************************************************************************
2091 write to a file
2092 ****************************************************************************/
2093 int write_file(int fnum,char *data,int n)
2094 {
2095   if (!Files[fnum].can_write) {
2096     errno = EPERM;
2097     return(0);
2098   }
2099
2100   if (!Files[fnum].modified) {
2101     struct stat st;
2102     Files[fnum].modified = True;
2103     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2104       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2105       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {  
2106         dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2107       }
2108     }  
2109   }
2110
2111   return(write_data(Files[fnum].fd_ptr->fd,data,n));
2112 }
2113
2114
2115 /****************************************************************************
2116 load parameters specific to a connection/service
2117 ****************************************************************************/
2118 BOOL become_service(int cnum,BOOL do_chdir)
2119 {
2120   extern char magic_char;
2121   static int last_cnum = -1;
2122   int snum;
2123
2124   if (!OPEN_CNUM(cnum))
2125     {
2126       last_cnum = -1;
2127       return(False);
2128     }
2129
2130   Connections[cnum].lastused = smb_last_time;
2131
2132   snum = SNUM(cnum);
2133   
2134   if (do_chdir &&
2135       ChDir(Connections[cnum].connectpath) != 0 &&
2136       ChDir(Connections[cnum].origpath) != 0)
2137     {
2138       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2139             Connections[cnum].connectpath,cnum));     
2140       return(False);
2141     }
2142
2143   if (cnum == last_cnum)
2144     return(True);
2145
2146   last_cnum = cnum;
2147
2148   case_default = lp_defaultcase(snum);
2149   case_preserve = lp_preservecase(snum);
2150   short_case_preserve = lp_shortpreservecase(snum);
2151   case_mangle = lp_casemangle(snum);
2152   case_sensitive = lp_casesensitive(snum);
2153   magic_char = lp_magicchar(snum);
2154   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2155   return(True);
2156 }
2157
2158
2159 /****************************************************************************
2160   find a service entry
2161 ****************************************************************************/
2162 int find_service(char *service)
2163 {
2164    int iService;
2165
2166    string_sub(service,"\\","/");
2167
2168    iService = lp_servicenumber(service);
2169
2170    /* now handle the special case of a home directory */
2171    if (iService < 0)
2172    {
2173       char *phome_dir = get_home_dir(service);
2174       DEBUG(3,("checking for home directory %s gave %s\n",service,
2175             phome_dir?phome_dir:"(NULL)"));
2176       if (phome_dir)
2177       {   
2178          int iHomeService;
2179          if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2180          {
2181             lp_add_home(service,iHomeService,phome_dir);
2182             iService = lp_servicenumber(service);
2183          }
2184       }
2185    }
2186
2187    /* If we still don't have a service, attempt to add it as a printer. */
2188    if (iService < 0)
2189    {
2190       int iPrinterService;
2191
2192       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2193       {
2194          char *pszTemp;
2195
2196          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2197          pszTemp = PRINTCAP;
2198          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2199          {
2200             DEBUG(3,("%s is a valid printer name\n", service));
2201             DEBUG(3,("adding %s as a printer service\n", service));
2202             lp_add_printer(service,iPrinterService);
2203             iService = lp_servicenumber(service);
2204             if (iService < 0)
2205                DEBUG(0,("failed to add %s as a printer service!\n", service));
2206          }
2207          else
2208             DEBUG(3,("%s is not a valid printer name\n", service));
2209       }
2210    }
2211
2212    /* just possibly it's a default service? */
2213    if (iService < 0) 
2214      {
2215        char *defservice = lp_defaultservice();
2216        if (defservice && *defservice && !strequal(defservice,service)) {
2217          iService = find_service(defservice);
2218          if (iService >= 0) {
2219            string_sub(service,"_","/");
2220            iService = lp_add_service(service,iService);
2221          }
2222        }
2223      }
2224
2225    if (iService >= 0)
2226       if (!VALID_SNUM(iService))
2227       {
2228          DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2229          iService = -1;
2230       }
2231
2232    if (iService < 0)
2233       DEBUG(3,("find_service() failed to find service %s\n", service));
2234
2235    return (iService);
2236 }
2237
2238
2239 /****************************************************************************
2240   create an error packet from a cached error.
2241 ****************************************************************************/
2242 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2243 {
2244   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2245
2246   int32 eclass = wbmpx->wr_errclass;
2247   int32 err = wbmpx->wr_error;
2248
2249   /* We can now delete the auxiliary struct */
2250   free((char *)wbmpx);
2251   Files[fnum].wbmpx_ptr = NULL;
2252   return error_packet(inbuf,outbuf,eclass,err,line);
2253 }
2254
2255
2256 struct
2257 {
2258   int unixerror;
2259   int smbclass;
2260   int smbcode;
2261 } unix_smb_errmap[] =
2262 {
2263   {EPERM,ERRDOS,ERRnoaccess},
2264   {EACCES,ERRDOS,ERRnoaccess},
2265   {ENOENT,ERRDOS,ERRbadfile},
2266   {ENOTDIR,ERRDOS,ERRbadpath},
2267   {EIO,ERRHRD,ERRgeneral},
2268   {EBADF,ERRSRV,ERRsrverror},
2269   {EINVAL,ERRSRV,ERRsrverror},
2270   {EEXIST,ERRDOS,ERRfilexists},
2271   {ENFILE,ERRDOS,ERRnofids},
2272   {EMFILE,ERRDOS,ERRnofids},
2273   {ENOSPC,ERRHRD,ERRdiskfull},
2274 #ifdef EDQUOT
2275   {EDQUOT,ERRHRD,ERRdiskfull},
2276 #endif
2277 #ifdef ENOTEMPTY
2278   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2279 #endif
2280 #ifdef EXDEV
2281   {EXDEV,ERRDOS,ERRdiffdevice},
2282 #endif
2283   {EROFS,ERRHRD,ERRnowrite},
2284   {0,0,0}
2285 };
2286
2287 /****************************************************************************
2288   create an error packet from errno
2289 ****************************************************************************/
2290 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2291 {
2292   int eclass=def_class;
2293   int ecode=def_code;
2294   int i=0;
2295
2296   if (unix_ERR_class != SUCCESS)
2297     {
2298       eclass = unix_ERR_class;
2299       ecode = unix_ERR_code;
2300       unix_ERR_class = SUCCESS;
2301       unix_ERR_code = 0;
2302     }
2303   else
2304     {
2305       while (unix_smb_errmap[i].smbclass != 0)
2306       {
2307             if (unix_smb_errmap[i].unixerror == errno)
2308             {
2309               eclass = unix_smb_errmap[i].smbclass;
2310               ecode = unix_smb_errmap[i].smbcode;
2311               break;
2312             }
2313           i++;
2314       }
2315     }
2316
2317   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2318 }
2319
2320
2321 /****************************************************************************
2322   create an error packet. Normally called using the ERROR() macro
2323 ****************************************************************************/
2324 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2325 {
2326   int outsize = set_message(outbuf,0,0,True);
2327   int cmd;
2328   cmd = CVAL(inbuf,smb_com);
2329   
2330   CVAL(outbuf,smb_rcls) = error_class;
2331   SSVAL(outbuf,smb_err,error_code);  
2332   
2333   DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2334            timestring(),
2335            line,
2336            (int)CVAL(inbuf,smb_com),
2337            smb_fn_name(CVAL(inbuf,smb_com)),
2338            error_class,
2339            error_code));
2340
2341   if (errno != 0)
2342     DEBUG(3,("error string = %s\n",strerror(errno)));
2343   
2344   return(outsize);
2345 }
2346
2347
2348 #ifndef SIGCLD_IGNORE
2349 /****************************************************************************
2350 this prevents zombie child processes
2351 ****************************************************************************/
2352 static int sig_cld()
2353 {
2354   static int depth = 0;
2355   if (depth != 0)
2356     {
2357       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2358       depth=0;
2359       return(0);
2360     }
2361   depth++;
2362
2363   BlockSignals(True,SIGCLD);
2364   DEBUG(5,("got SIGCLD\n"));
2365
2366 #ifdef USE_WAITPID
2367   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2368 #endif
2369
2370   /* Stop zombies */
2371   /* Stevens, Adv. Unix Prog. says that on system V you must call
2372      wait before reinstalling the signal handler, because the kernel
2373      calls the handler from within the signal-call when there is a
2374      child that has exited. This would lead to an infinite recursion
2375      if done vice versa. */
2376         
2377 #ifndef DONT_REINSTALL_SIG
2378 #ifdef SIGCLD_IGNORE
2379   signal(SIGCLD, SIG_IGN);  
2380 #else
2381   signal(SIGCLD, SIGNAL_CAST sig_cld);
2382 #endif
2383 #endif
2384
2385 #ifndef USE_WAITPID
2386   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2387 #endif
2388   depth--;
2389   BlockSignals(False,SIGCLD);
2390   return 0;
2391 }
2392 #endif
2393
2394 /****************************************************************************
2395   this is called when the client exits abruptly
2396   **************************************************************************/
2397 static int sig_pipe()
2398 {
2399         struct cli_state *cli;
2400         BlockSignals(True,SIGPIPE);
2401
2402         if ((cli = server_client()) && cli->initialised) {
2403                 DEBUG(3,("lost connection to password server\n"));
2404                 cli_shutdown(cli);
2405 #ifndef DONT_REINSTALL_SIG
2406                 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2407 #endif
2408                 BlockSignals(False,SIGPIPE);
2409                 return 0;
2410         }
2411
2412         exit_server("Got sigpipe\n");
2413         return(0);
2414 }
2415
2416 /****************************************************************************
2417   open the socket communication
2418 ****************************************************************************/
2419 static BOOL open_sockets(BOOL is_daemon,int port)
2420 {
2421   extern int Client;
2422
2423   if (is_daemon)
2424   {
2425     int num_interfaces = iface_count();
2426     int fd_listenset[FD_SETSIZE];
2427     fd_set listen_set;
2428     int s;
2429     int i;
2430
2431     /* Stop zombies */
2432 #ifdef SIGCLD_IGNORE
2433     signal(SIGCLD, SIG_IGN);
2434 #else
2435     signal(SIGCLD, SIGNAL_CAST sig_cld);
2436 #endif
2437
2438     if(atexit_set == 0)
2439       atexit(killkids);
2440
2441     FD_ZERO(&listen_set);
2442
2443     if(lp_interfaces() && lp_bind_interfaces_only())
2444     {
2445        /* We have been given an interfaces line, and been 
2446           told to only bind to those interfaces. Create a
2447           socket per interface and bind to only these.
2448         */
2449
2450       if(num_interfaces > FD_SETSIZE)
2451       {
2452         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2453 max can be %d\n", num_interfaces, FD_SETSIZE));
2454         return False;
2455       }
2456
2457       /* Now open a listen socket for each of the interfaces. */
2458       for(i = 0; i < num_interfaces; i++)
2459       {
2460         struct in_addr *ifip = iface_n_ip(i);
2461
2462         if(ifip == NULL)
2463         {
2464           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2465           continue;
2466         }
2467         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2468         if(s == -1)
2469           return False;
2470         /* ready to listen */
2471         if (listen(s, 5) == -1) 
2472         {
2473           DEBUG(0,("listen: %s\n",strerror(errno)));
2474           close(s);
2475           return False;
2476         }
2477         FD_SET(s,&listen_set);
2478       }
2479     }
2480     else
2481     {
2482       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2483       num_interfaces = 1;
2484
2485       /* open an incoming socket */
2486       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2487       if (s == -1)
2488         return(False);
2489
2490       /* ready to listen */
2491       if (listen(s, 5) == -1) 
2492       {
2493         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2494         close(s);
2495         return False;
2496       }
2497
2498       fd_listenset[0] = s;
2499       FD_SET(s,&listen_set);
2500     }      
2501
2502     /* now accept incoming connections - forking a new process
2503        for each incoming connection */
2504     DEBUG(2,("waiting for a connection\n"));
2505     while (1)
2506     {
2507       fd_set lfds;
2508       int num;
2509
2510       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2511
2512       num = sys_select(&lfds,NULL);
2513
2514       if (num == -1 && errno == EINTR)
2515         continue;
2516
2517       /* Find the sockets that are read-ready - accept on these. */
2518       for( ; num > 0; num--)
2519       {
2520         struct sockaddr addr;
2521         int in_addrlen = sizeof(addr);
2522
2523         s = -1;
2524         for(i = 0; i < num_interfaces; i++)
2525         {
2526           if(FD_ISSET(fd_listenset[i],&lfds))
2527           {
2528             s = fd_listenset[i];
2529             /* Clear this so we don't look at it again. */
2530             FD_CLR(fd_listenset[i],&lfds);
2531             break;
2532           }
2533         }
2534
2535         Client = accept(s,&addr,&in_addrlen);
2536
2537         if (Client == -1 && errno == EINTR)
2538           continue;
2539
2540         if (Client == -1)
2541         {
2542           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2543           continue;
2544         }
2545
2546 #ifdef NO_FORK_DEBUG
2547 #ifndef NO_SIGNAL_TEST
2548         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2549         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2550 #endif /* NO_SIGNAL_TEST */
2551         return True;
2552 #else /* NO_FORK_DEBUG */
2553         if (Client != -1 && fork()==0)
2554         {
2555           /* Child code ... */
2556
2557 #ifndef NO_SIGNAL_TEST
2558           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2559           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2560 #endif /* NO_SIGNAL_TEST */
2561           /* close the listening socket(s) */
2562           for(i = 0; i < num_interfaces; i++)
2563             close(fd_listenset[i]);
2564
2565           /* close our standard file descriptors */
2566           close_low_fds();
2567           am_parent = 0;
2568   
2569           set_socket_options(Client,"SO_KEEPALIVE");
2570           set_socket_options(Client,user_socket_options);
2571
2572           /* Reset global variables in util.c so that
2573              client substitutions will be done correctly
2574              in the process.
2575            */
2576           reset_globals_after_fork();
2577           return True; 
2578         }
2579         close(Client); /* The parent doesn't need this socket */
2580 #endif /* NO_FORK_DEBUG */
2581       } /* end for num */
2582     } /* end while 1 */
2583   } /* end if is_daemon */
2584   else
2585   {
2586     /* Started from inetd. fd 0 is the socket. */
2587     /* We will abort gracefully when the client or remote system 
2588        goes away */
2589 #ifndef NO_SIGNAL_TEST
2590     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2591 #endif
2592     Client = dup(0);
2593
2594     /* close our standard file descriptors */
2595     close_low_fds();
2596
2597     set_socket_options(Client,"SO_KEEPALIVE");
2598     set_socket_options(Client,user_socket_options);
2599   }
2600
2601   return True;
2602 }
2603
2604 /****************************************************************************
2605   process an smb from the client - split out from the process() code so
2606   it can be used by the oplock break code.
2607 ****************************************************************************/
2608
2609 static void process_smb(char *inbuf, char *outbuf)
2610 {
2611   extern int Client;
2612   static int trans_num;
2613   int msg_type = CVAL(inbuf,0);
2614   int32 len = smb_len(inbuf);
2615   int nread = len + 4;
2616
2617   if (trans_num == 0) {
2618           /* on the first packet, check the global hosts allow/ hosts
2619              deny parameters before doing any parsing of the packet
2620              passed to us by the client.  This prevents attacks on our
2621              parsing code from hosts not in the hosts allow list */
2622           if (!check_access(-1)) {
2623                   /* send a negative session response "not listining on calling
2624                    name" */
2625                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2626                   DEBUG(1,("%s Connection denied from %s\n",
2627                            timestring(),client_addr()));
2628                   send_smb(Client,(char *)buf);
2629                   exit_server("connection denied");
2630           }
2631   }
2632
2633   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2634   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2635
2636 #ifdef WITH_VTP
2637   if(trans_num == 1 && VT_Check(inbuf)) 
2638   {
2639     VT_Process();
2640     return;
2641   }
2642 #endif
2643
2644   if (msg_type == 0)
2645     show_msg(inbuf);
2646   else if(msg_type == 0x85)
2647     return; /* Keepalive packet. */
2648
2649   nread = construct_reply(inbuf,outbuf,nread,max_send);
2650       
2651   if(nread > 0) 
2652   {
2653     if (CVAL(outbuf,0) == 0)
2654       show_msg(outbuf);
2655         
2656     if (nread != smb_len(outbuf) + 4) 
2657     {
2658       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2659                  nread, smb_len(outbuf)));
2660     }
2661     else
2662       send_smb(Client,outbuf);
2663   }
2664   trans_num++;
2665 }
2666
2667 /****************************************************************************
2668   open the oplock IPC socket communication
2669 ****************************************************************************/
2670 static BOOL open_oplock_ipc()
2671 {
2672   struct sockaddr_in sock_name;
2673   int len = sizeof(sock_name);
2674
2675   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2676
2677   /* Open a lookback UDP socket on a random port. */
2678   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2679   if (oplock_sock == -1)
2680   {
2681     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2682 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2683     oplock_port = 0;
2684     return(False);
2685   }
2686
2687   /* Find out the transient UDP port we have been allocated. */
2688   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2689   {
2690     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2691             strerror(errno)));
2692     close(oplock_sock);
2693     oplock_sock = -1;
2694     oplock_port = 0;
2695     return False;
2696   }
2697   oplock_port = ntohs(sock_name.sin_port);
2698
2699   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2700             getpid(), oplock_port));
2701
2702   return True;
2703 }
2704
2705 /****************************************************************************
2706   process an oplock break message.
2707 ****************************************************************************/
2708 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2709 {
2710   int32 msg_len;
2711   uint16 from_port;
2712   char *msg_start;
2713
2714   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2715   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2716
2717   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2718
2719   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2720             msg_len, from_port));
2721
2722   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2723      only valid request. */
2724
2725   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2726   {
2727     case OPLOCK_BREAK_CMD:
2728       /* Ensure that the msg length is correct. */
2729       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2730       {
2731         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2732 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2733         return False;
2734       }
2735       {
2736         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2737         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2738         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2739         struct timeval tval;
2740         struct sockaddr_in toaddr;
2741
2742         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2743         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2744
2745         DEBUG(5,("process_local_message: oplock break request from \
2746 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2747
2748         /*
2749          * If we have no record of any currently open oplocks,
2750          * it's not an error, as a close command may have
2751          * just been issued on the file that was oplocked.
2752          * Just return success in this case.
2753          */
2754
2755         if(global_oplocks_open != 0)
2756         {
2757           if(oplock_break(dev, inode, &tval) == False)
2758           {
2759             DEBUG(0,("process_local_message: oplock break failed - \
2760 not returning udp message.\n"));
2761             return False;
2762           }
2763         }
2764         else
2765         {
2766           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2767 oplocks. Returning success.\n"));
2768         }
2769
2770         /* Send the message back after OR'ing in the 'REPLY' bit. */
2771         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2772   
2773         bzero((char *)&toaddr,sizeof(toaddr));
2774         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2775         toaddr.sin_port = htons(from_port);
2776         toaddr.sin_family = AF_INET;
2777
2778         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2779                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2780         {
2781           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2782                     remotepid, strerror(errno)));
2783           return False;
2784         }
2785
2786         DEBUG(5,("process_local_message: oplock break reply sent to \
2787 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2788                 from_port, dev, inode));
2789
2790       }
2791       break;
2792     /* 
2793      * Keep this as a debug case - eventually we can remove it.
2794      */
2795     case 0x8001:
2796       DEBUG(0,("process_local_message: Received unsolicited break \
2797 reply - dumping info.\n"));
2798
2799       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2800       {
2801         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2802 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2803         return False;
2804       }
2805
2806       {
2807         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2808         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2809         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2810
2811         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2812 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2813
2814        }
2815        return False;
2816
2817     default:
2818       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2819                 (unsigned int)SVAL(msg_start,0)));
2820       return False;
2821   }
2822   return True;
2823 }
2824
2825 /****************************************************************************
2826  Process an oplock break directly.
2827 ****************************************************************************/
2828 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2829 {
2830   extern int Client;
2831   char *inbuf = NULL;
2832   char *outbuf = NULL;
2833   files_struct *fsp = NULL;
2834   int fnum;
2835   time_t start_time;
2836   BOOL shutdown_server = False;
2837
2838   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2839 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2840
2841   /* We need to search the file open table for the
2842      entry containing this dev and inode, and ensure
2843      we have an oplock on it. */
2844   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2845   {
2846     if(OPEN_FNUM(fnum))
2847     {
2848       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2849          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
2850          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2851               fsp = &Files[fnum];
2852               break;
2853       }
2854     }
2855   }
2856
2857   if(fsp == NULL)
2858   {
2859     /* The file could have been closed in the meantime - return success. */
2860     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2861 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2862     return True;
2863   }
2864
2865   /* Ensure we have an oplock on the file */
2866
2867   /* There is a potential race condition in that an oplock could
2868      have been broken due to another udp request, and yet there are
2869      still oplock break messages being sent in the udp message
2870      queue for this file. So return true if we don't have an oplock,
2871      as we may have just freed it.
2872    */
2873
2874   if(!fsp->granted_oplock)
2875   {
2876     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));
2877     return True;
2878   }
2879
2880   /* mark the oplock break as sent - we don't want to send twice! */
2881   if (fsp->sent_oplock_break)
2882   {
2883     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));
2884
2885     /* We have to fail the open here as we cannot send another oplock break on this
2886        file whilst we are awaiting a response from the client - neither can we
2887        allow another open to succeed while we are waiting for the client. */
2888     return False;
2889   }
2890
2891   /* Now comes the horrid part. We must send an oplock break to the client,
2892      and then process incoming messages until we get a close or oplock release.
2893      At this point we know we need a new inbuf/outbuf buffer pair.
2894      We cannot use these staticaly as we may recurse into here due to
2895      messages crossing on the wire.
2896    */
2897
2898   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2899   {
2900     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2901     return False;
2902   }
2903
2904   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2905   {
2906     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2907     free(inbuf);
2908     inbuf = NULL;
2909     return False;
2910   }
2911
2912   /* Prepare the SMBlockingX message. */
2913   bzero(outbuf,smb_size);
2914   set_message(outbuf,8,0,True);
2915
2916   SCVAL(outbuf,smb_com,SMBlockingX);
2917   SSVAL(outbuf,smb_tid,fsp->cnum);
2918   SSVAL(outbuf,smb_pid,0xFFFF);
2919   SSVAL(outbuf,smb_uid,0);
2920   SSVAL(outbuf,smb_mid,0xFFFF);
2921   SCVAL(outbuf,smb_vwv0,0xFF);
2922   SSVAL(outbuf,smb_vwv2,fnum);
2923   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2924   /* Change this when we have level II oplocks. */
2925   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2926  
2927   send_smb(Client, outbuf);
2928
2929   /* Remember we just sent an oplock break on this file. */
2930   fsp->sent_oplock_break = True;
2931
2932   /* We need this in case a readraw crosses on the wire. */
2933   global_oplock_break = True;
2934  
2935   /* Process incoming messages. */
2936
2937   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2938      seconds we should just die.... */
2939
2940   start_time = time(NULL);
2941
2942   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2943   {
2944     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2945     {
2946       /*
2947        * Die if we got an error.
2948        */
2949
2950       if (smb_read_error == READ_EOF)
2951         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2952  
2953       if (smb_read_error == READ_ERROR)
2954         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2955                   timestring(), strerror(errno)));
2956
2957       if (smb_read_error == READ_TIMEOUT)
2958         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2959                   timestring(), OPLOCK_BREAK_TIMEOUT));
2960
2961       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2962 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2963       shutdown_server = True;
2964       break;
2965     }
2966
2967     /*
2968      * There are certain SMB requests that we shouldn't allow
2969      * to recurse. opens, renames and deletes are the obvious
2970      * ones. This is handled in the switch_message() function.
2971      * If global_oplock_break is set they will push the packet onto
2972      * the pending smb queue and return -1 (no reply).
2973      * JRA.
2974      */
2975
2976     process_smb(inbuf, outbuf);
2977
2978     /*
2979      * Die if we go over the time limit.
2980      */
2981
2982     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2983     {
2984       DEBUG(0,("%s oplock_break: no break received from client within \
2985 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2986       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2987 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2988       shutdown_server = True;
2989       break;
2990     }
2991   }
2992
2993   /* Free the buffers we've been using to recurse. */
2994   free(inbuf);
2995   free(outbuf);
2996
2997   /* We need this in case a readraw crossed on the wire. */
2998   if(global_oplock_break)
2999     global_oplock_break = False;
3000
3001   /*
3002    * If the client did not respond we must die.
3003    */
3004
3005   if(shutdown_server)
3006   {
3007     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3008           timestring()));
3009     close_sockets();
3010     close(oplock_sock);
3011     exit_server("oplock break failure");
3012   }
3013
3014   if(OPEN_FNUM(fnum))
3015   {
3016     /* The lockingX reply will have removed the oplock flag 
3017        from the sharemode. */
3018     /* Paranoia.... */
3019     fsp->granted_oplock = False;
3020     fsp->sent_oplock_break = False;
3021     global_oplocks_open--;
3022   }
3023
3024   /* Santity check - remove this later. JRA */
3025   if(global_oplocks_open < 0)
3026   {
3027     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3028               global_oplocks_open));
3029     exit_server("oplock_break: global_oplocks_open < 0");
3030   }
3031
3032   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3033 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3034
3035   return True;
3036 }
3037
3038 /****************************************************************************
3039 Send an oplock break message to another smbd process. If the oplock is held 
3040 by the local smbd then call the oplock break function directly.
3041 ****************************************************************************/
3042
3043 BOOL request_oplock_break(share_mode_entry *share_entry, 
3044                           uint32 dev, uint32 inode)
3045 {
3046   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3047   struct sockaddr_in addr_out;
3048   int pid = getpid();
3049   time_t start_time;
3050   int time_left;
3051
3052   if(pid == share_entry->pid)
3053   {
3054     /* We are breaking our own oplock, make sure it's us. */
3055     if(share_entry->op_port != oplock_port)
3056     {
3057       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3058 should be %d\n", pid, share_entry->op_port, oplock_port));
3059       return False;
3060     }
3061
3062     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3063
3064     /* Call oplock break direct. */
3065     return oplock_break(dev, inode, &share_entry->time);
3066   }
3067
3068   /* We need to send a OPLOCK_BREAK_CMD message to the
3069      port in the share mode entry. */
3070
3071   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3072   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3073   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3074   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3075   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3076   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3077
3078   /* set the address and port */
3079   bzero((char *)&addr_out,sizeof(addr_out));
3080   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3081   addr_out.sin_port = htons( share_entry->op_port );
3082   addr_out.sin_family = AF_INET;
3083    
3084   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3085 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3086
3087   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3088          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3089   {
3090     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3091 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3092          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3093          strerror(errno)));
3094     return False;
3095   }
3096
3097   /*
3098    * Now we must await the oplock broken message coming back
3099    * from the target smbd process. Timeout if it fails to
3100    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3101    * While we get messages that aren't ours, loop.
3102    */
3103
3104   start_time = time(NULL);
3105   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3106
3107   while(time_left >= 0)
3108   {
3109     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3110     int32 reply_msg_len;
3111     uint16 reply_from_port;
3112     char *reply_msg_start;
3113
3114     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3115                time_left ? time_left * 1000 : 1) == False)
3116     {
3117       if(smb_read_error == READ_TIMEOUT)
3118       {
3119         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3120 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3121                            share_entry->op_port, dev, inode));
3122         /*
3123          * This is a hack to make handling of failing clients more robust.
3124          * If a oplock break response message is not received in the timeout
3125          * period we may assume that the smbd servicing that client holding
3126          * the oplock has died and the client changes were lost anyway, so
3127          * we should continue to try and open the file.
3128          */
3129         break;
3130       }
3131       else
3132         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3133 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3134                          share_entry->op_port, dev, inode, strerror(errno)));
3135       return False;
3136     }
3137
3138     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3139     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3140
3141     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3142
3143     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3144     {
3145       /* Ignore it. */
3146       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3147              timestring()));
3148       continue;
3149     }
3150
3151     /*
3152      * Test to see if this is the reply we are awaiting.
3153      */
3154
3155     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3156        (reply_from_port == share_entry->op_port) && 
3157        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3158                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3159                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3160     {
3161       /*
3162        * This is the reply we've been waiting for.
3163        */
3164       break;
3165     }
3166     else
3167     {
3168       /*
3169        * This is another message - probably a break request.
3170        * Process it to prevent potential deadlock.
3171        * Note that the code in switch_message() prevents
3172        * us from recursing into here as any SMB requests
3173        * we might process that would cause another oplock
3174        * break request to be made will be queued.
3175        * JRA.
3176        */
3177
3178       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3179     }
3180
3181     time_left -= (time(NULL) - start_time);
3182   }
3183
3184   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3185
3186   return True;
3187 }
3188
3189 /****************************************************************************
3190 Get the next SMB packet, doing the local message processing automatically.
3191 ****************************************************************************/
3192
3193 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3194 {
3195   BOOL got_smb = False;
3196   BOOL ret;
3197
3198   do
3199   {
3200     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3201                                  timeout,&got_smb);
3202
3203     if(ret && !got_smb)
3204     {
3205       /* Deal with oplock break requests from other smbd's. */
3206       process_local_message(oplock_sock, inbuf, bufsize);
3207       continue;
3208     }
3209
3210     if(ret && (CVAL(inbuf,0) == 0x85))
3211     {
3212       /* Keepalive packet. */
3213       got_smb = False;
3214     }
3215
3216   }
3217   while(ret && !got_smb);
3218
3219   return ret;
3220 }
3221
3222 /****************************************************************************
3223 check if a snum is in use
3224 ****************************************************************************/
3225 BOOL snum_used(int snum)
3226 {
3227   int i;
3228   for (i=0;i<MAX_CONNECTIONS;i++)
3229     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3230       return(True);
3231   return(False);
3232 }
3233
3234 /****************************************************************************
3235   reload the services file
3236   **************************************************************************/
3237 BOOL reload_services(BOOL test)
3238 {
3239   BOOL ret;
3240
3241   if (lp_loaded())
3242     {
3243       pstring fname;
3244       pstrcpy(fname,lp_configfile());
3245       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3246         {
3247           pstrcpy(servicesf,fname);
3248           test = False;
3249         }
3250     }
3251
3252   reopen_logs();
3253
3254   if (test && !lp_file_list_changed())
3255     return(True);
3256
3257   lp_killunused(snum_used);
3258
3259   ret = lp_load(servicesf,False);
3260
3261   /* perhaps the config filename is now set */
3262   if (!test)
3263     reload_services(True);
3264
3265   reopen_logs();
3266
3267   load_interfaces();
3268
3269   {
3270     extern int Client;
3271     if (Client != -1) {      
3272       set_socket_options(Client,"SO_KEEPALIVE");
3273       set_socket_options(Client,user_socket_options);
3274     }
3275   }
3276
3277   reset_mangled_stack( lp_mangledstack() );
3278
3279   /* this forces service parameters to be flushed */
3280   become_service(-1,True);
3281
3282   return(ret);
3283 }
3284
3285
3286
3287 /****************************************************************************
3288 this prevents zombie child processes
3289 ****************************************************************************/
3290 static int sig_hup()
3291 {
3292   BlockSignals(True,SIGHUP);
3293   DEBUG(0,("Got SIGHUP\n"));
3294   reload_services(False);
3295 #ifndef DONT_REINSTALL_SIG
3296   signal(SIGHUP,SIGNAL_CAST sig_hup);
3297 #endif
3298   BlockSignals(False,SIGHUP);
3299   return(0);
3300 }
3301
3302 /****************************************************************************
3303 Setup the groups a user belongs to.
3304 ****************************************************************************/
3305 int setup_groups(char *user, int uid, int gid, int *p_ngroups, 
3306                  int **p_igroups, gid_t **p_groups,
3307          int **p_attrs)
3308 {
3309   if (-1 == initgroups(user,gid))
3310     {
3311       if (getuid() == 0)
3312         {
3313           DEBUG(0,("Unable to initgroups!\n"));
3314           if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3315             DEBUG(0,("This is probably a problem with the account %s\n",user));
3316         }
3317     }
3318   else
3319     {
3320       int i,ngroups;
3321       int *igroups;
3322       int *attrs;
3323       gid_t grp = 0;
3324       ngroups = getgroups(0,&grp);
3325       if (ngroups <= 0)
3326         ngroups = 32;
3327       igroups = (int *)malloc(sizeof(int)*ngroups);
3328       attrs   = (int *)malloc(sizeof(int)*ngroups);
3329       for (i=0;i<ngroups;i++)
3330       {
3331         attrs  [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3332         igroups[i] = 0x42424242;
3333       }
3334       ngroups = getgroups(ngroups,(gid_t *)igroups);
3335
3336       if (igroups[0] == 0x42424242)
3337         ngroups = 0;
3338
3339       *p_ngroups = ngroups;
3340       *p_attrs   = attrs;
3341
3342       /* The following bit of code is very strange. It is due to the
3343          fact that some OSes use int* and some use gid_t* for
3344          getgroups, and some (like SunOS) use both, one in prototypes,
3345          and one in man pages and the actual code. Thus we detect it
3346          dynamically using some very ugly code */
3347       if (ngroups > 0)
3348         {
3349           /* does getgroups return ints or gid_t ?? */
3350           static BOOL groups_use_ints = True;
3351
3352           if (groups_use_ints && 
3353               ngroups == 1 && 
3354               SVAL(igroups,2) == 0x4242)
3355             groups_use_ints = False;
3356           
3357           for (i=0;groups_use_ints && i<ngroups;i++)
3358             if (igroups[i] == 0x42424242)
3359               groups_use_ints = False;
3360               
3361           if (groups_use_ints)
3362           {
3363               *p_igroups = igroups;
3364               *p_groups = (gid_t *)igroups;       
3365           }
3366           else
3367           {
3368               gid_t *groups = (gid_t *)igroups;
3369               igroups = (int *)malloc(sizeof(int)*ngroups);
3370               for (i=0;i<ngroups;i++)
3371           {
3372                 igroups[i] = groups[i];
3373           }
3374               *p_igroups = igroups;
3375               *p_groups = (gid_t *)groups;
3376             }
3377         }
3378       DEBUG(3,("%s is in %d groups\n",user,ngroups));
3379       for (i=0;i<ngroups;i++)
3380         DEBUG(3,("%d ",igroups[i]));
3381       DEBUG(3,("\n"));
3382     }
3383   return 0;
3384 }
3385
3386 /****************************************************************************
3387   make a connection to a service
3388 ****************************************************************************/
3389 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3390 {
3391   int cnum;
3392   int snum;
3393   struct passwd *pass = NULL;
3394   connection_struct *pcon;
3395   BOOL guest = False;
3396   BOOL force = False;
3397   static BOOL first_connection = True;
3398
3399   strlower(service);
3400
3401   snum = find_service(service);
3402   if (snum < 0)
3403     {
3404       if (strequal(service,"IPC$"))
3405         {         
3406           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3407           return(-3);
3408         }
3409
3410       DEBUG(0,("%s couldn't find service %s\n",timestring(),service));      
3411       return(-2);
3412     }
3413
3414   if (strequal(service,HOMES_NAME))
3415     {
3416       if (*user && Get_Pwnam(user,True))
3417         return(make_connection(user,user,password,pwlen,dev,vuid));
3418
3419       if (validated_username(vuid))
3420         {
3421           strcpy(user,validated_username(vuid));
3422           return(make_connection(user,user,password,pwlen,dev,vuid));
3423         }
3424     }
3425
3426   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3427     return(-4);
3428   }
3429
3430   /* you can only connect to the IPC$ service as an ipc device */
3431   if (strequal(service,"IPC$"))
3432     strcpy(dev,"IPC");
3433
3434   if (*dev == '?' || !*dev)
3435     {
3436       if (lp_print_ok(snum))
3437         strcpy(dev,"LPT1:");
3438       else
3439         strcpy(dev,"A:");
3440     }
3441
3442   /* if the request is as a printer and you can't print then refuse */
3443   strupper(dev);
3444   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3445     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3446     return(-6);
3447   }
3448
3449   /* lowercase the user name */
3450   strlower(user);
3451
3452   /* add it as a possible user name */
3453   add_session_user(service);
3454
3455   /* shall we let them in? */
3456   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3457     {
3458       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3459       return(-1);
3460     }
3461   
3462   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3463   if (cnum < 0)
3464     {
3465       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3466       return(-1);
3467     }
3468
3469   pcon = &Connections[cnum];
3470   bzero((char *)pcon,sizeof(*pcon));
3471
3472   /* find out some info about the user */
3473   pass = Get_Pwnam(user,True);
3474
3475   if (pass == NULL)
3476     {
3477       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3478       return(-7);
3479     }
3480
3481   pcon->read_only = lp_readonly(snum);
3482
3483   {
3484     pstring list;
3485     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3486     string_sub(list,"%S",service);
3487
3488     if (user_in_list(user,list))
3489       pcon->read_only = True;
3490
3491     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3492     string_sub(list,"%S",service);
3493
3494     if (user_in_list(user,list))
3495       pcon->read_only = False;    
3496   }
3497
3498   /* admin user check */
3499
3500   /* JRA - original code denied admin user if the share was
3501      marked read_only. Changed as I don't think this is needed,
3502      but old code left in case there is a problem here.
3503    */
3504   if (user_in_list(user,lp_admin_users(snum)) 
3505 #if 0
3506       && !pcon->read_only)
3507 #else
3508       )
3509 #endif
3510     {
3511       pcon->admin_user = True;
3512       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3513     }
3514   else
3515     pcon->admin_user = False;
3516     
3517   pcon->force_user = force;
3518   pcon->vuid = vuid;
3519   pcon->uid = pass->pw_uid;
3520   pcon->gid = pass->pw_gid;
3521   pcon->num_files_open = 0;
3522   pcon->lastused = time(NULL);
3523   pcon->service = snum;
3524   pcon->used = True;
3525   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3526   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3527   pcon->dirptr = NULL;
3528   pcon->veto_list = NULL;
3529   pcon->hide_list = NULL;
3530   pcon->veto_oplock_list = NULL;
3531   string_set(&pcon->dirpath,"");
3532   string_set(&pcon->user,user);
3533
3534 #if HAVE_GETGRNAM 
3535   if (*lp_force_group(snum))
3536     {
3537       struct group *gptr;
3538       pstring gname;
3539
3540       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3541       /* default service may be a group name            */
3542       string_sub(gname,"%S",service);
3543       gptr = (struct group *)getgrnam(gname);
3544
3545       if (gptr)
3546         {
3547           pcon->gid = gptr->gr_gid;
3548           DEBUG(3,("Forced group %s\n",gname));
3549         }
3550       else
3551         DEBUG(1,("Couldn't find group %s\n",gname));
3552     }
3553 #endif
3554
3555   if (*lp_force_user(snum))
3556     {
3557       struct passwd *pass2;
3558       fstring fuser;
3559       fstrcpy(fuser,lp_force_user(snum));
3560       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3561       if (pass2)
3562         {
3563           pcon->uid = pass2->pw_uid;
3564           string_set(&pcon->user,fuser);
3565           fstrcpy(user,fuser);
3566           pcon->force_user = True;
3567           DEBUG(3,("Forced user %s\n",fuser));    
3568         }
3569       else
3570         DEBUG(1,("Couldn't find user %s\n",fuser));
3571     }
3572
3573   {
3574     pstring s;
3575     pstrcpy(s,lp_pathname(snum));
3576     standard_sub(cnum,s);
3577     string_set(&pcon->connectpath,s);
3578     DEBUG(3,("Connect path is %s\n",s));
3579   }
3580
3581   /* groups stuff added by ih */
3582   pcon->ngroups = 0;
3583   pcon->igroups = NULL;
3584   pcon->groups = NULL;
3585   pcon->attrs = NULL;
3586
3587   if (!IS_IPC(cnum))
3588     {
3589       /* Find all the groups this uid is in and store them. Used by become_user() */
3590       setup_groups(pcon->user,pcon->uid,pcon->gid,
3591                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3592       
3593       /* check number of connections */
3594       if (!claim_connection(cnum,
3595                             lp_servicename(SNUM(cnum)),
3596                             lp_max_connections(SNUM(cnum)),False))
3597         {
3598           DEBUG(1,("too many connections - rejected\n"));
3599           return(-8);
3600         }  
3601
3602       if (lp_status(SNUM(cnum)))
3603         claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3604
3605       first_connection = False;
3606     } /* IS_IPC */
3607
3608   pcon->open = True;
3609
3610   /* execute any "root preexec = " line */
3611   if (*lp_rootpreexec(SNUM(cnum)))
3612     {
3613       pstring cmd;
3614       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3615       standard_sub(cnum,cmd);
3616       DEBUG(5,("cmd=%s\n",cmd));
3617       smbrun(cmd,NULL,False);
3618     }
3619
3620   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3621     {
3622       DEBUG(0,("Can't become connected user!\n"));
3623       pcon->open = False;
3624       if (!IS_IPC(cnum)) {
3625         yield_connection(cnum,
3626                          lp_servicename(SNUM(cnum)),
3627                          lp_max_connections(SNUM(cnum)));
3628         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3629       }
3630       return(-1);
3631     }
3632
3633   if (ChDir(pcon->connectpath) != 0)
3634     {
3635       DEBUG(0,("Can't change directory to %s (%s)\n",
3636                pcon->connectpath,strerror(errno)));
3637       pcon->open = False;
3638       unbecome_user();
3639       if (!IS_IPC(cnum)) {
3640         yield_connection(cnum,
3641                          lp_servicename(SNUM(cnum)),
3642                          lp_max_connections(SNUM(cnum)));
3643         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3644       }
3645       return(-5);      
3646     }
3647
3648   string_set(&pcon->origpath,pcon->connectpath);
3649
3650 #if SOFTLINK_OPTIMISATION
3651   /* resolve any soft links early */
3652   {
3653     pstring s;
3654     pstrcpy(s,pcon->connectpath);
3655     GetWd(s);
3656     string_set(&pcon->connectpath,s);
3657     ChDir(pcon->connectpath);
3658   }
3659 #endif
3660
3661   num_connections_open++;
3662   add_session_user(user);
3663   
3664   /* execute any "preexec = " line */
3665   if (*lp_preexec(SNUM(cnum)))
3666     {
3667       pstring cmd;
3668       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3669       standard_sub(cnum,cmd);
3670       smbrun(cmd,NULL,False);
3671     }
3672   
3673   /* we've finished with the sensitive stuff */
3674   unbecome_user();
3675
3676   /* Add veto/hide lists */
3677   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3678   {
3679     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3680     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3681     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3682   }
3683
3684   {
3685     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3686                             timestring(),
3687                             remote_machine,
3688                             client_addr(),
3689                             lp_servicename(SNUM(cnum)),user,
3690                             pcon->uid,
3691                             pcon->gid,
3692                             (int)getpid()));
3693   }
3694
3695   return(cnum);
3696 }
3697
3698
3699 /****************************************************************************
3700   find first available file slot
3701 ****************************************************************************/
3702 int find_free_file(void )
3703 {
3704         int i;
3705         static int first_file;
3706
3707         /* we want to give out file handles differently on each new
3708            connection because of a common bug in MS clients where they try to
3709            reuse a file descriptor from an earlier smb connection. This code
3710            increases the chance that the errant client will get an error rather
3711            than causing corruption */
3712         if (first_file == 0) {
3713                 first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES;
3714                 if (first_file == 0) first_file = 1;
3715         }
3716
3717         if (first_file >= MAX_OPEN_FILES)
3718                 first_file = 1;
3719
3720         for (i=first_file;i<MAX_OPEN_FILES;i++)
3721                 if (!Files[i].open && !Files[i].reserved) {
3722                         memset(&Files[i], 0, sizeof(Files[i]));
3723                         first_file = i+1;
3724                         Files[i].reserved = True;
3725                         return(i);
3726                 }
3727
3728         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3729         for (i=1;i<first_file;i++)
3730                 if (!Files[i].open && !Files[i].reserved) {
3731                         memset(&Files[i], 0, sizeof(Files[i]));
3732                         first_file = i+1;
3733                         Files[i].reserved = True;
3734                         return(i);
3735                 }
3736
3737
3738         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3739         return(-1);
3740 }
3741
3742 /****************************************************************************
3743   find first available connection slot, starting from a random position.
3744 The randomisation stops problems with the server dieing and clients
3745 thinking the server is still available.
3746 ****************************************************************************/
3747 static int find_free_connection(int hash )
3748 {
3749   int i;
3750   BOOL used=False;
3751   hash = (hash % (MAX_CONNECTIONS-2))+1;
3752
3753  again:
3754
3755   for (i=hash+1;i!=hash;)
3756     {
3757       if (!Connections[i].open && Connections[i].used == used) 
3758         {
3759           DEBUG(3,("found free connection number %d\n",i));
3760           return(i);
3761         }
3762       i++;
3763       if (i == MAX_CONNECTIONS)
3764         i = 1;
3765     }
3766
3767   if (!used)
3768     {
3769       used = !used;
3770       goto again;
3771     }
3772
3773   DEBUG(1,("ERROR! Out of connection structures\n"));
3774   return(-1);
3775 }
3776
3777
3778 /****************************************************************************
3779 reply for the core protocol
3780 ****************************************************************************/
3781 int reply_corep(char *outbuf)
3782 {
3783   int outsize = set_message(outbuf,1,0,True);
3784
3785   Protocol = PROTOCOL_CORE;
3786
3787   return outsize;
3788 }
3789
3790
3791 /****************************************************************************
3792 reply for the coreplus protocol
3793 ****************************************************************************/
3794 int reply_coreplus(char *outbuf)
3795 {
3796   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3797   int outsize = set_message(outbuf,13,0,True);
3798   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3799                                  readbraw and writebraw (possibly) */
3800   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3801   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3802
3803   Protocol = PROTOCOL_COREPLUS;
3804
3805   return outsize;
3806 }
3807
3808
3809 /****************************************************************************
3810 reply for the lanman 1.0 protocol
3811 ****************************************************************************/
3812 int reply_lanman1(char *outbuf)
3813 {
3814   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3815   int secword=0;
3816   BOOL doencrypt = SMBENCRYPT();
3817   time_t t = time(NULL);
3818
3819   if (lp_security()>=SEC_USER) secword |= 1;
3820   if (doencrypt) secword |= 2;
3821
3822   set_message(outbuf,13,doencrypt?8:0,True);
3823   SSVAL(outbuf,smb_vwv1,secword); 
3824   /* Create a token value and add it to the outgoing packet. */
3825   if (doencrypt) 
3826     generate_next_challenge(smb_buf(outbuf));
3827
3828   Protocol = PROTOCOL_LANMAN1;
3829
3830   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3831   SSVAL(outbuf,smb_vwv2,max_recv);
3832   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3833   SSVAL(outbuf,smb_vwv4,1);
3834   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3835                                  readbraw writebraw (possibly) */
3836   SIVAL(outbuf,smb_vwv6,getpid());
3837   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3838
3839   put_dos_date(outbuf,smb_vwv8,t);
3840
3841   return (smb_len(outbuf)+4);
3842 }
3843
3844
3845 /****************************************************************************
3846 reply for the lanman 2.0 protocol
3847 ****************************************************************************/
3848 int reply_lanman2(char *outbuf)
3849 {
3850   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3851   int secword=0;
3852   BOOL doencrypt = SMBENCRYPT();
3853   time_t t = time(NULL);
3854   struct cli_state *cli = NULL;
3855   char cryptkey[8];
3856   char crypt_len = 0;
3857
3858   if (lp_security() == SEC_SERVER) {
3859           cli = server_cryptkey();
3860   }
3861
3862   if (cli) {
3863           DEBUG(3,("using password server validation\n"));
3864           doencrypt = ((cli->sec_mode & 2) != 0);
3865   }
3866
3867   if (lp_security()>=SEC_USER) secword |= 1;
3868   if (doencrypt) secword |= 2;
3869
3870   if (doencrypt) {
3871           crypt_len = 8;
3872           if (!cli) {
3873                   generate_next_challenge(cryptkey);
3874           } else {
3875                   memcpy(cryptkey, cli->cryptkey, 8);
3876                   set_challenge(cli->cryptkey);
3877           }
3878   }
3879
3880   set_message(outbuf,13,crypt_len,True);
3881   SSVAL(outbuf,smb_vwv1,secword); 
3882   SIVAL(outbuf,smb_vwv6,getpid());
3883   if (doencrypt) 
3884           memcpy(smb_buf(outbuf), cryptkey, 8);
3885
3886   Protocol = PROTOCOL_LANMAN2;
3887
3888   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3889   SSVAL(outbuf,smb_vwv2,max_recv);
3890   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3891   SSVAL(outbuf,smb_vwv4,1);
3892   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3893   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3894   put_dos_date(outbuf,smb_vwv8,t);
3895
3896   return (smb_len(outbuf)+4);
3897 }
3898
3899
3900 /****************************************************************************
3901 reply for the nt protocol
3902 ****************************************************************************/
3903 int reply_nt1(char *outbuf)
3904 {
3905   /* dual names + lock_and_read + nt SMBs + remote API calls */
3906   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3907 /*
3908   other valid capabilities which we may support at some time...
3909                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3910                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3911  */
3912
3913   int secword=0;
3914   BOOL doencrypt = SMBENCRYPT();
3915   time_t t = time(NULL);
3916   int data_len;
3917   struct cli_state *cli = NULL;
3918   char cryptkey[8];
3919   char crypt_len = 0;
3920
3921   if (lp_security() == SEC_SERVER) {
3922           cli = server_cryptkey();
3923   }
3924
3925   if (cli) {
3926           DEBUG(3,("using password server validation\n"));
3927           doencrypt = ((cli->sec_mode & 2) != 0);
3928   }
3929
3930   if (doencrypt) {
3931           crypt_len = 8;
3932           if (!cli) {
3933                   generate_next_challenge(cryptkey);
3934           } else {
3935                   memcpy(cryptkey, cli->cryptkey, 8);
3936                   set_challenge(cli->cryptkey);
3937           }
3938   }
3939
3940   if (lp_readraw() && lp_writeraw()) {
3941           capabilities |= CAP_RAW_MODE;
3942   }
3943
3944   if (lp_security() >= SEC_USER) secword |= 1;
3945   if (doencrypt) secword |= 2;
3946
3947   /* decide where (if) to put the encryption challenge, and
3948      follow it with the OEM'd domain name
3949    */
3950   data_len = crypt_len + strlen(myworkgroup) + 1;
3951
3952   set_message(outbuf,17,data_len,True);
3953   strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3954
3955   CVAL(outbuf,smb_vwv1) = secword;
3956   SSVALS(outbuf,smb_vwv16+1,crypt_len);
3957   if (doencrypt) 
3958           memcpy(smb_buf(outbuf), cryptkey, 8);
3959
3960   Protocol = PROTOCOL_NT1;
3961
3962   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3963   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3964   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3965   SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3966   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3967   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3968   put_long_date(outbuf+smb_vwv11+1,t);
3969   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3970   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3971
3972   return (smb_len(outbuf)+4);
3973 }
3974
3975 /* these are the protocol lists used for auto architecture detection:
3976
3977 WinNT 3.51:
3978 protocol [PC NETWORK PROGRAM 1.0]
3979 protocol [XENIX CORE]
3980 protocol [MICROSOFT NETWORKS 1.03]
3981 protocol [LANMAN1.0]
3982 protocol [Windows for Workgroups 3.1a]
3983 protocol [LM1.2X002]
3984 protocol [LANMAN2.1]
3985 protocol [NT LM 0.12]
3986
3987 Win95:
3988 protocol [PC NETWORK PROGRAM 1.0]
3989 protocol [XENIX CORE]
3990 protocol [MICROSOFT NETWORKS 1.03]
3991 protocol [LANMAN1.0]
3992 protocol [Windows for Workgroups 3.1a]
3993 protocol [LM1.2X002]
3994 protocol [LANMAN2.1]
3995 protocol [NT LM 0.12]
3996
3997 OS/2:
3998 protocol [PC NETWORK PROGRAM 1.0]
3999 protocol [XENIX CORE]
4000 protocol [LANMAN1.0]
4001 protocol [LM1.2X002]
4002 protocol [LANMAN2.1]
4003 */
4004
4005 /*
4006   * Modified to recognize the architecture of the remote machine better.
4007   *
4008   * This appears to be the matrix of which protocol is used by which
4009   * MS product.
4010        Protocol                       WfWg    Win95   WinNT  OS/2
4011        PC NETWORK PROGRAM 1.0          1       1       1      1
4012        XENIX CORE                                      2      2
4013        MICROSOFT NETWORKS 3.0          2       2       
4014        DOS LM1.2X002                   3       3       
4015        MICROSOFT NETWORKS 1.03                         3
4016        DOS LANMAN2.1                   4       4       
4017        LANMAN1.0                                       4      3
4018        Windows for Workgroups 3.1a     5       5       5
4019        LM1.2X002                                       6      4
4020        LANMAN2.1                                       7      5
4021        NT LM 0.12                              6       8
4022   *
4023   *  tim@fsg.com 09/29/95
4024   */
4025   
4026 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4027 #define ARCH_WIN95    0x2
4028 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4029 #define ARCH_WINNT    0x8
4030 #define ARCH_SAMBA    0x10
4031  
4032 #define ARCH_ALL      0x1F
4033  
4034 /* List of supported protocols, most desired first */
4035 struct {
4036   char *proto_name;
4037   char *short_name;
4038   int (*proto_reply_fn)(char *);
4039   int protocol_level;
4040 } supported_protocols[] = {
4041   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4042   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4043   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4044   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4045   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4046   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4047   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4048   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4049   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4050   {NULL,NULL},
4051 };
4052
4053
4054 /****************************************************************************
4055   reply to a negprot
4056 ****************************************************************************/
4057 static int reply_negprot(char *inbuf,char *outbuf)
4058 {
4059   int outsize = set_message(outbuf,1,0,True);
4060   int Index=0;
4061   int choice= -1;
4062   int protocol;
4063   char *p;
4064   int bcc = SVAL(smb_buf(inbuf),-2);
4065   int arch = ARCH_ALL;
4066
4067   p = smb_buf(inbuf)+1;
4068   while (p < (smb_buf(inbuf) + bcc))
4069     { 
4070       Index++;
4071       DEBUG(3,("Requested protocol [%s]\n",p));
4072       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4073         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4074       else if (strcsequal(p,"DOS LM1.2X002"))
4075         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4076       else if (strcsequal(p,"DOS LANMAN2.1"))
4077         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4078       else if (strcsequal(p,"NT LM 0.12"))
4079         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4080       else if (strcsequal(p,"LANMAN2.1"))
4081         arch &= ( ARCH_WINNT | ARCH_OS2 );
4082       else if (strcsequal(p,"LM1.2X002"))
4083         arch &= ( ARCH_WINNT | ARCH_OS2 );
4084       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4085         arch &= ARCH_WINNT;
4086       else if (strcsequal(p,"XENIX CORE"))
4087         arch &= ( ARCH_WINNT | ARCH_OS2 );
4088       else if (strcsequal(p,"Samba")) {
4089         arch = ARCH_SAMBA;
4090         break;
4091       }
4092  
4093       p += strlen(p) + 2;
4094     }
4095     
4096   switch ( arch ) {
4097   case ARCH_SAMBA:
4098     set_remote_arch(RA_SAMBA);
4099     break;
4100   case ARCH_WFWG:
4101     set_remote_arch(RA_WFWG);
4102     break;
4103   case ARCH_WIN95:
4104     set_remote_arch(RA_WIN95);
4105     break;
4106   case ARCH_WINNT:
4107     set_remote_arch(RA_WINNT);
4108     break;
4109   case ARCH_OS2:
4110     set_remote_arch(RA_OS2);
4111     break;
4112   default:
4113     set_remote_arch(RA_UNKNOWN);
4114     break;
4115   }
4116  
4117   /* possibly reload - change of architecture */
4118   reload_services(True);      
4119     
4120   /* a special case to stop password server loops */
4121   if (Index == 1 && strequal(remote_machine,myhostname) && 
4122       lp_security()==SEC_SERVER)
4123     exit_server("Password server loop!");
4124   
4125   /* Check for protocols, most desirable first */
4126   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4127     {
4128       p = smb_buf(inbuf)+1;
4129       Index = 0;
4130       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4131         while (p < (smb_buf(inbuf) + bcc))
4132           { 
4133             if (strequal(p,supported_protocols[protocol].proto_name))
4134               choice = Index;
4135             Index++;
4136             p += strlen(p) + 2;
4137           }
4138       if(choice != -1)
4139         break;
4140     }
4141   
4142   SSVAL(outbuf,smb_vwv0,choice);
4143   if(choice != -1) {
4144     extern fstring remote_proto;
4145     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4146     reload_services(True);          
4147     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4148     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4149   }
4150   else {
4151     DEBUG(0,("No protocol supported !\n"));
4152   }
4153   SSVAL(outbuf,smb_vwv0,choice);
4154   
4155   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4156
4157   return(outsize);
4158 }
4159
4160
4161 /****************************************************************************
4162 close all open files for a connection
4163 ****************************************************************************/
4164 static void close_open_files(int cnum)
4165 {
4166   int i;
4167   for (i=0;i<MAX_OPEN_FILES;i++)
4168     if( Files[i].cnum == cnum && Files[i].open) {
4169       close_file(i,False);
4170     }
4171 }
4172
4173
4174
4175 /****************************************************************************
4176 close a cnum
4177 ****************************************************************************/
4178 void close_cnum(int cnum, uint16 vuid)
4179 {
4180   DirCacheFlush(SNUM(cnum));
4181
4182   unbecome_user();
4183
4184   if (!OPEN_CNUM(cnum))
4185     {
4186       DEBUG(0,("Can't close cnum %d\n",cnum));
4187       return;
4188     }
4189
4190   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4191                           timestring(),
4192                           remote_machine,client_addr(),
4193                           lp_servicename(SNUM(cnum))));
4194
4195   yield_connection(cnum,
4196                    lp_servicename(SNUM(cnum)),
4197                    lp_max_connections(SNUM(cnum)));
4198
4199   if (lp_status(SNUM(cnum)))
4200     yield_connection(cnum,"STATUS.",MAXSTATUS);
4201
4202   close_open_files(cnum);
4203   dptr_closecnum(cnum);
4204
4205   /* execute any "postexec = " line */
4206   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4207     {
4208       pstring cmd;
4209       strcpy(cmd,lp_postexec(SNUM(cnum)));
4210       standard_sub(cnum,cmd);
4211       smbrun(cmd,NULL,False);
4212       unbecome_user();
4213     }
4214
4215   unbecome_user();
4216   /* execute any "root postexec = " line */
4217   if (*lp_rootpostexec(SNUM(cnum)))
4218     {
4219       pstring cmd;
4220       strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4221       standard_sub(cnum,cmd);
4222       smbrun(cmd,NULL,False);
4223     }
4224
4225   Connections[cnum].open = False;
4226   num_connections_open--;
4227   if (Connections[cnum].ngroups && Connections[cnum].groups)
4228     {
4229       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4230         free(Connections[cnum].groups);
4231       free(Connections[cnum].igroups);
4232       Connections[cnum].groups = NULL;
4233       Connections[cnum].igroups = NULL;
4234       Connections[cnum].ngroups = 0;
4235     }
4236
4237   free_namearray(Connections[cnum].veto_list);
4238   free_namearray(Connections[cnum].hide_list);
4239   free_namearray(Connections[cnum].veto_oplock_list);
4240
4241   string_set(&Connections[cnum].user,"");
4242   string_set(&Connections[cnum].dirpath,"");
4243   string_set(&Connections[cnum].connectpath,"");
4244 }
4245
4246
4247 /****************************************************************************
4248 simple routines to do connection counting
4249 ****************************************************************************/
4250 BOOL yield_connection(int cnum,char *name,int max_connections)
4251 {
4252   struct connect_record crec;
4253   pstring fname;
4254   FILE *f;
4255   int mypid = getpid();
4256   int i;
4257
4258   DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4259
4260   if (max_connections <= 0)
4261     return(True);
4262
4263   bzero(&crec,sizeof(crec));
4264
4265   pstrcpy(fname,lp_lockdir());
4266   standard_sub(cnum,fname);
4267   trim_string(fname,"","/");
4268
4269   strcat(fname,"/");
4270   strcat(fname,name);
4271   strcat(fname,".LCK");
4272
4273   f = fopen(fname,"r+");
4274   if (!f)
4275     {
4276       DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4277       return(False);
4278     }
4279
4280   fseek(f,0,SEEK_SET);
4281
4282   /* find a free spot */
4283   for (i=0;i<max_connections;i++)
4284     {
4285       if (fread(&crec,sizeof(crec),1,f) != 1)
4286         {
4287           DEBUG(2,("Entry not found in lock file %s\n",fname));
4288           fclose(f);
4289           return(False);
4290         }
4291       if (crec.pid == mypid && crec.cnum == cnum)
4292         break;
4293     }
4294
4295   if (crec.pid != mypid || crec.cnum != cnum)
4296     {
4297       fclose(f);
4298       DEBUG(2,("Entry not found in lock file %s\n",fname));
4299       return(False);
4300     }
4301
4302   bzero((void *)&crec,sizeof(crec));
4303   
4304   /* remove our mark */
4305   if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4306       fwrite(&crec,sizeof(crec),1,f) != 1)
4307     {
4308       DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4309       fclose(f);
4310       return(False);
4311     }
4312
4313   DEBUG(3,("Yield successful\n"));
4314
4315   fclose(f);
4316   return(True);
4317 }
4318
4319
4320 /****************************************************************************
4321 simple routines to do connection counting
4322 ****************************************************************************/
4323 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4324 {
4325   struct connect_record crec;
4326   pstring fname;
4327   FILE *f;
4328   int snum = SNUM(cnum);
4329   int i,foundi= -1;
4330   int total_recs;
4331
4332   if (max_connections <= 0)
4333     return(True);
4334
4335   DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4336
4337   pstrcpy(fname,lp_lockdir());
4338   standard_sub(cnum,fname);
4339   trim_string(fname,"","/");
4340
4341   if (!directory_exist(fname,NULL))
4342     mkdir(fname,0755);
4343
4344   strcat(fname,"/");
4345   strcat(fname,name);
4346   strcat(fname,".LCK");
4347
4348   if (!file_exist(fname,NULL))
4349     {
4350       int oldmask = umask(022);
4351       f = fopen(fname,"w");
4352       if (f) fclose(f);
4353       umask(oldmask);
4354     }
4355
4356   total_recs = file_size(fname) / sizeof(crec);
4357
4358   f = fopen(fname,"r+");
4359
4360   if (!f)
4361     {
4362       DEBUG(1,("couldn't open lock file %s\n",fname));
4363       return(False);
4364     }
4365
4366   /* find a free spot */
4367   for (i=0;i<max_connections;i++)
4368     {
4369
4370       if (i>=total_recs || 
4371           fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4372           fread(&crec,sizeof(crec),1,f) != 1)
4373         {
4374           if (foundi < 0) foundi = i;
4375           break;
4376         }
4377
4378       if (Clear && crec.pid && !process_exists(crec.pid))
4379         {
4380           fseek(f,i*sizeof(crec),SEEK_SET);
4381           bzero((void *)&crec,sizeof(crec));
4382           fwrite(&crec,sizeof(crec),1,f);
4383           if (foundi < 0) foundi = i;
4384           continue;
4385         }
4386       if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4387         {
4388           foundi=i;
4389           if (!Clear) break;
4390         }
4391     }  
4392
4393   if (foundi < 0)
4394     {
4395       DEBUG(3,("no free locks in %s\n",fname));
4396       fclose(f);
4397       return(False);
4398     }      
4399
4400   /* fill in the crec */
4401   bzero((void *)&crec,sizeof(crec));
4402   crec.magic = 0x280267;
4403   crec.pid = getpid();
4404   crec.cnum = cnum;
4405   crec.uid = Connections[cnum].uid;
4406   crec.gid = Connections[cnum].gid;
4407   StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4408   crec.start = time(NULL);
4409
4410   StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4411   StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4412   
4413   /* make our mark */
4414   if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4415       fwrite(&crec,sizeof(crec),1,f) != 1)
4416     {
4417       fclose(f);
4418       return(False);
4419     }
4420
4421   fclose(f);
4422   return(True);
4423 }
4424
4425 #if DUMP_CORE
4426 /*******************************************************************
4427 prepare to dump a core file - carefully!
4428 ********************************************************************/
4429 static BOOL dump_core(void)
4430 {
4431   char *p;
4432   pstring dname;
4433   pstrcpy(dname,debugf);
4434   if ((p=strrchr(dname,'/'))) *p=0;
4435   strcat(dname,"/corefiles");
4436   mkdir(dname,0700);
4437   sys_chown(dname,getuid(),getgid());
4438   chmod(dname,0700);
4439   if (chdir(dname)) return(False);
4440   umask(~(0700));
4441
4442 #ifndef NO_GETRLIMIT
4443 #ifdef RLIMIT_CORE
4444   {
4445     struct rlimit rlp;
4446     getrlimit(RLIMIT_CORE, &rlp);
4447     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4448     setrlimit(RLIMIT_CORE, &rlp);
4449     getrlimit(RLIMIT_CORE, &rlp);
4450     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4451   }
4452 #endif
4453 #endif
4454
4455
4456   DEBUG(0,("Dumping core in %s\n",dname));
4457   return(True);
4458 }
4459 #endif
4460
4461 /****************************************************************************
4462 exit the server
4463 ****************************************************************************/
4464 void exit_server(char *reason)
4465 {
4466   static int firsttime=1;
4467   int i;
4468
4469   if (!firsttime) exit(0);
4470   firsttime = 0;
4471
4472   unbecome_user();
4473   DEBUG(2,("Closing connections\n"));
4474   for (i=0;i<MAX_CONNECTIONS;i++)
4475     if (Connections[i].open)
4476       close_cnum(i,(uint16)-1);
4477 #ifdef DFS_AUTH
4478   if (dcelogin_atmost_once)
4479     dfs_unlogin();
4480 #endif
4481   if (!reason) {   
4482     int oldlevel = DEBUGLEVEL;
4483     DEBUGLEVEL = 10;
4484     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4485     if (last_inbuf)
4486       show_msg(last_inbuf);
4487     DEBUGLEVEL = oldlevel;
4488     DEBUG(0,("===============================================================\n"));
4489 #if DUMP_CORE
4490     if (dump_core()) return;
4491 #endif
4492   }    
4493
4494   locking_end();
4495
4496   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4497   exit(0);
4498 }
4499
4500 /****************************************************************************
4501 do some standard substitutions in a string
4502 ****************************************************************************/
4503 void standard_sub(int cnum,char *str)
4504 {
4505   if (VALID_CNUM(cnum)) {
4506     char *p, *s, *home;
4507
4508     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4509       switch (*(p+1)) {
4510         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4511                      string_sub(p,"%H",home);
4512                    else
4513                      p += 2;
4514                    break;
4515         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4516         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4517         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4518         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4519         case '\0' : p++; break; /* don't run off the end of the string */
4520         default  : p+=2; break;
4521       }
4522     }
4523   }
4524   standard_sub_basic(str);
4525 }
4526
4527 /*
4528 These flags determine some of the permissions required to do an operation 
4529
4530 Note that I don't set NEED_WRITE on some write operations because they
4531 are used by some brain-dead clients when printing, and I don't want to
4532 force write permissions on print services.
4533 */
4534 #define AS_USER (1<<0)
4535 #define NEED_WRITE (1<<1)
4536 #define TIME_INIT (1<<2)
4537 #define CAN_IPC (1<<3)
4538 #define AS_GUEST (1<<5)
4539 #define QUEUE_IN_OPLOCK (1<<6)
4540
4541 /* 
4542    define a list of possible SMB messages and their corresponding
4543    functions. Any message that has a NULL function is unimplemented -
4544    please feel free to contribute implementations!
4545 */
4546 struct smb_message_struct
4547 {
4548   int code;
4549   char *name;
4550   int (*fn)();
4551   int flags;
4552 #if PROFILING
4553   unsigned long time;
4554 #endif
4555 }
4556  smb_messages[] = {
4557
4558     /* CORE PROTOCOL */
4559
4560    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4561    {SMBtcon,"SMBtcon",reply_tcon,0},
4562    {SMBtdis,"SMBtdis",reply_tdis,0},
4563    {SMBexit,"SMBexit",reply_exit,0},
4564    {SMBioctl,"SMBioctl",reply_ioctl,0},
4565    {SMBecho,"SMBecho",reply_echo,0},
4566    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4567    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4568    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4569    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4570    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4571    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4572    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4573    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4574
4575    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4576    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4577    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4578
4579    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4580    {SMBread,"SMBread",reply_read,AS_USER},
4581    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4582    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4583    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4584    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4585    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4586    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4587
4588    /* this is a Pathworks specific call, allowing the 
4589       changing of the root path */
4590    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4591
4592    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4593    {SMBflush,"SMBflush",reply_flush,AS_USER},
4594    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4595    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4596    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4597    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4598    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4599    {SMBlock,"SMBlock",reply_lock,AS_USER},
4600    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4601    
4602    /* CORE+ PROTOCOL FOLLOWS */
4603    
4604    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4605    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4606    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4607    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4608    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4609    
4610    /* LANMAN1.0 PROTOCOL FOLLOWS */
4611    
4612    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4613    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4614    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4615    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4616    {SMBwritec,"SMBwritec",NULL,AS_USER},
4617    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4618    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4619    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4620    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4621    {SMBioctls,"SMBioctls",NULL,AS_USER},
4622    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4623    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4624    
4625    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4626    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4627    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4628    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4629    
4630    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4631    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4632    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4633
4634    /* LANMAN2.0 PROTOCOL FOLLOWS */
4635    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4636    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4637    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK },
4638    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4639
4640    /* messaging routines */
4641    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4642    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4643    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4644    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4645
4646    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4647    
4648    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4649    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4650    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4651    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4652  };
4653
4654 /****************************************************************************
4655 return a string containing the function name of a SMB command
4656 ****************************************************************************/
4657 char *smb_fn_name(int type)
4658 {
4659   static char *unknown_name = "SMBunknown";
4660   static int num_smb_messages = 
4661     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4662   int match;
4663
4664   for (match=0;match<num_smb_messages;match++)
4665     if (smb_messages[match].code == type)
4666       break;
4667
4668   if (match == num_smb_messages)
4669     return(unknown_name);
4670
4671   return(smb_messages[match].name);
4672 }
4673
4674
4675 /****************************************************************************
4676 do a switch on the message type, and return the response size
4677 ****************************************************************************/
4678 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4679 {
4680   static int pid= -1;
4681   int outsize = 0;
4682   static int num_smb_messages = 
4683     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4684   int match;
4685
4686 #if PROFILING
4687   struct timeval msg_start_time;
4688   struct timeval msg_end_time;
4689   static unsigned long total_time = 0;
4690
4691   GetTimeOfDay(&msg_start_time);
4692 #endif
4693
4694   if (pid == -1)
4695     pid = getpid();
4696
4697   errno = 0;
4698   last_message = type;
4699
4700   /* make sure this is an SMB packet */
4701   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4702     {
4703       DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4704       return(-1);
4705     }
4706
4707   for (match=0;match<num_smb_messages;match++)
4708     if (smb_messages[match].code == type)
4709       break;
4710
4711   if (match == num_smb_messages)
4712     {
4713       DEBUG(0,("Unknown message type %d!\n",type));
4714       outsize = reply_unknown(inbuf,outbuf);
4715     }
4716   else
4717     {
4718       DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4719
4720       if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4721       {
4722         /* 
4723          * Queue this message as we are the process of an oplock break.
4724          */
4725
4726         DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4727                timestring() ));
4728
4729         push_smb_message( inbuf, size);
4730         return -1;
4731       }          
4732
4733       if (smb_messages[match].fn)
4734         {
4735           int cnum = SVAL(inbuf,smb_tid);
4736           int flags = smb_messages[match].flags;
4737           /* In share mode security we must ignore the vuid. */
4738           uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4739           /* Ensure this value is replaced in the incoming packet. */
4740           SSVAL(inbuf,smb_uid,session_tag);
4741
4742           /* does this protocol need to be run as root? */
4743           if (!(flags & AS_USER))
4744             unbecome_user();
4745
4746           /* does this protocol need to be run as the connected user? */
4747           if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4748             if (flags & AS_GUEST) 
4749               flags &= ~AS_USER;
4750             else
4751               return(ERROR(ERRSRV,ERRinvnid));
4752           }
4753           /* this code is to work around a bug is MS client 3 without
4754              introducing a security hole - it needs to be able to do
4755              print queue checks as guest if it isn't logged in properly */
4756           if (flags & AS_USER)
4757             flags &= ~AS_GUEST;
4758
4759           /* does it need write permission? */
4760           if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4761             return(ERROR(ERRSRV,ERRaccess));
4762
4763           /* ipc services are limited */
4764           if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4765             return(ERROR(ERRSRV,ERRaccess));        
4766
4767           /* load service specific parameters */
4768           if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4769             return(ERROR(ERRSRV,ERRaccess));
4770
4771           /* does this protocol need to be run as guest? */
4772           if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4773             return(ERROR(ERRSRV,ERRaccess));
4774
4775           last_inbuf = inbuf;
4776
4777           outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4778         }
4779       else
4780         {
4781           outsize = reply_unknown(inbuf,outbuf);
4782         }
4783     }
4784
4785 #if PROFILING
4786   GetTimeOfDay(&msg_end_time);
4787   if (!(smb_messages[match].flags & TIME_INIT))
4788     {
4789       smb_messages[match].time = 0;
4790       smb_messages[match].flags |= TIME_INIT;
4791     }
4792   {
4793     unsigned long this_time =     
4794       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4795         (msg_end_time.tv_usec - msg_start_time.tv_usec);
4796     smb_messages[match].time += this_time;
4797     total_time += this_time;
4798   }
4799   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4800            smb_fn_name(type),smb_messages[match].time,
4801         (100.0*smb_messages[match].time) / total_time));
4802 #endif
4803
4804   return(outsize);
4805 }
4806
4807
4808 /****************************************************************************
4809   construct a chained reply and add it to the already made reply
4810   **************************************************************************/
4811 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4812 {
4813   static char *orig_inbuf;
4814   static char *orig_outbuf;
4815   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4816   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4817   char *inbuf2, *outbuf2;
4818   int outsize2;
4819   char inbuf_saved[smb_wct];
4820   char outbuf_saved[smb_wct];
4821   extern int chain_size;
4822   int wct = CVAL(outbuf,smb_wct);
4823   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4824
4825   /* maybe its not chained */
4826   if (smb_com2 == 0xFF) {
4827     CVAL(outbuf,smb_vwv0) = 0xFF;
4828     return outsize;
4829   }
4830
4831   if (chain_size == 0) {
4832     /* this is the first part of the chain */
4833     orig_inbuf = inbuf;
4834     orig_outbuf = outbuf;
4835   }
4836
4837   /* we need to tell the client where the next part of the reply will be */
4838   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4839   CVAL(outbuf,smb_vwv0) = smb_com2;
4840
4841   /* remember how much the caller added to the chain, only counting stuff
4842      after the parameter words */
4843   chain_size += outsize - smb_wct;
4844
4845   /* work out pointers into the original packets. The
4846      headers on these need to be filled in */
4847   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4848   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4849
4850   /* remember the original command type */
4851   smb_com1 = CVAL(orig_inbuf,smb_com);
4852
4853   /* save the data which will be overwritten by the new headers */
4854   memcpy(inbuf_saved,inbuf2,smb_wct);
4855   memcpy(outbuf_saved,outbuf2,smb_wct);
4856
4857   /* give the new packet the same header as the last part of the SMB */
4858   memmove(inbuf2,inbuf,smb_wct);
4859
4860   /* create the in buffer */
4861   CVAL(inbuf2,smb_com) = smb_com2;
4862
4863   /* create the out buffer */
4864   bzero(outbuf2,smb_size);
4865   set_message(outbuf2,0,0,True);
4866   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4867   
4868   memcpy(outbuf2+4,inbuf2+4,4);
4869   CVAL(outbuf2,smb_rcls) = SUCCESS;
4870   CVAL(outbuf2,smb_reh) = 0;
4871   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4872                                                                   means a reply */
4873   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4874   SSVAL(outbuf2,smb_err,SUCCESS);
4875   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4876   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4877   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4878   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4879
4880   DEBUG(3,("Chained message\n"));
4881   show_msg(inbuf2);
4882
4883   /* process the request */
4884   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4885                             bufsize-chain_size);
4886
4887   /* copy the new reply and request headers over the old ones, but
4888      preserve the smb_com field */
4889   memmove(orig_outbuf,outbuf2,smb_wct);
4890   CVAL(orig_outbuf,smb_com) = smb_com1;
4891
4892   /* restore the saved data, being careful not to overwrite any
4893    data from the reply header */
4894   memcpy(inbuf2,inbuf_saved,smb_wct);
4895   {
4896     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4897     if (ofs < 0) ofs = 0;
4898     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4899   }
4900
4901   return outsize2;
4902 }
4903
4904
4905
4906 /****************************************************************************
4907   construct a reply to the incoming packet
4908 ****************************************************************************/
4909 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4910 {
4911   int type = CVAL(inbuf,smb_com);
4912   int outsize = 0;
4913   int msg_type = CVAL(inbuf,0);
4914   extern int chain_size;
4915
4916   smb_last_time = time(NULL);
4917
4918   chain_size = 0;
4919   chain_fnum = -1;
4920   reset_chain_pnum();
4921
4922   bzero(outbuf,smb_size);
4923
4924   if (msg_type != 0)
4925     return(reply_special(inbuf,outbuf));  
4926
4927   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4928   set_message(outbuf,0,0,True);
4929   
4930   memcpy(outbuf+4,inbuf+4,4);
4931   CVAL(outbuf,smb_rcls) = SUCCESS;
4932   CVAL(outbuf,smb_reh) = 0;
4933   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4934                                                              means a reply */
4935   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4936   SSVAL(outbuf,smb_err,SUCCESS);
4937   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4938   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4939   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4940   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4941
4942   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4943
4944   outsize += chain_size;
4945
4946   if(outsize > 4)
4947     smb_setlen(outbuf,outsize - 4);
4948   return(outsize);
4949 }
4950
4951 /****************************************************************************
4952   process commands from the client
4953 ****************************************************************************/
4954 static void process(void)
4955 {
4956   extern int Client;
4957
4958   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4959   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4960   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
4961     return;
4962
4963   InBuffer += SMB_ALIGNMENT;
4964   OutBuffer += SMB_ALIGNMENT;
4965
4966 #if PRIME_NMBD
4967   DEBUG(3,("priming nmbd\n"));
4968   {
4969     struct in_addr ip;
4970     ip = *interpret_addr2("localhost");
4971     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4972     *OutBuffer = 0;
4973     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4974   }
4975 #endif    
4976
4977   /* re-initialise the timezone */
4978   TimeInit();
4979
4980   while (True)
4981   {
4982     int deadtime = lp_deadtime()*60;
4983     int counter;
4984     int last_keepalive=0;
4985     int service_load_counter = 0;
4986     BOOL got_smb = False;
4987
4988     if (deadtime <= 0)
4989       deadtime = DEFAULT_SMBD_TIMEOUT;
4990
4991 #if USE_READ_PREDICTION
4992     if (lp_readprediction())
4993       do_read_prediction();
4994 #endif
4995
4996     errno = 0;      
4997
4998     for (counter=SMBD_SELECT_LOOP; 
4999           !receive_message_or_smb(Client,oplock_sock,
5000                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
5001           counter += SMBD_SELECT_LOOP)
5002     {
5003       int i;
5004       time_t t;
5005       BOOL allidle = True;
5006       extern int keepalive;
5007
5008       if (counter > 365 * 3600) /* big number of seconds. */
5009       {
5010         counter = 0;
5011         service_load_counter = 0;
5012       }
5013
5014       if (smb_read_error == READ_EOF) 
5015       {
5016         DEBUG(3,("end of file from client\n"));
5017         return;
5018       }
5019
5020       if (smb_read_error == READ_ERROR) 
5021       {
5022         DEBUG(3,("receive_smb error (%s) exiting\n",
5023                   strerror(errno)));
5024         return;
5025       }
5026
5027       t = time(NULL);
5028
5029       /* become root again if waiting */
5030       unbecome_user();
5031
5032       /* check for smb.conf reload */
5033       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
5034       {
5035         service_load_counter = counter;
5036
5037         /* reload services, if files have changed. */
5038         reload_services(True);
5039       }
5040
5041       /* automatic timeout if all connections are closed */      
5042       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
5043       {
5044         DEBUG(2,("%s Closing idle connection\n",timestring()));
5045         return;
5046       }
5047
5048       if (keepalive && (counter-last_keepalive)>keepalive) 
5049       {
5050               struct cli_state *cli = server_client();
5051               if (!send_keepalive(Client)) { 
5052                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5053                       return;
5054               }     
5055               /* also send a keepalive to the password server if its still
5056                  connected */
5057               if (cli && cli->initialised)
5058                       send_keepalive(cli->fd);
5059               last_keepalive = counter;
5060       }
5061
5062       /* check for connection timeouts */
5063       for (i=0;i<MAX_CONNECTIONS;i++)
5064         if (Connections[i].open)
5065         {
5066           /* close dirptrs on connections that are idle */
5067           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5068             dptr_idlecnum(i);
5069
5070           if (Connections[i].num_files_open > 0 ||
5071                      (t-Connections[i].lastused)<deadtime)
5072             allidle = False;
5073         }
5074
5075       if (allidle && num_connections_open>0) 
5076       {
5077         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5078         return;
5079       }
5080     }
5081
5082     if(got_smb)
5083       process_smb(InBuffer, OutBuffer);
5084     else
5085       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5086   }
5087 }
5088
5089
5090 /****************************************************************************
5091   initialise connect, service and file structs
5092 ****************************************************************************/
5093 static void init_structs(void )
5094 {
5095   int i;
5096   get_myname(myhostname,NULL);
5097
5098   for (i=0;i<MAX_CONNECTIONS;i++)
5099     {
5100       Connections[i].open = False;
5101       Connections[i].num_files_open=0;
5102       Connections[i].lastused=0;
5103       Connections[i].used=False;
5104       string_init(&Connections[i].user,"");
5105       string_init(&Connections[i].dirpath,"");
5106       string_init(&Connections[i].connectpath,"");
5107       string_init(&Connections[i].origpath,"");
5108     }
5109
5110   for (i=0;i<MAX_OPEN_FILES;i++)
5111     {
5112       Files[i].open = False;
5113       string_init(&Files[i].name,"");
5114
5115     }
5116
5117   for (i=0;i<MAX_OPEN_FILES;i++)
5118     {
5119       file_fd_struct *fd_ptr = &FileFd[i];
5120       fd_ptr->ref_count = 0;
5121       fd_ptr->dev = (int32)-1;
5122       fd_ptr->inode = (int32)-1;
5123       fd_ptr->fd = -1;
5124       fd_ptr->fd_readonly = -1;
5125       fd_ptr->fd_writeonly = -1;
5126       fd_ptr->real_open_flags = -1;
5127     }
5128
5129   /* for RPC pipes */
5130   init_rpc_pipe_hnd();
5131
5132 #ifdef NTDOMAIN
5133   /* for LSA handles */
5134   init_lsa_policy_hnd();
5135 #endif
5136
5137   init_dptrs();
5138 }
5139
5140 /****************************************************************************
5141 usage on the program
5142 ****************************************************************************/
5143 static void usage(char *pname)
5144 {
5145   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5146
5147   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5148   printf("Version %s\n",VERSION);
5149   printf("\t-D                    become a daemon\n");
5150   printf("\t-p port               listen on the specified port\n");
5151   printf("\t-d debuglevel         set the debuglevel\n");
5152   printf("\t-l log basename.      Basename for log/debug files\n");
5153   printf("\t-s services file.     Filename of services file\n");
5154   printf("\t-P                    passive only\n");
5155   printf("\t-a                    overwrite log file, don't append\n");
5156   printf("\n");
5157 }
5158
5159
5160 /****************************************************************************
5161   main program
5162 ****************************************************************************/
5163  int main(int argc,char *argv[])
5164 {
5165   extern BOOL append_log;
5166   /* shall I run as a daemon */
5167   BOOL is_daemon = False;
5168   int port = SMB_PORT;
5169   int opt;
5170   extern char *optarg;
5171   char pidFile[100];
5172
5173   *pidFile = '\0';
5174
5175 #ifdef NEED_AUTH_PARAMETERS
5176   set_auth_parameters(argc,argv);
5177 #endif
5178
5179 #ifdef SecureWare
5180   setluid(0);
5181 #endif
5182
5183   append_log = True;
5184
5185   TimeInit();
5186
5187   strcpy(debugf,SMBLOGFILE);  
5188
5189   setup_logging(argv[0],False);
5190
5191   charset_initialise();
5192
5193   /* make absolutely sure we run as root - to handle cases where people
5194      are crazy enough to have it setuid */
5195 #ifdef USE_SETRES
5196   setresuid(0,0,0);
5197 #else
5198   setuid(0);
5199   seteuid(0);
5200   setuid(0);
5201   seteuid(0);
5202 #endif
5203
5204   fault_setup(exit_server);
5205   signal(SIGTERM , SIGNAL_CAST dflt_sig);
5206
5207   /* we want total control over the permissions on created files,
5208      so set our umask to 0 */
5209   umask(0);
5210
5211   GetWd(OriginalDir);
5212
5213   init_uid();
5214
5215   /* this is for people who can't start the program correctly */
5216   while (argc > 1 && (*argv[1] != '-'))
5217     {
5218       argv++;
5219       argc--;
5220     }
5221
5222   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5223     switch (opt)
5224       {
5225       case 'f':
5226         strncpy(pidFile, optarg, sizeof(pidFile));
5227         break;
5228       case 'O':
5229         strcpy(user_socket_options,optarg);
5230         break;
5231       case 'i':
5232         strcpy(scope,optarg);
5233         break;
5234       case 'P':
5235         {
5236           extern BOOL passive;
5237           passive = True;
5238         }
5239         break;  
5240       case 's':
5241         strcpy(servicesf,optarg);
5242         break;
5243       case 'l':
5244         strcpy(debugf,optarg);
5245         break;
5246       case 'a':
5247         {
5248           extern BOOL append_log;
5249           append_log = !append_log;
5250         }
5251         break;
5252       case 'D':
5253         is_daemon = True;
5254         break;
5255       case 'd':
5256         if (*optarg == 'A')
5257           DEBUGLEVEL = 10000;
5258         else
5259           DEBUGLEVEL = atoi(optarg);
5260         break;
5261       case 'p':
5262         port = atoi(optarg);
5263         break;
5264       case 'h':
5265         usage(argv[0]);
5266         exit(0);
5267         break;
5268       default:
5269         usage(argv[0]);
5270         exit(1);
5271       }
5272
5273   reopen_logs();
5274
5275   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5276   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5277
5278 #ifndef NO_GETRLIMIT
5279 #ifdef RLIMIT_NOFILE
5280   {
5281     struct rlimit rlp;
5282     getrlimit(RLIMIT_NOFILE, &rlp);
5283     rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5284     setrlimit(RLIMIT_NOFILE, &rlp);
5285     getrlimit(RLIMIT_NOFILE, &rlp);
5286     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5287   }
5288 #endif
5289 #endif
5290
5291   
5292   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5293         getuid(),getgid(),geteuid(),getegid()));
5294
5295   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5296     {
5297       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5298       exit(1);
5299     }
5300
5301   init_structs();
5302
5303   if (!reload_services(False))
5304     return(-1); 
5305
5306   codepage_initialise(lp_client_code_page());
5307
5308   strcpy(myworkgroup, lp_workgroup());
5309
5310 #ifndef NO_SIGNAL_TEST
5311   signal(SIGHUP,SIGNAL_CAST sig_hup);
5312 #endif
5313
5314   /* Setup the signals that allow the debug log level
5315      to by dynamically changed. */
5316  
5317 #if defined(SIGUSR1)
5318   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5319 #endif /* SIGUSR1 */
5320    
5321 #if defined(SIGUSR2)
5322   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5323 #endif /* SIGUSR2 */
5324
5325   DEBUG(3,("%s loaded services\n",timestring()));
5326
5327   if (!is_daemon && !is_a_socket(0))
5328     {
5329       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5330       is_daemon = True;
5331     }
5332
5333   if (is_daemon)
5334     {
5335       DEBUG(3,("%s becoming a daemon\n",timestring()));
5336       become_daemon();
5337     }
5338
5339   if (!directory_exist(lp_lockdir(), NULL)) {
5340           mkdir(lp_lockdir(), 0755);
5341   }
5342
5343   if (*pidFile)
5344     {
5345       int     fd;
5346       char    buf[20];
5347
5348       if ((fd = open(pidFile,
5349 #ifdef O_NONBLOCK
5350          O_NONBLOCK | 
5351 #endif
5352          O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5353         {
5354            DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5355            exit(1);
5356         }
5357       if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5358         {
5359           DEBUG(0,("ERROR: smbd is already running\n"));
5360           exit(1);
5361         }
5362       sprintf(buf, "%u\n", (unsigned int) getpid());
5363       if (write(fd, buf, strlen(buf)) < 0)
5364         {
5365           DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5366           exit(1);
5367         }
5368       /* Leave pid file open & locked for the duration... */
5369     }
5370
5371   if (!open_sockets(is_daemon,port))
5372     exit(1);
5373
5374   if (!locking_init(0))
5375     exit(1);
5376
5377   /* possibly reload the services file. */
5378   reload_services(True);
5379
5380   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5381
5382   if (*lp_rootdir())
5383     {
5384       if (sys_chroot(lp_rootdir()) == 0)
5385         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5386     }
5387
5388   /* Setup the oplock IPC socket. */
5389   if(!open_oplock_ipc())
5390     exit(1);
5391
5392   process();
5393   close_sockets();
5394
5395   exit_server("normal exit");
5396   return(0);
5397 }
5398
5399