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