Modified Files:
[samba.git] / source3 / smbd / server.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Main SMB server routines
5    Copyright (C) Andrew Tridgell 1992-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "trans2.h"
24
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
29
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
33
34 int am_parent = 1;
35 int atexit_set = 0;
36
37 /* the last message the was processed */
38 int last_message = -1;
39
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
42
43 extern pstring scope;
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 time_t smb_last_time=(time_t)0;
52
53 extern int smb_read_error;
54
55 extern pstring user_socket_options;
56
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
59
60 /*
61  * Indirection for file fd's. Needed as POSIX locking
62  * is based on file/process, not fd/process.
63  */
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
66
67 extern int Protocol;
68
69 /* 
70  * Size of data we can send to client. Set
71  *  by the client for all protocols above CORE.
72  *  Set by us for CORE protocol.
73  */
74 int max_send = BUFFER_SIZE;
75 /*
76  * Size of the data we can receive. Set by us.
77  * Can be modified by the max xmit parameter.
78  */
79 int max_recv = BUFFER_SIZE;
80
81 /* a fnum to use when chaining */
82 int chain_fnum = -1;
83
84 /* number of open connections */
85 static int num_connections_open = 0;
86
87 /* Oplock ipc UDP socket. */
88 int oplock_sock = -1;
89 uint16 oplock_port = 0;
90 /* Current number of oplocks we have outstanding. */
91 int32 global_oplocks_open = 0;
92
93 BOOL global_oplock_break = False;
94
95 extern fstring remote_machine;
96
97 extern pstring OriginalDir;
98
99 /* these can be set by some functions to override the error codes */
100 int unix_ERR_class=SUCCESS;
101 int unix_ERR_code=0;
102
103
104 extern int extra_time_offset;
105
106 extern pstring myhostname;
107
108 static int find_free_connection(int hash);
109
110 /* for readability... */
111 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
112 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
113 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
114 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
115 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
116
117 /****************************************************************************
118   when exiting, take the whole family
119 ****************************************************************************/
120 void  *dflt_sig(void)
121 {
122   exit_server("caught signal");
123   return 0; /* Keep -Wall happy :-) */
124 }
125 /****************************************************************************
126   Send a SIGTERM to our process group.
127 *****************************************************************************/
128 void  killkids(void)
129 {
130   if(am_parent) kill(0,SIGTERM);
131 }
132
133 /****************************************************************************
134   change a dos mode to a unix mode
135     base permission for files:
136          everybody gets read bit set
137          dos readonly is represented in unix by removing everyone's write bit
138          dos archive is represented in unix by the user's execute bit
139          dos system is represented in unix by the group's execute bit
140          dos hidden is represented in unix by the other's execute bit
141          Then apply create mask,
142          then add force bits.
143     base permission for directories:
144          dos directory is represented in unix by unix's dir bit and the exec bit
145          Then apply create mask,
146          then add force bits.
147 ****************************************************************************/
148 mode_t unix_mode(int cnum,int dosmode)
149 {
150   mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
151
152   if ( !IS_DOS_READONLY(dosmode) )
153     result |= (S_IWUSR | S_IWGRP | S_IWOTH);
154  
155   if (IS_DOS_DIR(dosmode)) {
156     /* We never make directories read only for the owner as under DOS a user
157        can always create a file in a read-only directory. */
158     result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
159     /* Apply directory mask */
160     result &= lp_dir_mode(SNUM(cnum));
161     /* Add in force bits */
162     result |= lp_force_dir_mode(SNUM(cnum));
163   } else { 
164     if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
165       result |= S_IXUSR;
166
167     if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
168       result |= S_IXGRP;
169  
170     if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
171       result |= S_IXOTH;  
172  
173     /* Apply mode mask */
174     result &= lp_create_mode(SNUM(cnum));
175     /* Add in force bits */
176     result |= lp_force_create_mode(SNUM(cnum));
177   }
178   return(result);
179 }
180
181
182 /****************************************************************************
183   change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
186 {
187   int result = 0;
188   extern struct current_user current_user;
189
190   DEBUG(8,("dos_mode: %d %s\n", cnum, path));
191
192   if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
193     if (!((sbuf->st_mode & S_IWOTH) ||
194           Connections[cnum].admin_user ||
195           ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
196           ((sbuf->st_mode & S_IWGRP) && 
197            in_group(sbuf->st_gid,current_user.gid,
198                     current_user.ngroups,current_user.igroups))))
199       result |= aRONLY;
200   } else {
201     if ((sbuf->st_mode & S_IWUSR) == 0)
202       result |= aRONLY;
203   }
204
205   if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
206     result |= aARCH;
207
208   if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
209     result |= aSYSTEM;
210
211   if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
212     result |= aHIDDEN;   
213   
214   if (S_ISDIR(sbuf->st_mode))
215     result = aDIR | (result & aRONLY);
216
217 #ifdef S_ISLNK
218 #if LINKS_READ_ONLY
219   if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
220     result |= aRONLY;
221 #endif
222 #endif
223
224   /* hide files with a name starting with a . */
225   if (lp_hide_dot_files(SNUM(cnum)))
226     {
227       char *p = strrchr(path,'/');
228       if (p)
229         p++;
230       else
231         p = path;
232       
233       if (p[0] == '.' && p[1] != '.' && p[1] != 0)
234         result |= aHIDDEN;
235     }
236
237   /* Optimization : Only call is_hidden_path if it's not already
238      hidden. */
239   if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
240   {
241     result |= aHIDDEN;
242   }
243
244   DEBUG(8,("dos_mode returning "));
245
246   if (result & aHIDDEN) DEBUG(8, ("h"));
247   if (result & aRONLY ) DEBUG(8, ("r"));
248   if (result & aSYSTEM) DEBUG(8, ("s"));
249   if (result & aDIR   ) DEBUG(8, ("d"));
250   if (result & aARCH  ) DEBUG(8, ("a"));
251
252   DEBUG(8,("\n"));
253
254   return(result);
255 }
256
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
261 {
262   struct stat st1;
263   int mask=0;
264   int tmp;
265   int unixmode;
266
267   if (!st) {
268     st = &st1;
269     if (sys_stat(fname,st)) return(-1);
270   }
271
272   if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
273
274   if (dos_mode(cnum,fname,st) == dosmode) return(0);
275
276   unixmode = unix_mode(cnum,dosmode);
277
278   /* preserve the s bits */
279   mask |= (S_ISUID | S_ISGID);
280
281   /* preserve the t bit */
282 #ifdef S_ISVTX
283   mask |= S_ISVTX;
284 #endif
285
286   /* possibly preserve the x bits */
287   if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
288   if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
289   if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
290
291   unixmode |= (st->st_mode & mask);
292
293   /* if we previously had any r bits set then leave them alone */
294   if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
295     unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
296     unixmode |= tmp;
297   }
298
299   /* if we previously had any w bits set then leave them alone 
300    if the new mode is not rdonly */
301   if (!IS_DOS_READONLY(dosmode) &&
302       (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
303     unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
304     unixmode |= tmp;
305   }
306
307   return(sys_chmod(fname,unixmode));
308 }
309
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
312 than POSIX.
313 *******************************************************************/
314
315 int file_utime(int cnum, char *fname, struct utimbuf *times)
316 {
317   extern struct current_user current_user;
318   struct stat sb;
319   int ret = -1;
320
321   errno = 0;
322
323   if(sys_utime(fname, times) == 0)
324     return 0;
325
326   if((errno != EPERM) && (errno != EACCES))
327     return -1;
328
329   if(!lp_dos_filetimes(SNUM(cnum)))
330     return -1;
331
332   /* We have permission (given by the Samba admin) to
333      break POSIX semantics and allow a user to change
334      the time on a file they don't own but can write to
335      (as DOS does).
336    */
337
338   if(sys_stat(fname,&sb) != 0)
339     return -1;
340
341   /* Check if we have write access. */
342   if (CAN_WRITE(cnum)) {
343           if (((sb.st_mode & S_IWOTH) ||
344                Connections[cnum].admin_user ||
345                ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
346                ((sb.st_mode & S_IWGRP) &&
347                 in_group(sb.st_gid,current_user.gid,
348                          current_user.ngroups,current_user.igroups)))) {
349                   /* We are allowed to become root and change the filetime. */
350                   become_root(False);
351                   ret = sys_utime(fname, times);
352                   unbecome_root(False);
353           }
354   }
355
356   return ret;
357 }
358   
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
362
363 BOOL set_filetime(int cnum, char *fname, time_t mtime)
364 {
365   struct utimbuf times;
366
367   if (null_mtime(mtime)) return(True);
368
369   times.modtime = times.actime = mtime;
370
371   if (file_utime(cnum, fname, &times)) {
372     DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
373   }
374   
375   return(True);
376
377
378 /****************************************************************************
379 check if two filenames are equal
380
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL fname_equal(char *name1, char *name2)
384 {
385   int l1 = strlen(name1);
386   int l2 = strlen(name2);
387
388   /* handle filenames ending in a single dot */
389   if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
390     {
391       BOOL ret;
392       name1[l1-1] = 0;
393       ret = fname_equal(name1,name2);
394       name1[l1-1] = '.';
395       return(ret);
396     }
397
398   if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
399     {
400       BOOL ret;
401       name2[l2-1] = 0;
402       ret = fname_equal(name1,name2);
403       name2[l2-1] = '.';
404       return(ret);
405     }
406
407   /* now normal filename handling */
408   if (case_sensitive)
409     return(strcmp(name1,name2) == 0);
410
411   return(strequal(name1,name2));
412 }
413
414
415 /****************************************************************************
416 mangle the 2nd name and check if it is then equal to the first name
417 ****************************************************************************/
418 static BOOL mangled_equal(char *name1, char *name2)
419 {
420   pstring tmpname;
421
422   if (is_8_3(name2, True))
423     return(False);
424
425   strcpy(tmpname,name2);
426   mangle_name_83(tmpname);
427
428   return(strequal(name1,tmpname));
429 }
430
431
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
434
435 If the name looks like a mangled name then try via the mangling functions
436 ****************************************************************************/
437 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
438 {
439   void *cur_dir;
440   char *dname;
441   BOOL mangled;
442   pstring name2;
443
444   mangled = is_mangled(name);
445
446   /* handle null paths */
447   if (*path == 0)
448     path = ".";
449
450   if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
451     strcpy(name, dname);        
452     return(True);
453   }      
454
455   if (mangled)
456     check_mangled_stack(name);
457
458   /* open the directory */
459   if (!(cur_dir = OpenDir(cnum, path, True))) 
460     {
461       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
462       return(False);
463     }
464
465   /* now scan for matching names */
466   while ((dname = ReadDirName(cur_dir))) 
467     {
468       if (*dname == '.' &&
469           (strequal(dname,".") || strequal(dname,"..")))
470         continue;
471
472       pstrcpy(name2,dname);
473       if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
474
475       if ((mangled && mangled_equal(name,name2))
476           || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
477         {
478           /* we've found the file, change it's name and return */
479           if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
480           strcpy(name, dname);
481           CloseDir(cur_dir);
482           return(True);
483         }
484     }
485
486   CloseDir(cur_dir);
487   return(False);
488 }
489
490 /****************************************************************************
491 This routine is called to convert names from the dos namespace to unix
492 namespace. It needs to handle any case conversions, mangling, format
493 changes etc.
494
495 We assume that we have already done a chdir() to the right "root" directory
496 for this service.
497
498 The function will return False if some part of the name except for the last
499 part cannot be resolved
500
501 If the saved_last_component != 0, then the unmodified last component
502 of the pathname is returned there. This is used in an exceptional
503 case in reply_mv (so far). If saved_last_component == 0 then nothing
504 is returned there.
505
506 The bad_path arg is set to True if the filename walk failed. This is
507 used to pick the correct error code to return between ENOENT and ENOTDIR
508 as Windows applications depend on ERRbadpath being returned if a component
509 of a pathname does not exist.
510 ****************************************************************************/
511 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
512 {
513   struct stat st;
514   char *start, *end;
515   pstring dirpath;
516   int saved_errno;
517
518   *dirpath = 0;
519   *bad_path = False;
520
521   if(saved_last_component)
522     *saved_last_component = 0;
523
524   /* convert to basic unix format - removing \ chars and cleaning it up */
525   unix_format(name);
526   unix_clean_name(name);
527
528   /* names must be relative to the root of the service - trim any leading /.
529    also trim trailing /'s */
530   trim_string(name,"/","/");
531
532   /*
533    * Ensure saved_last_component is valid even if file exists.
534    */
535   if(saved_last_component) {
536     end = strrchr(name, '/');
537     if(end)
538       strcpy(saved_last_component, end + 1);
539     else
540       strcpy(saved_last_component, name);
541   }
542
543   if (!case_sensitive && 
544       (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
545     strnorm(name);
546
547   /* check if it's a printer file */
548   if (Connections[cnum].printer)
549     {
550       if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
551         {
552           char *s;
553           fstring name2;
554           sprintf(name2,"%.6s.XXXXXX",remote_machine);
555           /* sanitise the name */
556           for (s=name2 ; *s ; s++)
557             if (!issafe(*s)) *s = '_';
558           strcpy(name,(char *)mktemp(name2));     
559         }      
560       return(True);
561     }
562
563   /* stat the name - if it exists then we are all done! */
564   if (sys_stat(name,&st) == 0)
565     return(True);
566
567   saved_errno = errno;
568
569   DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
570
571   /* a special case - if we don't have any mangling chars and are case
572      sensitive then searching won't help */
573   if (case_sensitive && !is_mangled(name) && 
574       !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
575     return(False);
576
577   /* now we need to recursively match the name against the real 
578      directory structure */
579
580   start = name;
581   while (strncmp(start,"./",2) == 0)
582     start += 2;
583
584   /* now match each part of the path name separately, trying the names
585      as is first, then trying to scan the directory for matching names */
586   for (;start;start = (end?end+1:(char *)NULL)) 
587     {
588       /* pinpoint the end of this section of the filename */
589       end = strchr(start, '/');
590
591       /* chop the name at this point */
592       if (end)  *end = 0;
593
594       if(saved_last_component != 0)
595         strcpy(saved_last_component, end ? end + 1 : start);
596
597       /* check if the name exists up to this point */
598       if (sys_stat(name, &st) == 0) 
599         {
600           /* it exists. it must either be a directory or this must be
601              the last part of the path for it to be OK */
602           if (end && !(st.st_mode & S_IFDIR)) 
603             {
604               /* an intermediate part of the name isn't a directory */
605               DEBUG(5,("Not a dir %s\n",start));
606               *end = '/';
607               return(False);
608             }
609         }
610       else 
611         {
612           pstring rest;
613
614           *rest = 0;
615
616           /* remember the rest of the pathname so it can be restored
617              later */
618           if (end) pstrcpy(rest,end+1);
619
620           /* try to find this part of the path in the directory */
621           if (strchr(start,'?') || strchr(start,'*') ||
622               !scan_directory(dirpath, start, cnum, end?True:False))
623             {
624               if (end) 
625                 {
626                   /* an intermediate part of the name can't be found */
627                   DEBUG(5,("Intermediate not found %s\n",start));
628                   *end = '/';
629                   /* We need to return the fact that the intermediate
630                      name resolution failed. This is used to return an
631                      error of ERRbadpath rather than ERRbadfile. Some
632                      Windows applications depend on the difference between
633                      these two errors.
634                    */
635                   *bad_path = True;
636                   return(False);
637                 }
638               
639               /* just the last part of the name doesn't exist */
640               /* we may need to strupper() or strlower() it in case
641                  this conversion is being used for file creation 
642                  purposes */
643               /* if the filename is of mixed case then don't normalise it */
644               if (!case_preserve && 
645                   (!strhasupper(start) || !strhaslower(start)))         
646                 strnorm(start);
647
648               /* check on the mangled stack to see if we can recover the 
649                  base of the filename */
650               if (is_mangled(start))
651                 check_mangled_stack(start);
652
653               DEBUG(5,("New file %s\n",start));
654               return(True); 
655             }
656
657           /* restore the rest of the string */
658           if (end) 
659             {
660               strcpy(start+strlen(start)+1,rest);
661               end = start + strlen(start);
662             }
663         }
664
665       /* add to the dirpath that we have resolved so far */
666       if (*dirpath) strcat(dirpath,"/");
667       strcat(dirpath,start);
668
669       /* restore the / that we wiped out earlier */
670       if (end) *end = '/';
671     }
672   
673   /* the name has been resolved */
674   DEBUG(5,("conversion finished %s\n",name));
675   return(True);
676 }
677
678
679 /****************************************************************************
680 normalise for DOS usage 
681 ****************************************************************************/
682 static void disk_norm(int *bsize,int *dfree,int *dsize)
683 {
684   /* check if the disk is beyond the max disk size */
685   int maxdisksize = lp_maxdisksize();
686   if (maxdisksize) {
687     /* convert to blocks - and don't overflow */
688     maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
689     if (*dsize > maxdisksize) *dsize = maxdisksize;
690     if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop 
691                                                          applications getting 
692                                                          div by 0 errors */
693   }  
694
695   while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) 
696     {
697       *dfree /= 2;
698       *dsize /= 2;
699       *bsize *= 2;
700       if (*bsize > WORDMAX )
701         {
702           *bsize = WORDMAX;
703           if (*dsize > WORDMAX)
704             *dsize = WORDMAX;
705           if (*dfree >  WORDMAX)
706             *dfree = WORDMAX;
707           break;
708         }
709     }
710 }
711
712 /****************************************************************************
713   return number of 1K blocks available on a path and total number 
714 ****************************************************************************/
715 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
716 {
717   char *df_command = lp_dfree_command();
718   int dfree_retval;
719 #ifdef QUOTAS
720   int dfreeq_retval;
721   int dfreeq = 0;
722   int bsizeq = *bsize;
723   int dsizeq = *dsize;
724 #endif
725
726 #ifndef NO_STATFS
727 #ifdef USE_STATVFS
728   struct statvfs fs;
729 #else
730 #ifdef ULTRIX
731   struct fs_data fs;
732 #else
733   struct statfs fs;
734 #endif
735 #endif
736 #endif
737
738   /* possibly use system() to get the result */
739   if (df_command && *df_command)
740     {
741       int ret;
742       pstring syscmd;
743       pstring outfile;
744           
745       sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
746       sprintf(syscmd,"%s %s",df_command,path);
747       standard_sub_basic(syscmd);
748
749       ret = smbrun(syscmd,outfile,False);
750       DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
751           
752       {
753         FILE *f = fopen(outfile,"r");   
754         *dsize = 0;
755         *dfree = 0;
756         *bsize = 1024;
757         if (f)
758           {
759             fscanf(f,"%d %d %d",dsize,dfree,bsize);
760             fclose(f);
761           }
762         else
763           DEBUG(0,("Can't open %s\n",outfile));
764       }
765           
766       unlink(outfile);
767       disk_norm(bsize,dfree,dsize);
768       dfree_retval = ((*bsize)/1024)*(*dfree);
769 #ifdef QUOTAS
770       /* Ensure we return the min value between the users quota and
771          what's free on the disk. Thanks to Albrecht Gebhardt 
772          <albrecht.gebhardt@uni-klu.ac.at> for this fix.
773       */
774       if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
775         {
776           disk_norm(&bsizeq, &dfreeq, &dsizeq);
777           dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
778           dfree_retval =  ( dfree_retval < dfreeq_retval ) ? 
779                            dfree_retval : dfreeq_retval ;
780           /* maybe dfree and dfreeq are calculated using different bsizes 
781              so convert dfree from bsize into bsizeq */
782           /* avoid overflows due to multiplication, so do not:
783                 *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
784              bsize and bsizeq are powers of 2 so its better to
785              to divide them getting a multiplication or division factor
786              for dfree. Rene Nieuwenhuizen (07-10-1997) */
787           if (*bsize >= bsizeq) 
788             *dfree = *dfree * (*bsize / bsizeq);
789           else 
790             *dfree = *dfree / (bsizeq / *bsize);
791           *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; 
792           *bsize = bsizeq;
793           *dsize = dsizeq;
794         }
795 #endif
796       return(dfree_retval);
797     }
798
799 #ifdef NO_STATFS
800   DEBUG(1,("Warning - no statfs function\n"));
801   return(1);
802 #else
803 #ifdef STATFS4
804   if (statfs(path,&fs,sizeof(fs),0) != 0)
805 #else
806 #ifdef USE_STATVFS
807     if (statvfs(path, &fs))
808 #else
809 #ifdef STATFS3
810       if (statfs(path,&fs,sizeof(fs)) == -1)     
811 #else
812         if (statfs(path,&fs) == -1)
813 #endif /* STATFS3 */
814 #endif /* USE_STATVFS */
815 #endif /* STATFS4 */
816           {
817             DEBUG(3,("dfree call failed code errno=%d\n",errno));
818             *bsize = 1024;
819             *dfree = 1;
820             *dsize = 1;
821             return(((*bsize)/1024)*(*dfree));
822           }
823
824 #ifdef ULTRIX
825   *bsize = 1024;
826   *dfree = fs.fd_req.bfree;
827   *dsize = fs.fd_req.btot;
828 #else
829 #ifdef USE_STATVFS
830   *bsize = fs.f_frsize;
831 #else
832 #ifdef USE_F_FSIZE
833   /* eg: osf1 has f_fsize = fundamental filesystem block size, 
834      f_bsize = optimal transfer block size (MX: 94-04-19) */
835   *bsize = fs.f_fsize;
836 #else
837   *bsize = fs.f_bsize;
838 #endif /* STATFS3 */
839 #endif /* USE_STATVFS */
840
841 #ifdef STATFS4
842   *dfree = fs.f_bfree;
843 #else
844   *dfree = fs.f_bavail;
845 #endif /* STATFS4 */
846   *dsize = fs.f_blocks;
847 #endif /* ULTRIX */
848
849 #if defined(SCO) || defined(ISC) || defined(MIPS)
850   *bsize = 512;
851 #endif
852
853 /* handle rediculous bsize values - some OSes are broken */
854 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
855
856   disk_norm(bsize,dfree,dsize);
857
858   if (*bsize < 256)
859     *bsize = 512;
860   if ((*dsize)<1)
861     {
862       DEBUG(0,("dfree seems to be broken on your system\n"));
863       *dsize = 20*1024*1024/(*bsize);
864       *dfree = MAX(1,*dfree);
865     }
866   dfree_retval = ((*bsize)/1024)*(*dfree);
867 #ifdef QUOTAS
868   /* Ensure we return the min value between the users quota and
869      what's free on the disk. Thanks to Albrecht Gebhardt 
870      <albrecht.gebhardt@uni-klu.ac.at> for this fix.
871   */
872   if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
873     {
874       disk_norm(&bsizeq, &dfreeq, &dsizeq);
875       dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
876       dfree_retval = ( dfree_retval < dfreeq_retval ) ? 
877                        dfree_retval : dfreeq_retval ;
878       /* maybe dfree and dfreeq are calculated using different bsizes 
879          so convert dfree from bsize into bsizeq */
880       /* avoid overflows due to multiplication, so do not:
881               *dfree = ((*dfree) * (*bsize)) / (bsizeq); 
882        bsize and bsizeq are powers of 2 so its better to
883        to divide them getting a multiplication or division factor
884        for dfree. Rene Nieuwenhuizen (07-10-1997) */
885       if (*bsize >= bsizeq)
886         *dfree = *dfree * (*bsize / bsizeq);
887       else
888         *dfree = *dfree / (bsizeq / *bsize);
889       *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
890       *bsize = bsizeq;
891       *dsize = dsizeq;
892     }
893 #endif
894   return(dfree_retval);
895 #endif
896 }
897
898
899 /****************************************************************************
900 wrap it to get filenames right
901 ****************************************************************************/
902 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
903 {
904   return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
905 }
906
907
908
909 /****************************************************************************
910 check a filename - possibly caling reducename
911
912 This is called by every routine before it allows an operation on a filename.
913 It does any final confirmation necessary to ensure that the filename is
914 a valid one for the user to access.
915 ****************************************************************************/
916 BOOL check_name(char *name,int cnum)
917 {
918   BOOL ret;
919
920   errno = 0;
921
922   if( IS_VETO_PATH(cnum, name)) 
923     {
924       DEBUG(5,("file path name %s vetoed\n",name));
925       return(0);
926     }
927
928   ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
929
930   /* Check if we are allowing users to follow symlinks */
931   /* Patch from David Clerc <David.Clerc@cui.unige.ch>
932      University of Geneva */
933
934 #ifdef S_ISLNK
935   if (!lp_symlinks(SNUM(cnum)))
936     {
937       struct stat statbuf;
938       if ( (sys_lstat(name,&statbuf) != -1) &&
939           (S_ISLNK(statbuf.st_mode)) )
940         {
941           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
942           ret=0; 
943         }
944     }
945 #endif
946
947   if (!ret)
948     DEBUG(5,("check_name on %s failed\n",name));
949
950   return(ret);
951 }
952
953 /****************************************************************************
954 check a filename - possibly caling reducename
955 ****************************************************************************/
956 static void check_for_pipe(char *fname)
957 {
958   /* special case of pipe opens */
959   char s[10];
960   StrnCpy(s,fname,9);
961   strlower(s);
962   if (strstr(s,"pipe/"))
963     {
964       DEBUG(3,("Rejecting named pipe open for %s\n",fname));
965       unix_ERR_class = ERRSRV;
966       unix_ERR_code = ERRaccess;
967     }
968 }
969
970 /****************************************************************************
971 fd support routines - attempt to do a sys_open
972 ****************************************************************************/
973 static int fd_attempt_open(char *fname, int flags, int mode)
974 {
975   int fd = sys_open(fname,flags,mode);
976
977   /* Fix for files ending in '.' */
978   if((fd == -1) && (errno == ENOENT) &&
979      (strchr(fname,'.')==NULL))
980     {
981       strcat(fname,".");
982       fd = sys_open(fname,flags,mode);
983     }
984
985 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
986   if ((fd == -1) && (errno == ENAMETOOLONG))
987     {
988       int max_len;
989       char *p = strrchr(fname, '/');
990
991       if (p == fname)   /* name is "/xxx" */
992         {
993           max_len = pathconf("/", _PC_NAME_MAX);
994           p++;
995         }
996       else if ((p == NULL) || (p == fname))
997         {
998           p = fname;
999           max_len = pathconf(".", _PC_NAME_MAX);
1000         }
1001       else
1002         {
1003           *p = '\0';
1004           max_len = pathconf(fname, _PC_NAME_MAX);
1005           *p = '/';
1006           p++;
1007         }
1008       if (strlen(p) > max_len)
1009         {
1010           char tmp = p[max_len];
1011
1012           p[max_len] = '\0';
1013           if ((fd = sys_open(fname,flags,mode)) == -1)
1014             p[max_len] = tmp;
1015         }
1016     }
1017 #endif
1018   return fd;
1019 }
1020
1021 /****************************************************************************
1022 fd support routines - attempt to find an already open file by dev
1023 and inode - increments the ref_count of the returned file_fd_struct *.
1024 ****************************************************************************/
1025 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
1026 {
1027   int i;
1028   file_fd_struct *fd_ptr;
1029
1030   if(sbuf == 0)
1031     return 0;
1032
1033   for(i = 0; i <= max_file_fd_used; i++) {
1034     fd_ptr = &FileFd[i];
1035     if((fd_ptr->ref_count > 0) &&
1036        (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
1037        (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
1038       fd_ptr->ref_count++;
1039       DEBUG(3,
1040        ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1041         i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
1042       return fd_ptr;
1043     }
1044   }
1045   return 0;
1046 }
1047
1048 /****************************************************************************
1049 fd support routines - attempt to find a empty slot in the FileFd array.
1050 Increments the ref_count of the returned entry.
1051 ****************************************************************************/
1052 static file_fd_struct *fd_get_new()
1053 {
1054   int i;
1055   file_fd_struct *fd_ptr;
1056
1057   for(i = 0; i < MAX_OPEN_FILES; i++) {
1058     fd_ptr = &FileFd[i];
1059     if(fd_ptr->ref_count == 0) {
1060       fd_ptr->dev = (uint32)-1;
1061       fd_ptr->inode = (uint32)-1;
1062       fd_ptr->fd = -1;
1063       fd_ptr->fd_readonly = -1;
1064       fd_ptr->fd_writeonly = -1;
1065       fd_ptr->real_open_flags = -1;
1066       fd_ptr->ref_count++;
1067       /* Increment max used counter if neccessary, cuts down
1068          on search time when re-using */
1069       if(i > max_file_fd_used)
1070         max_file_fd_used = i;
1071       DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1072                i, fd_ptr->dev, fd_ptr->inode));
1073       return fd_ptr;
1074     }
1075   }
1076   DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1077 n"));
1078   return 0;
1079 }
1080
1081 /****************************************************************************
1082 fd support routines - attempt to re-open an already open fd as O_RDWR.
1083 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1084 ****************************************************************************/
1085 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
1086 {
1087   int fd = sys_open( fname, O_RDWR, mode);
1088
1089   if(fd == -1)
1090     return;
1091
1092   if(fd_ptr->real_open_flags == O_RDONLY)
1093     fd_ptr->fd_readonly = fd_ptr->fd;
1094   if(fd_ptr->real_open_flags == O_WRONLY)
1095     fd_ptr->fd_writeonly = fd_ptr->fd;
1096
1097   fd_ptr->fd = fd;
1098   fd_ptr->real_open_flags = O_RDWR;
1099 }
1100
1101 /****************************************************************************
1102 fd support routines - attempt to close the file referenced by this fd.
1103 Decrements the ref_count and returns it.
1104 ****************************************************************************/
1105 static int fd_attempt_close(file_fd_struct *fd_ptr)
1106 {
1107   DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1108            fd_ptr - &FileFd[0],
1109            fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
1110            fd_ptr->real_open_flags,
1111            fd_ptr->ref_count));
1112   if(fd_ptr->ref_count > 0) {
1113     fd_ptr->ref_count--;
1114     if(fd_ptr->ref_count == 0) {
1115       if(fd_ptr->fd != -1)
1116         close(fd_ptr->fd);
1117       if(fd_ptr->fd_readonly != -1)
1118         close(fd_ptr->fd_readonly);
1119       if(fd_ptr->fd_writeonly != -1)
1120         close(fd_ptr->fd_writeonly);
1121       fd_ptr->fd = -1;
1122       fd_ptr->fd_readonly = -1;
1123       fd_ptr->fd_writeonly = -1;
1124       fd_ptr->real_open_flags = -1;
1125       fd_ptr->dev = (uint32)-1;
1126       fd_ptr->inode = (uint32)-1;
1127     }
1128   } 
1129  return fd_ptr->ref_count;
1130 }
1131
1132 /****************************************************************************
1133 open a file
1134 ****************************************************************************/
1135 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1136 {
1137   extern struct current_user current_user;
1138   pstring fname;
1139   struct stat statbuf;
1140   file_fd_struct *fd_ptr;
1141   files_struct *fsp = &Files[fnum];
1142
1143   fsp->open = False;
1144   fsp->fd_ptr = 0;
1145   fsp->granted_oplock = False;
1146   errno = EPERM;
1147
1148   pstrcpy(fname,fname1);
1149
1150   /* check permissions */
1151   if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1152     {
1153       DEBUG(3,("Permission denied opening %s\n",fname));
1154       check_for_pipe(fname);
1155       return;
1156     }
1157
1158   /* this handles a bug in Win95 - it doesn't say to create the file when it 
1159      should */
1160   if (Connections[cnum].printer)
1161     flags |= O_CREAT;
1162
1163 /*
1164   if (flags == O_WRONLY)
1165     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1166 */
1167
1168   /*
1169    * Ensure we have a valid struct stat so we can search the
1170    * open fd table.
1171    */
1172   if(sbuf == 0) {
1173     if(stat(fname, &statbuf) < 0) {
1174       if(errno != ENOENT) {
1175         DEBUG(3,("Error doing stat on file %s (%s)\n",
1176                  fname,strerror(errno)));
1177
1178         check_for_pipe(fname);
1179         return;
1180       }
1181       sbuf = 0;
1182     } else {
1183       sbuf = &statbuf;
1184     }
1185   }
1186
1187   /*
1188    * Check to see if we have this file already
1189    * open. If we do, just use the already open fd and increment the
1190    * reference count (fd_get_already_open increments the ref_count).
1191    */
1192   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1193
1194     int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1195
1196     /* File was already open. */
1197     if((flags & O_CREAT) && (flags & O_EXCL)) {
1198       fd_ptr->ref_count--;
1199       errno = EEXIST;
1200       return;
1201     }
1202
1203     /* 
1204      * If not opened O_RDWR try
1205      * and do that here - a chmod may have been done
1206      * between the last open and now. 
1207      */
1208     if(fd_ptr->real_open_flags != O_RDWR)
1209       fd_attempt_reopen(fname, mode, fd_ptr);
1210
1211     /*
1212      * Ensure that if we wanted write access
1213      * it has been opened for write, and if we wanted read it
1214      * was open for read. 
1215      */
1216     if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1217        ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1218        ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1219       DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1220                fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1221       check_for_pipe(fname);
1222       fd_ptr->ref_count--;
1223       return;
1224     }
1225
1226   } else {
1227     int open_flags;
1228     /* We need to allocate a new file_fd_struct (this increments the
1229        ref_count). */
1230     if((fd_ptr = fd_get_new()) == 0)
1231       return;
1232     /*
1233      * Whatever the requested flags, attempt read/write access,
1234      * as we don't know what flags future file opens may require.
1235      * If this fails, try again with the required flags. 
1236      * Even if we open read/write when only read access was 
1237      * requested the setting of the can_write flag in
1238      * the file_struct will protect us from errant
1239      * write requests. We never need to worry about O_APPEND
1240      * as this is not set anywhere in Samba.
1241      */
1242     fd_ptr->real_open_flags = O_RDWR;
1243     /* Set the flags as needed without the read/write modes. */
1244     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1245     fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1246     /*
1247      * On some systems opening a file for R/W access on a read only
1248      * filesystems sets errno to EROFS.
1249      */
1250 #ifdef EROFS
1251     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1252 #else /* No EROFS */
1253     if((fd_ptr->fd == -1) && (errno == EACCES)) {
1254 #endif /* EROFS */
1255       if(flags & O_WRONLY) {
1256         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
1257         fd_ptr->real_open_flags = O_WRONLY;
1258       } else {
1259         fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
1260         fd_ptr->real_open_flags = O_RDONLY;
1261       }
1262     }
1263   }
1264
1265   if ((fd_ptr->fd >=0) && 
1266       Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1267     pstring dname;
1268     int dum1,dum2,dum3;
1269     char *p;
1270     pstrcpy(dname,fname);
1271     p = strrchr(dname,'/');
1272     if (p) *p = 0;
1273     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
1274         lp_minprintspace(SNUM(cnum))) {
1275       fd_attempt_close(fd_ptr);
1276       fsp->fd_ptr = 0;
1277       if(fd_ptr->ref_count == 0)
1278         sys_unlink(fname);
1279       errno = ENOSPC;
1280       return;
1281     }
1282   }
1283     
1284   if (fd_ptr->fd < 0)
1285     {
1286       DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1287                fname,strerror(errno),flags));
1288       /* Ensure the ref_count is decremented. */
1289       fd_attempt_close(fd_ptr);
1290       check_for_pipe(fname);
1291       return;
1292     }
1293
1294   if (fd_ptr->fd >= 0)
1295     {
1296       if(sbuf == 0) {
1297         /* Do the fstat */
1298         if(fstat(fd_ptr->fd, &statbuf) == -1) {
1299           /* Error - backout !! */
1300           DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1301                    fd_ptr->fd, fname,strerror(errno)));
1302           /* Ensure the ref_count is decremented. */
1303           fd_attempt_close(fd_ptr);
1304           return;
1305         }
1306         sbuf = &statbuf;
1307       }
1308       /* Set the correct entries in fd_ptr. */
1309       fd_ptr->dev = (uint32)sbuf->st_dev;
1310       fd_ptr->inode = (uint32)sbuf->st_ino;
1311
1312       fsp->fd_ptr = fd_ptr;
1313       Connections[cnum].num_files_open++;
1314       fsp->mode = sbuf->st_mode;
1315       GetTimeOfDay(&fsp->open_time);
1316       fsp->uid = current_user.id;
1317       fsp->size = 0;
1318       fsp->pos = -1;
1319       fsp->open = True;
1320       fsp->mmap_ptr = NULL;
1321       fsp->mmap_size = 0;
1322       fsp->can_lock = True;
1323       fsp->can_read = ((flags & O_WRONLY)==0);
1324       fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1325       fsp->share_mode = 0;
1326       fsp->print_file = Connections[cnum].printer;
1327       fsp->modified = False;
1328       fsp->granted_oplock = False;
1329       fsp->cnum = cnum;
1330       string_set(&fsp->name,dos_to_unix(fname,False));
1331       fsp->wbmpx_ptr = NULL;      
1332
1333       /*
1334        * If the printer is marked as postscript output a leading
1335        * file identifier to ensure the file is treated as a raw
1336        * postscript file.
1337        * This has a similar effect as CtrlD=0 in WIN.INI file.
1338        * tim@fsg.com 09/06/94
1339        */
1340       if (fsp->print_file && POSTSCRIPT(cnum) && 
1341           fsp->can_write) 
1342         {
1343           DEBUG(3,("Writing postscript line\n"));
1344           write_file(fnum,"%!\n",3);
1345         }
1346       
1347       DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1348                timestring(),Connections[cnum].user,fname,
1349                BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1350                Connections[cnum].num_files_open,fnum));
1351
1352     }
1353
1354 #if USE_MMAP
1355   /* mmap it if read-only */
1356   if (!fsp->can_write)
1357     {
1358       fsp->mmap_size = file_size(fname);
1359       fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1360                                           PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
1361
1362       if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1363         {
1364           DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1365           fsp->mmap_ptr = NULL;
1366         }
1367     }
1368 #endif
1369 }
1370
1371 /*******************************************************************
1372 sync a file
1373 ********************************************************************/
1374 void sync_file(int fnum)
1375 {
1376 #ifndef NO_FSYNC
1377   fsync(Files[fnum].fd_ptr->fd);
1378 #endif
1379 }
1380
1381 /****************************************************************************
1382 run a file if it is a magic script
1383 ****************************************************************************/
1384 static void check_magic(int fnum,int cnum)
1385 {
1386   if (!*lp_magicscript(SNUM(cnum)))
1387     return;
1388
1389   DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1390
1391   {
1392     char *p;
1393     if (!(p = strrchr(Files[fnum].name,'/')))
1394       p = Files[fnum].name;
1395     else
1396       p++;
1397
1398     if (!strequal(lp_magicscript(SNUM(cnum)),p))
1399       return;
1400   }
1401
1402   {
1403     int ret;
1404     pstring magic_output;
1405     pstring fname;
1406     pstrcpy(fname,Files[fnum].name);
1407
1408     if (*lp_magicoutput(SNUM(cnum)))
1409       pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1410     else
1411       sprintf(magic_output,"%s.out",fname);
1412
1413     chmod(fname,0755);
1414     ret = smbrun(fname,magic_output,False);
1415     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1416     unlink(fname);
1417   }
1418 }
1419
1420
1421 /****************************************************************************
1422 close a file - possibly invalidating the read prediction
1423
1424 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1425 operation otherwise it came as the result of some other operation such as
1426 the closing of the connection. In the latter case printing and
1427 magic scripts are not run
1428 ****************************************************************************/
1429 void close_file(int fnum, BOOL normal_close)
1430 {
1431   files_struct *fs_p = &Files[fnum];
1432   int cnum = fs_p->cnum;
1433   uint32 dev = fs_p->fd_ptr->dev;
1434   uint32 inode = fs_p->fd_ptr->inode;
1435   int token;
1436
1437 #if USE_READ_PREDICTION
1438   invalidate_read_prediction(fs_p->fd_ptr->fd);
1439 #endif
1440
1441   fs_p->open = False;
1442   Connections[cnum].num_files_open--;
1443   if(fs_p->wbmpx_ptr) 
1444   {
1445     free((char *)fs_p->wbmpx_ptr);
1446     fs_p->wbmpx_ptr = NULL;
1447   }
1448
1449 #if USE_MMAP
1450   if(fs_p->mmap_ptr) 
1451   {
1452     munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1453     fs_p->mmap_ptr = NULL;
1454   }
1455 #endif
1456
1457   if (lp_share_modes(SNUM(cnum)))
1458   {
1459     lock_share_entry( cnum, dev, inode, &token);
1460     del_share_mode(token, fnum);
1461   }
1462
1463   fd_attempt_close(fs_p->fd_ptr);
1464
1465   if (lp_share_modes(SNUM(cnum)))
1466     unlock_share_entry( cnum, dev, inode, token);
1467
1468   /* NT uses smbclose to start a print - weird */
1469   if (normal_close && fs_p->print_file)
1470     print_file(fnum);
1471
1472   /* check for magic scripts */
1473   if (normal_close)
1474     check_magic(fnum,cnum);
1475
1476   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1477            timestring(),Connections[cnum].user,fs_p->name,
1478            Connections[cnum].num_files_open));
1479 }
1480
1481 enum {AFAIL,AREAD,AWRITE,AALL};
1482
1483 /*******************************************************************
1484 reproduce the share mode access table
1485 ********************************************************************/
1486 static int access_table(int new_deny,int old_deny,int old_mode,
1487                         int share_pid,char *fname)
1488 {
1489   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1490
1491   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1492     int pid = getpid();
1493     if (old_deny == new_deny && share_pid == pid) 
1494         return(AALL);    
1495
1496     if (old_mode == 0) return(AREAD);
1497
1498     /* the new smbpub.zip spec says that if the file extension is
1499        .com, .dll, .exe or .sym then allow the open. I will force
1500        it to read-only as this seems sensible although the spec is
1501        a little unclear on this. */
1502     if ((fname = strrchr(fname,'.'))) {
1503       if (strequal(fname,".com") ||
1504           strequal(fname,".dll") ||
1505           strequal(fname,".exe") ||
1506           strequal(fname,".sym"))
1507         return(AREAD);
1508     }
1509
1510     return(AFAIL);
1511   }
1512
1513   switch (new_deny) 
1514     {
1515     case DENY_WRITE:
1516       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1517       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1518       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1519       return(AFAIL);
1520     case DENY_READ:
1521       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1522       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1523       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1524       return(AFAIL);
1525     case DENY_NONE:
1526       if (old_deny==DENY_WRITE) return(AREAD);
1527       if (old_deny==DENY_READ) return(AWRITE);
1528       if (old_deny==DENY_NONE) return(AALL);
1529       return(AFAIL);      
1530     }
1531   return(AFAIL);      
1532 }
1533
1534 /*******************************************************************
1535 check if the share mode on a file allows it to be deleted or unlinked
1536 return True if sharing doesn't prevent the operation
1537 ********************************************************************/
1538 BOOL check_file_sharing(int cnum,char *fname)
1539 {
1540   int i;
1541   int ret = False;
1542   share_mode_entry *old_shares = 0;
1543   int num_share_modes;
1544   struct stat sbuf;
1545   int token;
1546   int pid = getpid();
1547   uint32 dev, inode;
1548
1549   if(!lp_share_modes(SNUM(cnum)))
1550     return True;
1551
1552   if (stat(fname,&sbuf) == -1) return(True);
1553
1554   dev = (uint32)sbuf.st_dev;
1555   inode = (uint32)sbuf.st_ino;
1556
1557   lock_share_entry(cnum, dev, inode, &token);
1558   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1559
1560   /*
1561    * Check if the share modes will give us access.
1562    */
1563
1564   if(num_share_modes != 0)
1565   {
1566     BOOL broke_oplock;
1567
1568     do
1569     {
1570
1571       broke_oplock = False;
1572       for(i = 0; i < num_share_modes; i++)
1573       {
1574         share_mode_entry *share_entry = &old_shares[i];
1575
1576         /* 
1577          * Break oplocks before checking share modes. See comment in
1578          * open_file_shared for details. 
1579          * Check if someone has an oplock on this file. If so we must 
1580          * break it before continuing. 
1581          */
1582         if(share_entry->op_type & BATCH_OPLOCK)
1583         {
1584
1585           DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1586 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1587
1588           /* Oplock break.... */
1589           unlock_share_entry(cnum, dev, inode, token);
1590           if(request_oplock_break(share_entry, dev, inode) == False)
1591           {
1592             free((char *)old_shares);
1593             DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1594 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1595             return False;
1596           }
1597           lock_share_entry(cnum, dev, inode, &token);
1598           broke_oplock = True;
1599           break;
1600         }
1601
1602         /* someone else has a share lock on it, check to see 
1603            if we can too */
1604         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1605           goto free_and_exit;
1606
1607       } /* end for */
1608
1609       if(broke_oplock)
1610       {
1611         free((char *)old_shares);
1612         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1613       }
1614     } while(broke_oplock);
1615   }
1616
1617   /* XXXX exactly what share mode combinations should be allowed for
1618      deleting/renaming? */
1619   /* If we got here then either there were no share modes or
1620      all share modes were DENY_DOS and the pid == getpid() */
1621   ret = True;
1622
1623 free_and_exit:
1624
1625   unlock_share_entry(cnum, dev, inode, token);
1626   if(old_shares != NULL)
1627     free((char *)old_shares);
1628   return(ret);
1629 }
1630
1631 /****************************************************************************
1632   C. Hoch 11/22/95
1633   Helper for open_file_shared. 
1634   Truncate a file after checking locking; close file if locked.
1635   **************************************************************************/
1636 static void truncate_unless_locked(int fnum, int cnum, int token, 
1637                                    BOOL *share_locked)
1638 {
1639   if (Files[fnum].can_write){
1640     if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1641       /* If share modes are in force for this connection we
1642          have the share entry locked. Unlock it before closing. */
1643       if (*share_locked && lp_share_modes(SNUM(cnum)))
1644         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
1645                             Files[fnum].fd_ptr->inode, token);
1646       close_file(fnum,False);   
1647       /* Share mode no longer locked. */
1648       *share_locked = False;
1649       errno = EACCES;
1650       unix_ERR_class = ERRDOS;
1651       unix_ERR_code = ERRlock;
1652     }
1653     else
1654       ftruncate(Files[fnum].fd_ptr->fd,0); 
1655   }
1656 }
1657
1658 /****************************************************************************
1659 check if we can open a file with a share mode
1660 ****************************************************************************/
1661 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1662                       BOOL fcbopen, int *flags)
1663 {
1664   int old_open_mode = share->share_mode &0xF;
1665   int old_deny_mode = (share->share_mode >>4)&7;
1666
1667   if (old_deny_mode > 4 || old_open_mode > 2)
1668   {
1669     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1670                deny_mode,old_deny_mode,old_open_mode,fname));
1671     return False;
1672   }
1673
1674   {
1675     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1676                                 share->pid,fname);
1677
1678     if ((access_allowed == AFAIL) ||
1679         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1680         (access_allowed == AREAD && *flags == O_WRONLY) ||
1681         (access_allowed == AWRITE && *flags == O_RDONLY))
1682     {
1683       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1684                 deny_mode,old_deny_mode,old_open_mode,
1685                 share->pid,fname, access_allowed));
1686       return False;
1687     }
1688
1689     if (access_allowed == AREAD)
1690       *flags = O_RDONLY;
1691
1692     if (access_allowed == AWRITE)
1693       *flags = O_WRONLY;
1694
1695   }
1696   return True;
1697 }
1698
1699 /****************************************************************************
1700 open a file with a share mode
1701 ****************************************************************************/
1702 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1703                       int mode,int oplock_request, int *Access,int *action)
1704 {
1705   files_struct *fs_p = &Files[fnum];
1706   int flags=0;
1707   int flags2=0;
1708   int deny_mode = (share_mode>>4)&7;
1709   struct stat sbuf;
1710   BOOL file_existed = file_exist(fname,&sbuf);
1711   BOOL share_locked = False;
1712   BOOL fcbopen = False;
1713   int token;
1714   uint32 dev = 0;
1715   uint32 inode = 0;
1716   int num_share_modes = 0;
1717
1718   fs_p->open = False;
1719   fs_p->fd_ptr = 0;
1720
1721   /* this is for OS/2 EAs - try and say we don't support them */
1722   if (strstr(fname,".+,;=[].")) 
1723   {
1724     unix_ERR_class = ERRDOS;
1725     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1726 #ifdef OS2_WPS_FIX
1727     unix_ERR_code = ERRcannotopen;
1728 #else /* OS2_WPS_FIX */
1729     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1730 #endif /* OS2_WPS_FIX */
1731
1732     return;
1733   }
1734
1735   if ((ofun & 0x3) == 0 && file_existed)  
1736   {
1737     errno = EEXIST;
1738     return;
1739   }
1740       
1741   if (ofun & 0x10)
1742     flags2 |= O_CREAT;
1743   if ((ofun & 0x3) == 2)
1744     flags2 |= O_TRUNC;
1745
1746   /* note that we ignore the append flag as 
1747      append does not mean the same thing under dos and unix */
1748
1749   switch (share_mode&0xF)
1750   {
1751     case 1: 
1752       flags = O_WRONLY; 
1753       break;
1754     case 0xF: 
1755       fcbopen = True;
1756       flags = O_RDWR; 
1757       break;
1758     case 2: 
1759       flags = O_RDWR; 
1760       break;
1761     default:
1762       flags = O_RDONLY;
1763       break;
1764   }
1765   
1766   if (flags != O_RDONLY && file_existed && 
1767       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
1768   {
1769     if (!fcbopen) 
1770     {
1771       errno = EACCES;
1772       return;
1773     }
1774     flags = O_RDONLY;
1775   }
1776
1777   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
1778   {
1779     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1780     errno = EINVAL;
1781     return;
1782   }
1783
1784   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1785
1786   if (lp_share_modes(SNUM(cnum))) 
1787   {
1788     int i;
1789     share_mode_entry *old_shares = 0;
1790
1791     if (file_existed)
1792     {
1793       dev = (uint32)sbuf.st_dev;
1794       inode = (uint32)sbuf.st_ino;
1795       lock_share_entry(cnum, dev, inode, &token);
1796       share_locked = True;
1797       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1798     }
1799
1800     /*
1801      * Check if the share modes will give us access.
1802      */
1803
1804     if(share_locked && (num_share_modes != 0))
1805     {
1806       BOOL broke_oplock;
1807
1808       do
1809       {
1810
1811         broke_oplock = False;
1812         for(i = 0; i < num_share_modes; i++)
1813         {
1814           share_mode_entry *share_entry = &old_shares[i];
1815
1816           /* 
1817            * By observation of NetBench, oplocks are broken *before* share
1818            * modes are checked. This allows a file to be closed by the client
1819            * if the share mode would deny access and the client has an oplock. 
1820            * Check if someone has an oplock on this file. If so we must break 
1821            * it before continuing. 
1822            */
1823           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1824           {
1825
1826             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1827 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1828
1829             /* Oplock break.... */
1830             unlock_share_entry(cnum, dev, inode, token);
1831             if(request_oplock_break(share_entry, dev, inode) == False)
1832             {
1833               free((char *)old_shares);
1834               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1835 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1836               errno = EACCES;
1837               unix_ERR_class = ERRDOS;
1838               unix_ERR_code = ERRbadshare;
1839               return;
1840             }
1841             lock_share_entry(cnum, dev, inode, &token);
1842             broke_oplock = True;
1843             break;
1844           }
1845
1846           /* someone else has a share lock on it, check to see 
1847              if we can too */
1848           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1849           {
1850             free((char *)old_shares);
1851             unlock_share_entry(cnum, dev, inode, token);
1852             errno = EACCES;
1853             unix_ERR_class = ERRDOS;
1854             unix_ERR_code = ERRbadshare;
1855             return;
1856           }
1857
1858         } /* end for */
1859
1860         if(broke_oplock)
1861         {
1862           free((char *)old_shares);
1863           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1864         }
1865       } while(broke_oplock);
1866     }
1867
1868     if(old_shares != 0)
1869       free((char *)old_shares);
1870   }
1871
1872   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1873            flags,flags2,mode));
1874
1875   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1876   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
1877   {
1878     flags = O_RDONLY;
1879     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1880   }
1881
1882   if (fs_p->open) 
1883   {
1884     int open_mode=0;
1885
1886     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1887     {
1888       /* We created the file - thus we must now lock the share entry before creating it. */
1889       dev = fs_p->fd_ptr->dev;
1890       inode = fs_p->fd_ptr->inode;
1891       lock_share_entry(cnum, dev, inode, &token);
1892       share_locked = True;
1893     }
1894
1895     switch (flags) 
1896     {
1897       case O_RDONLY:
1898         open_mode = 0;
1899         break;
1900       case O_RDWR:
1901         open_mode = 2;
1902         break;
1903       case O_WRONLY:
1904         open_mode = 1;
1905         break;
1906     }
1907
1908     fs_p->share_mode = (deny_mode<<4) | open_mode;
1909
1910     if (Access)
1911       (*Access) = open_mode;
1912
1913     if (action) 
1914     {
1915       if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1916       if (!file_existed) *action = 2;
1917       if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1918     }
1919     /* We must create the share mode entry before truncate as
1920        truncate can fail due to locking and have to close the
1921        file (which expects the share_mode_entry to be there).
1922      */
1923     if (lp_share_modes(SNUM(cnum)))
1924     {
1925       uint16 port = 0;
1926       /* JRA. Currently this only services Exlcusive and batch
1927          oplocks (no other opens on this file). This needs to
1928          be extended to level II oplocks (multiple reader
1929          oplocks). */
1930
1931       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
1932       {
1933         fs_p->granted_oplock = True;
1934         global_oplocks_open++;
1935         port = oplock_port;
1936
1937         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1938 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1939
1940       }
1941       else
1942       {
1943         port = 0;
1944         oplock_request = 0;
1945       }
1946       set_share_mode(token, fnum, port, oplock_request);
1947     }
1948
1949     if ((flags2&O_TRUNC) && file_existed)
1950       truncate_unless_locked(fnum,cnum,token,&share_locked);
1951   }
1952
1953   if (share_locked && lp_share_modes(SNUM(cnum)))
1954     unlock_share_entry( cnum, dev, inode, token);
1955 }
1956
1957 /****************************************************************************
1958 seek a file. Try to avoid the seek if possible
1959 ****************************************************************************/
1960 int seek_file(int fnum,uint32 pos)
1961 {
1962   uint32 offset = 0;
1963   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1964     offset = 3;
1965
1966   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
1967                                   - offset);
1968   return(Files[fnum].pos);
1969 }
1970
1971 /****************************************************************************
1972 read from a file
1973 ****************************************************************************/
1974 int read_file(int fnum,char *data,uint32 pos,int n)
1975 {
1976   int ret=0,readret;
1977
1978 #if USE_READ_PREDICTION
1979   if (!Files[fnum].can_write)
1980     {
1981       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1982
1983       data += ret;
1984       n -= ret;
1985       pos += ret;
1986     }
1987 #endif
1988
1989 #if USE_MMAP
1990   if (Files[fnum].mmap_ptr)
1991     {
1992       int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1993       if (num > 0)
1994         {
1995           memcpy(data,Files[fnum].mmap_ptr+pos,num);
1996           data += num;
1997           pos += num;
1998           n -= num;
1999           ret += num;
2000         }
2001     }
2002 #endif
2003
2004   if (n <= 0)
2005     return(ret);
2006
2007   if (seek_file(fnum,pos) != pos)
2008     {
2009       DEBUG(3,("Failed to seek to %d\n",pos));
2010       return(ret);
2011     }
2012   
2013   if (n > 0) {
2014     readret = read(Files[fnum].fd_ptr->fd,data,n);
2015     if (readret > 0) ret += readret;
2016   }
2017
2018   return(ret);
2019 }
2020
2021
2022 /****************************************************************************
2023 write to a file
2024 ****************************************************************************/
2025 int write_file(int fnum,char *data,int n)
2026 {
2027   if (!Files[fnum].can_write) {
2028     errno = EPERM;
2029     return(0);
2030   }
2031
2032   if (!Files[fnum].modified) {
2033     struct stat st;
2034     Files[fnum].modified = True;
2035     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2036       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2037       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {  
2038         dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2039       }
2040     }  
2041   }
2042
2043   return(write_data(Files[fnum].fd_ptr->fd,data,n));
2044 }
2045
2046
2047 /****************************************************************************
2048 load parameters specific to a connection/service
2049 ****************************************************************************/
2050 BOOL become_service(int cnum,BOOL do_chdir)
2051 {
2052   extern char magic_char;
2053   static int last_cnum = -1;
2054   int snum;
2055
2056   if (!OPEN_CNUM(cnum))
2057     {
2058       last_cnum = -1;
2059       return(False);
2060     }
2061
2062   Connections[cnum].lastused = smb_last_time;
2063
2064   snum = SNUM(cnum);
2065   
2066   if (do_chdir &&
2067       ChDir(Connections[cnum].connectpath) != 0 &&
2068       ChDir(Connections[cnum].origpath) != 0)
2069     {
2070       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2071             Connections[cnum].connectpath,cnum));     
2072       return(False);
2073     }
2074
2075   if (cnum == last_cnum)
2076     return(True);
2077
2078   last_cnum = cnum;
2079
2080   case_default = lp_defaultcase(snum);
2081   case_preserve = lp_preservecase(snum);
2082   short_case_preserve = lp_shortpreservecase(snum);
2083   case_mangle = lp_casemangle(snum);
2084   case_sensitive = lp_casesensitive(snum);
2085   magic_char = lp_magicchar(snum);
2086   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2087   return(True);
2088 }
2089
2090
2091 /****************************************************************************
2092   find a service entry
2093 ****************************************************************************/
2094 int find_service(char *service)
2095 {
2096    int iService;
2097
2098    string_sub(service,"\\","/");
2099
2100    iService = lp_servicenumber(service);
2101
2102    /* now handle the special case of a home directory */
2103    if (iService < 0)
2104    {
2105       char *phome_dir = get_home_dir(service);
2106       DEBUG(3,("checking for home directory %s gave %s\n",service,
2107             phome_dir?phome_dir:"(NULL)"));
2108       if (phome_dir)
2109       {   
2110          int iHomeService;
2111          if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2112          {
2113             lp_add_home(service,iHomeService,phome_dir);
2114             iService = lp_servicenumber(service);
2115          }
2116       }
2117    }
2118
2119    /* If we still don't have a service, attempt to add it as a printer. */
2120    if (iService < 0)
2121    {
2122       int iPrinterService;
2123
2124       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2125       {
2126          char *pszTemp;
2127
2128          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2129          pszTemp = PRINTCAP;
2130          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2131          {
2132             DEBUG(3,("%s is a valid printer name\n", service));
2133             DEBUG(3,("adding %s as a printer service\n", service));
2134             lp_add_printer(service,iPrinterService);
2135             iService = lp_servicenumber(service);
2136             if (iService < 0)
2137                DEBUG(0,("failed to add %s as a printer service!\n", service));
2138          }
2139          else
2140             DEBUG(3,("%s is not a valid printer name\n", service));
2141       }
2142    }
2143
2144    /* just possibly it's a default service? */
2145    if (iService < 0) 
2146      {
2147        char *defservice = lp_defaultservice();
2148        if (defservice && *defservice && !strequal(defservice,service)) {
2149          iService = find_service(defservice);
2150          if (iService >= 0) {
2151            string_sub(service,"_","/");
2152            iService = lp_add_service(service,iService);
2153          }
2154        }
2155      }
2156
2157    if (iService >= 0)
2158       if (!VALID_SNUM(iService))
2159       {
2160          DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2161          iService = -1;
2162       }
2163
2164    if (iService < 0)
2165       DEBUG(3,("find_service() failed to find service %s\n", service));
2166
2167    return (iService);
2168 }
2169
2170
2171 /****************************************************************************
2172   create an error packet from a cached error.
2173 ****************************************************************************/
2174 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2175 {
2176   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2177
2178   int32 eclass = wbmpx->wr_errclass;
2179   int32 err = wbmpx->wr_error;
2180
2181   /* We can now delete the auxiliary struct */
2182   free((char *)wbmpx);
2183   Files[fnum].wbmpx_ptr = NULL;
2184   return error_packet(inbuf,outbuf,eclass,err,line);
2185 }
2186
2187
2188 struct
2189 {
2190   int unixerror;
2191   int smbclass;
2192   int smbcode;
2193 } unix_smb_errmap[] =
2194 {
2195   {EPERM,ERRDOS,ERRnoaccess},
2196   {EACCES,ERRDOS,ERRnoaccess},
2197   {ENOENT,ERRDOS,ERRbadfile},
2198   {ENOTDIR,ERRDOS,ERRbadpath},
2199   {EIO,ERRHRD,ERRgeneral},
2200   {EBADF,ERRSRV,ERRsrverror},
2201   {EINVAL,ERRSRV,ERRsrverror},
2202   {EEXIST,ERRDOS,ERRfilexists},
2203   {ENFILE,ERRDOS,ERRnofids},
2204   {EMFILE,ERRDOS,ERRnofids},
2205   {ENOSPC,ERRHRD,ERRdiskfull},
2206 #ifdef EDQUOT
2207   {EDQUOT,ERRHRD,ERRdiskfull},
2208 #endif
2209 #ifdef ENOTEMPTY
2210   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2211 #endif
2212 #ifdef EXDEV
2213   {EXDEV,ERRDOS,ERRdiffdevice},
2214 #endif
2215   {EROFS,ERRHRD,ERRnowrite},
2216   {0,0,0}
2217 };
2218
2219 /****************************************************************************
2220   create an error packet from errno
2221 ****************************************************************************/
2222 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2223 {
2224   int eclass=def_class;
2225   int ecode=def_code;
2226   int i=0;
2227
2228   if (unix_ERR_class != SUCCESS)
2229     {
2230       eclass = unix_ERR_class;
2231       ecode = unix_ERR_code;
2232       unix_ERR_class = SUCCESS;
2233       unix_ERR_code = 0;
2234     }
2235   else
2236     {
2237       while (unix_smb_errmap[i].smbclass != 0)
2238       {
2239             if (unix_smb_errmap[i].unixerror == errno)
2240             {
2241               eclass = unix_smb_errmap[i].smbclass;
2242               ecode = unix_smb_errmap[i].smbcode;
2243               break;
2244             }
2245           i++;
2246       }
2247     }
2248
2249   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2250 }
2251
2252
2253 /****************************************************************************
2254   create an error packet. Normally called using the ERROR() macro
2255 ****************************************************************************/
2256 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2257 {
2258   int outsize = set_message(outbuf,0,0,True);
2259   int cmd;
2260   cmd = CVAL(inbuf,smb_com);
2261   
2262   CVAL(outbuf,smb_rcls) = error_class;
2263   SSVAL(outbuf,smb_err,error_code);  
2264   
2265   DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2266            timestring(),
2267            line,
2268            (int)CVAL(inbuf,smb_com),
2269            smb_fn_name(CVAL(inbuf,smb_com)),
2270            error_class,
2271            error_code));
2272
2273   if (errno != 0)
2274     DEBUG(3,("error string = %s\n",strerror(errno)));
2275   
2276   return(outsize);
2277 }
2278
2279
2280 #ifndef SIGCLD_IGNORE
2281 /****************************************************************************
2282 this prevents zombie child processes
2283 ****************************************************************************/
2284 static int sig_cld()
2285 {
2286   static int depth = 0;
2287   if (depth != 0)
2288     {
2289       DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2290       depth=0;
2291       return(0);
2292     }
2293   depth++;
2294
2295   BlockSignals(True,SIGCLD);
2296   DEBUG(5,("got SIGCLD\n"));
2297
2298 #ifdef USE_WAITPID
2299   while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2300 #endif
2301
2302   /* Stop zombies */
2303   /* Stevens, Adv. Unix Prog. says that on system V you must call
2304      wait before reinstalling the signal handler, because the kernel
2305      calls the handler from within the signal-call when there is a
2306      child that has exited. This would lead to an infinite recursion
2307      if done vice versa. */
2308         
2309 #ifndef DONT_REINSTALL_SIG
2310 #ifdef SIGCLD_IGNORE
2311   signal(SIGCLD, SIG_IGN);  
2312 #else
2313   signal(SIGCLD, SIGNAL_CAST sig_cld);
2314 #endif
2315 #endif
2316
2317 #ifndef USE_WAITPID
2318   while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2319 #endif
2320   depth--;
2321   BlockSignals(False,SIGCLD);
2322   return 0;
2323 }
2324 #endif
2325
2326 /****************************************************************************
2327   this is called when the client exits abruptly
2328   **************************************************************************/
2329 static int sig_pipe()
2330 {
2331         struct cli_state *cli;
2332         BlockSignals(True,SIGPIPE);
2333
2334         if ((cli = server_client()) && cli->initialised) {
2335                 DEBUG(3,("lost connection to password server\n"));
2336                 cli_shutdown(cli);
2337 #ifndef DONT_REINSTALL_SIG
2338                 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2339 #endif
2340                 BlockSignals(False,SIGPIPE);
2341                 return 0;
2342         }
2343
2344         exit_server("Got sigpipe\n");
2345         return(0);
2346 }
2347
2348 /****************************************************************************
2349   open the socket communication
2350 ****************************************************************************/
2351 static BOOL open_sockets(BOOL is_daemon,int port)
2352 {
2353   extern int Client;
2354
2355   if (is_daemon)
2356   {
2357     int num_interfaces = iface_count();
2358     int fd_listenset[FD_SETSIZE];
2359     fd_set listen_set;
2360     int s;
2361     int i;
2362
2363     /* Stop zombies */
2364 #ifdef SIGCLD_IGNORE
2365     signal(SIGCLD, SIG_IGN);
2366 #else
2367     signal(SIGCLD, SIGNAL_CAST sig_cld);
2368 #endif
2369
2370     if(atexit_set == 0)
2371       atexit(killkids);
2372
2373     FD_ZERO(&listen_set);
2374
2375     if(lp_interfaces() && lp_bind_interfaces_only())
2376     {
2377        /* We have been given an interfaces line, and been 
2378           told to only bind to those interfaces. Create a
2379           socket per interface and bind to only these.
2380         */
2381
2382       if(num_interfaces > FD_SETSIZE)
2383       {
2384         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2385 max can be %d\n", num_interfaces, FD_SETSIZE));
2386         return False;
2387       }
2388
2389       /* Now open a listen socket for each of the interfaces. */
2390       for(i = 0; i < num_interfaces; i++)
2391       {
2392         struct in_addr *ifip = iface_n_ip(i);
2393
2394         if(ifip == NULL)
2395         {
2396           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2397           continue;
2398         }
2399         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2400         if(s == -1)
2401           return False;
2402         /* ready to listen */
2403         if (listen(s, 5) == -1) 
2404         {
2405           DEBUG(0,("listen: %s\n",strerror(errno)));
2406           close(s);
2407           return False;
2408         }
2409         FD_SET(s,&listen_set);
2410       }
2411     }
2412     else
2413     {
2414       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2415       num_interfaces = 1;
2416
2417       /* open an incoming socket */
2418       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2419       if (s == -1)
2420         return(False);
2421
2422       /* ready to listen */
2423       if (listen(s, 5) == -1) 
2424       {
2425         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2426         close(s);
2427         return False;
2428       }
2429
2430       fd_listenset[0] = s;
2431       FD_SET(s,&listen_set);
2432     }      
2433
2434     /* now accept incoming connections - forking a new process
2435        for each incoming connection */
2436     DEBUG(2,("waiting for a connection\n"));
2437     while (1)
2438     {
2439       fd_set lfds;
2440       int num;
2441
2442       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2443
2444       num = sys_select(&lfds,NULL);
2445
2446       if (num == -1 && errno == EINTR)
2447         continue;
2448
2449       /* Find the sockets that are read-ready - accept on these. */
2450       for( ; num > 0; num--)
2451       {
2452         struct sockaddr addr;
2453         int in_addrlen = sizeof(addr);
2454
2455         s = -1;
2456         for(i = 0; i < num_interfaces; i++)
2457         {
2458           if(FD_ISSET(fd_listenset[i],&lfds))
2459           {
2460             s = fd_listenset[i];
2461             /* Clear this so we don't look at it again. */
2462             FD_CLR(fd_listenset[i],&lfds);
2463             break;
2464           }
2465         }
2466
2467         Client = accept(s,&addr,&in_addrlen);
2468
2469         if (Client == -1 && errno == EINTR)
2470           continue;
2471
2472         if (Client == -1)
2473         {
2474           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2475           continue;
2476         }
2477
2478 #ifdef NO_FORK_DEBUG
2479 #ifndef NO_SIGNAL_TEST
2480         signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2481         signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2482 #endif /* NO_SIGNAL_TEST */
2483         return True;
2484 #else /* NO_FORK_DEBUG */
2485         if (Client != -1 && fork()==0)
2486         {
2487           /* Child code ... */
2488
2489 #ifndef NO_SIGNAL_TEST
2490           signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2491           signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2492 #endif /* NO_SIGNAL_TEST */
2493           /* close the listening socket(s) */
2494           for(i = 0; i < num_interfaces; i++)
2495             close(fd_listenset[i]);
2496
2497           /* close our standard file descriptors */
2498           close_low_fds();
2499           am_parent = 0;
2500   
2501           set_socket_options(Client,"SO_KEEPALIVE");
2502           set_socket_options(Client,user_socket_options);
2503
2504           /* Reset global variables in util.c so that
2505              client substitutions will be done correctly
2506              in the process.
2507            */
2508           reset_globals_after_fork();
2509           return True; 
2510         }
2511         close(Client); /* The parent doesn't need this socket */
2512 #endif /NO_FORK_DEBUG */
2513       } /* end for num */
2514     } /* end while 1 */
2515   } /* end if is_daemon */
2516   else
2517   {
2518     /* Started from inetd. fd 0 is the socket. */
2519     /* We will abort gracefully when the client or remote system 
2520        goes away */
2521 #ifndef NO_SIGNAL_TEST
2522     signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2523 #endif
2524     Client = dup(0);
2525
2526     /* close our standard file descriptors */
2527     close_low_fds();
2528
2529     set_socket_options(Client,"SO_KEEPALIVE");
2530     set_socket_options(Client,user_socket_options);
2531   }
2532
2533   return True;
2534 }
2535
2536 /****************************************************************************
2537   process an smb from the client - split out from the process() code so
2538   it can be used by the oplock break code.
2539 ****************************************************************************/
2540
2541 static void process_smb(char *inbuf, char *outbuf)
2542 {
2543   extern int Client;
2544   static int trans_num;
2545   int msg_type = CVAL(inbuf,0);
2546   int32 len = smb_len(inbuf);
2547   int nread = len + 4;
2548
2549   if (trans_num == 0) {
2550           /* on the first packet, check the global hosts allow/ hosts
2551              deny parameters before doing any parsing of the packet
2552              passed to us by the client.  This prevents attacks on our
2553              parsing code from hosts not in the hosts allow list */
2554           if (!check_access(-1)) {
2555                   /* send a negative session response "not listining on calling
2556                    name" */
2557                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2558                   DEBUG(1,("%s Connection denied from %s\n",
2559                            timestring(),client_addr()));
2560                   send_smb(Client,(char *)buf);
2561                   exit_server("connection denied");
2562           }
2563   }
2564
2565   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2566   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2567
2568 #ifdef WITH_VTP
2569   if(trans_num == 1 && VT_Check(inbuf)) 
2570   {
2571     VT_Process();
2572     return;
2573   }
2574 #endif
2575
2576   if (msg_type == 0)
2577     show_msg(inbuf);
2578
2579   nread = construct_reply(inbuf,outbuf,nread,max_send);
2580       
2581   if(nread > 0) 
2582   {
2583     if (CVAL(outbuf,0) == 0)
2584       show_msg(outbuf);
2585         
2586     if (nread != smb_len(outbuf) + 4) 
2587     {
2588       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2589                  nread, smb_len(outbuf)));
2590     }
2591     else
2592       send_smb(Client,outbuf);
2593   }
2594   trans_num++;
2595 }
2596
2597 /****************************************************************************
2598   open the oplock IPC socket communication
2599 ****************************************************************************/
2600 static BOOL open_oplock_ipc()
2601 {
2602   struct sockaddr_in sock_name;
2603   int len = sizeof(sock_name);
2604
2605   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2606
2607   /* Open a lookback UDP socket on a random port. */
2608   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2609   if (oplock_sock == -1)
2610   {
2611     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2612 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2613     oplock_port = 0;
2614     return(False);
2615   }
2616
2617   /* Find out the transient UDP port we have been allocated. */
2618   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2619   {
2620     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2621             strerror(errno)));
2622     close(oplock_sock);
2623     oplock_sock = -1;
2624     oplock_port = 0;
2625     return False;
2626   }
2627   oplock_port = ntohs(sock_name.sin_port);
2628
2629   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2630             getpid(), oplock_port));
2631
2632   return True;
2633 }
2634
2635 /****************************************************************************
2636   process an oplock break message.
2637 ****************************************************************************/
2638 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2639 {
2640   int32 msg_len;
2641   uint16 from_port;
2642   char *msg_start;
2643
2644   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2645   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2646
2647   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2648
2649   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2650             msg_len, from_port));
2651
2652   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2653      only valid request. */
2654
2655   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2656   {
2657     case OPLOCK_BREAK_CMD:
2658       /* Ensure that the msg length is correct. */
2659       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2660       {
2661         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2662 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2663         return False;
2664       }
2665       {
2666         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2667         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2668         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2669         struct timeval tval;
2670         struct sockaddr_in toaddr;
2671
2672         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2673         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2674
2675         DEBUG(5,("process_local_message: oplock break request from \
2676 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2677
2678         /*
2679          * If we have no record of any currently open oplocks,
2680          * it's not an error, as a close command may have
2681          * just been issued on the file that was oplocked.
2682          * Just return success in this case.
2683          */
2684
2685         if(global_oplocks_open != 0)
2686         {
2687           if(oplock_break(dev, inode, &tval) == False)
2688           {
2689             DEBUG(0,("process_local_message: oplock break failed - \
2690 not returning udp message.\n"));
2691             return False;
2692           }
2693         }
2694         else
2695         {
2696           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2697 oplocks. Returning success.\n"));
2698         }
2699
2700         /* Send the message back after OR'ing in the 'REPLY' bit. */
2701         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2702   
2703         bzero((char *)&toaddr,sizeof(toaddr));
2704         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2705         toaddr.sin_port = htons(from_port);
2706         toaddr.sin_family = AF_INET;
2707
2708         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2709                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2710         {
2711           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2712                     remotepid, strerror(errno)));
2713           return False;
2714         }
2715
2716         DEBUG(5,("process_local_message: oplock break reply sent to \
2717 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2718                 from_port, dev, inode));
2719
2720       }
2721       break;
2722     /* 
2723      * Keep this as a debug case - eventually we can remove it.
2724      */
2725     case 0x8001:
2726       DEBUG(0,("process_local_message: Received unsolicited break \
2727 reply - dumping info.\n"));
2728
2729       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2730       {
2731         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2732 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2733         return False;
2734       }
2735
2736       {
2737         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2738         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2739         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2740
2741         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2742 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2743
2744        }
2745        return False;
2746
2747     default:
2748       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2749                 (unsigned int)SVAL(msg_start,0)));
2750       return False;
2751   }
2752   return True;
2753 }
2754
2755 /****************************************************************************
2756  Process an oplock break directly.
2757 ****************************************************************************/
2758 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2759 {
2760   extern int Client;
2761   static char *inbuf = NULL;
2762   static char *outbuf = NULL;
2763   files_struct *fsp = NULL;
2764   int fnum;
2765   time_t start_time;
2766   BOOL shutdown_server = False;
2767
2768   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2769 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2770
2771   if(inbuf == NULL)
2772   {
2773     inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2774     if(inbuf == NULL) {
2775       DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2776       return False;
2777     } 
2778     outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2779     if(outbuf == NULL) {
2780       DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2781       free(inbuf);
2782       inbuf = NULL;
2783       return False;
2784     }
2785   } 
2786
2787   /* We need to search the file open table for the
2788      entry containing this dev and inode, and ensure
2789      we have an oplock on it. */
2790   for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2791   {
2792     if(OPEN_FNUM(fnum))
2793     {
2794       fsp = &Files[fnum];
2795       if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2796          (fsp->open_time.tv_sec == tval->tv_sec) && 
2797          (fsp->open_time.tv_usec == tval->tv_usec))
2798         break;
2799     }
2800   }
2801
2802   if(fsp == NULL)
2803   {
2804     /* The file could have been closed in the meantime - return success. */
2805     DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2806 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2807     return True;
2808   }
2809
2810   /* Ensure we have an oplock on the file */
2811
2812   /* There is a potential race condition in that an oplock could
2813      have been broken due to another udp request, and yet there are
2814      still oplock break messages being sent in the udp message
2815      queue for this file. So return true if we don't have an oplock,
2816      as we may have just freed it.
2817    */
2818
2819   if(!fsp->granted_oplock)
2820   {
2821     DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2822 Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2823     return True;
2824   }
2825
2826   /* Now comes the horrid part. We must send an oplock break to the client,
2827      and then process incoming messages until we get a close or oplock release.
2828    */
2829
2830   /* Prepare the SMBlockingX message. */
2831   bzero(outbuf,smb_size);
2832   set_message(outbuf,8,0,True);
2833
2834   SCVAL(outbuf,smb_com,SMBlockingX);
2835   SSVAL(outbuf,smb_tid,fsp->cnum);
2836   SSVAL(outbuf,smb_pid,0xFFFF);
2837   SSVAL(outbuf,smb_uid,0);
2838   SSVAL(outbuf,smb_mid,0xFFFF);
2839   SCVAL(outbuf,smb_vwv0,0xFF);
2840   SSVAL(outbuf,smb_vwv2,fnum);
2841   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2842   /* Change this when we have level II oplocks. */
2843   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2844  
2845   send_smb(Client, outbuf);
2846
2847   global_oplock_break = True;
2848  
2849   /* Process incoming messages. */
2850
2851   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2852      seconds we should just die.... */
2853
2854   start_time = time(NULL);
2855
2856   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2857   {
2858     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2859     {
2860       /*
2861        * Die if we got an error.
2862        */
2863
2864       if (smb_read_error == READ_EOF)
2865         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2866  
2867       if (smb_read_error == READ_ERROR)
2868         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2869                   timestring(), strerror(errno)));
2870
2871       if (smb_read_error == READ_TIMEOUT)
2872         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2873                   timestring(), OPLOCK_BREAK_TIMEOUT));
2874
2875       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2876 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2877       shutdown_server = True;
2878       break;
2879     }
2880     process_smb(inbuf, outbuf);
2881
2882     /* We only need this in case a readraw crossed on the wire. */
2883     if(global_oplock_break)
2884       global_oplock_break = False;
2885
2886     /*
2887      * Die if we go over the time limit.
2888      */
2889
2890     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2891     {
2892       DEBUG(0,("%s oplock_break: no break received from client within \
2893 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2894       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2895 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2896       shutdown_server = True;
2897       break;
2898     }
2899   }
2900
2901   /*
2902    * If the client did not respond we must die.
2903    */
2904
2905   if(shutdown_server)
2906   {
2907     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2908           timestring()));
2909     close_sockets();
2910     close(oplock_sock);
2911     exit_server("oplock break failure");
2912   }
2913
2914   if(OPEN_FNUM(fnum))
2915   {
2916     /* The lockingX reply will have removed the oplock flag 
2917        from the sharemode. */
2918     /* Paranoia.... */
2919     fsp->granted_oplock = False;
2920   }
2921
2922   global_oplocks_open--;
2923
2924   /* Santity check - remove this later. JRA */
2925   if(global_oplocks_open < 0)
2926   {
2927     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2928               global_oplocks_open));
2929     exit_server("oplock_break: global_oplocks_open < 0");
2930   }
2931
2932   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2933 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2934
2935   return True;
2936 }
2937
2938 /****************************************************************************
2939 Send an oplock break message to another smbd process. If the oplock is held 
2940 by the local smbd then call the oplock break function directly.
2941 ****************************************************************************/
2942
2943 BOOL request_oplock_break(share_mode_entry *share_entry, 
2944                           uint32 dev, uint32 inode)
2945 {
2946   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2947   struct sockaddr_in addr_out;
2948   int pid = getpid();
2949
2950   if(pid == share_entry->pid)
2951   {
2952     /* We are breaking our own oplock, make sure it's us. */
2953     if(share_entry->op_port != oplock_port)
2954     {
2955       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2956 should be %d\n", pid, share_entry->op_port, oplock_port));
2957       return False;
2958     }
2959
2960     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2961
2962     /* Call oplock break direct. */
2963     return oplock_break(dev, inode, &share_entry->time);
2964   }
2965
2966   /* We need to send a OPLOCK_BREAK_CMD message to the
2967      port in the share mode entry. */
2968
2969   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2970   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2971   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2972   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2973   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2974   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2975
2976   /* set the address and port */
2977   bzero((char *)&addr_out,sizeof(addr_out));
2978   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2979   addr_out.sin_port = htons( share_entry->op_port );
2980   addr_out.sin_family = AF_INET;
2981    
2982   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2983 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
2984
2985   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2986          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2987   {
2988     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2989 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2990          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
2991          strerror(errno)));
2992     return False;
2993   }
2994
2995   /*
2996    * Now we must await the oplock broken message coming back
2997    * from the target smbd process. Timeout if it fails to
2998    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
2999    * While we get messages that aren't ours, loop.
3000    */
3001
3002   while(1)
3003   {
3004     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3005     int32 reply_msg_len;
3006     uint16 reply_from_port;
3007     char *reply_msg_start;
3008
3009     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3010                (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3011     {
3012       if(smb_read_error == READ_TIMEOUT)
3013       {
3014         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3015 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3016                            share_entry->op_port, dev, inode));
3017         /*
3018          * This is a hack to make handling of failing clients more robust.
3019          * If a oplock break response message is not received in the timeout
3020          * period we may assume that the smbd servicing that client holding
3021          * the oplock has died and the client changes were lost anyway, so
3022          * we should continue to try and open the file.
3023          */
3024         break;
3025       }
3026       else
3027         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3028 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3029                          share_entry->op_port, dev, inode, strerror(errno)));
3030       return False;
3031     }
3032
3033     /* 
3034      * If the response we got was not an answer to our message, but
3035      * was a completely different request, push it onto the pending
3036      * udp message stack so that we can deal with it in the main loop.
3037      * It may be another oplock break request to us.
3038      */
3039
3040     /*
3041      * Local note from JRA. There exists the possibility of a denial
3042      * of service attack here by allowing non-root processes running
3043      * on a local machine sending many of these pending messages to
3044      * a smbd port. Currently I'm not sure how to restrict the messages
3045      * I will queue (although I could add a limit to the queue) to
3046      * those received by root processes only. There should be a 
3047      * way to make this bulletproof....
3048      */
3049
3050     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3051     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3052
3053     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3054
3055     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3056     {
3057       /* Ignore it. */
3058       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3059              timestring()));
3060       continue;
3061     }
3062
3063     if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3064        (reply_from_port != share_entry->op_port) ||
3065        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3066                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3067                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3068     {
3069       DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3070 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3071              timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3072       if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3073         return False;
3074       continue;
3075     }
3076
3077     break;
3078   }
3079
3080   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3081
3082   return True;
3083 }
3084
3085 /****************************************************************************
3086 check if a snum is in use
3087 ****************************************************************************/
3088 BOOL snum_used(int snum)
3089 {
3090   int i;
3091   for (i=0;i<MAX_CONNECTIONS;i++)
3092     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3093       return(True);
3094   return(False);
3095 }
3096
3097 /****************************************************************************
3098   reload the services file
3099   **************************************************************************/
3100 BOOL reload_services(BOOL test)
3101 {
3102   BOOL ret;
3103
3104   if (lp_loaded())
3105     {
3106       pstring fname;
3107       pstrcpy(fname,lp_configfile());
3108       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3109         {
3110           pstrcpy(servicesf,fname);
3111           test = False;
3112         }
3113     }
3114
3115   reopen_logs();
3116
3117   if (test && !lp_file_list_changed())
3118     return(True);
3119
3120   lp_killunused(snum_used);
3121
3122   ret = lp_load(servicesf,False);
3123
3124   /* perhaps the config filename is now set */
3125   if (!test)
3126     reload_services(True);
3127
3128   reopen_logs();
3129
3130   load_interfaces();
3131
3132   {
3133     extern int Client;
3134     if (Client != -1) {      
3135       set_socket_options(Client,"SO_KEEPALIVE");
3136       set_socket_options(Client,user_socket_options);
3137     }
3138   }
3139
3140   reset_mangled_stack( lp_mangledstack() );
3141
3142   /* this forces service parameters to be flushed */
3143   become_service(-1,True);
3144
3145   return(ret);
3146 }
3147
3148
3149
3150 /****************************************************************************
3151 this prevents zombie child processes
3152 ****************************************************************************/
3153 static int sig_hup()
3154 {
3155   BlockSignals(True,SIGHUP);
3156   DEBUG(0,("Got SIGHUP\n"));
3157   reload_services(False);
3158 #ifndef DONT_REINSTALL_SIG
3159   signal(SIGHUP,SIGNAL_CAST sig_hup);
3160 #endif
3161   BlockSignals(False,SIGHUP);
3162   return(0);
3163 }
3164
3165 /****************************************************************************
3166 Setup the groups a user belongs to.
3167 ****************************************************************************/
3168 int setup_groups(char *user, int uid, int gid, int *p_ngroups, 
3169                  int **p_igroups, gid_t **p_groups,
3170          int **p_attrs)
3171 {
3172   if (-1 == initgroups(user,gid))
3173     {
3174       if (getuid() == 0)
3175         {
3176           DEBUG(0,("Unable to initgroups!\n"));
3177           if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3178             DEBUG(0,("This is probably a problem with the account %s\n",user));
3179         }
3180     }
3181   else
3182     {
3183       int i,ngroups;
3184       int *igroups;
3185       int *attrs;
3186       gid_t grp = 0;
3187       ngroups = getgroups(0,&grp);
3188       if (ngroups <= 0)
3189         ngroups = 32;
3190       igroups = (int *)malloc(sizeof(int)*ngroups);
3191       attrs   = (int *)malloc(sizeof(int)*ngroups);
3192       for (i=0;i<ngroups;i++)
3193       {
3194         attrs  [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3195         igroups[i] = 0x42424242;
3196       }
3197       ngroups = getgroups(ngroups,(gid_t *)igroups);
3198
3199       if (igroups[0] == 0x42424242)
3200         ngroups = 0;
3201
3202       *p_ngroups = ngroups;
3203       *p_attrs   = attrs;
3204
3205       /* The following bit of code is very strange. It is due to the
3206          fact that some OSes use int* and some use gid_t* for
3207          getgroups, and some (like SunOS) use both, one in prototypes,
3208          and one in man pages and the actual code. Thus we detect it
3209          dynamically using some very ugly code */
3210       if (ngroups > 0)
3211         {
3212           /* does getgroups return ints or gid_t ?? */
3213           static BOOL groups_use_ints = True;
3214
3215           if (groups_use_ints && 
3216               ngroups == 1 && 
3217               SVAL(igroups,2) == 0x4242)
3218             groups_use_ints = False;
3219           
3220           for (i=0;groups_use_ints && i<ngroups;i++)
3221             if (igroups[i] == 0x42424242)
3222               groups_use_ints = False;
3223               
3224           if (groups_use_ints)
3225           {
3226               *p_igroups = igroups;
3227               *p_groups = (gid_t *)igroups;       
3228           }
3229           else
3230           {
3231               gid_t *groups = (gid_t *)igroups;
3232               igroups = (int *)malloc(sizeof(int)*ngroups);
3233               for (i=0;i<ngroups;i++)
3234           {
3235                 igroups[i] = groups[i];
3236           }
3237               *p_igroups = igroups;
3238               *p_groups = (gid_t *)groups;
3239             }
3240         }
3241       DEBUG(3,("%s is in %d groups\n",user,ngroups));
3242       for (i=0;i<ngroups;i++)
3243         DEBUG(3,("%d ",igroups[i]));
3244       DEBUG(3,("\n"));
3245     }
3246   return 0;
3247 }
3248
3249 /****************************************************************************
3250   make a connection to a service
3251 ****************************************************************************/
3252 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3253 {
3254   int cnum;
3255   int snum;
3256   struct passwd *pass = NULL;
3257   connection_struct *pcon;
3258   BOOL guest = False;
3259   BOOL force = False;
3260   static BOOL first_connection = True;
3261
3262   strlower(service);
3263
3264   snum = find_service(service);
3265   if (snum < 0)
3266     {
3267       if (strequal(service,"IPC$"))
3268         {         
3269           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3270           return(-3);
3271         }
3272
3273       DEBUG(0,("%s couldn't find service %s\n",timestring(),service));      
3274       return(-2);
3275     }
3276
3277   if (strequal(service,HOMES_NAME))
3278     {
3279       if (*user && Get_Pwnam(user,True))
3280         return(make_connection(user,user,password,pwlen,dev,vuid));
3281
3282       if (validated_username(vuid))
3283         {
3284           strcpy(user,validated_username(vuid));
3285           return(make_connection(user,user,password,pwlen,dev,vuid));
3286         }
3287     }
3288
3289   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3290     return(-4);
3291   }
3292
3293   /* you can only connect to the IPC$ service as an ipc device */
3294   if (strequal(service,"IPC$"))
3295     strcpy(dev,"IPC");
3296
3297   if (*dev == '?' || !*dev)
3298     {
3299       if (lp_print_ok(snum))
3300         strcpy(dev,"LPT1:");
3301       else
3302         strcpy(dev,"A:");
3303     }
3304
3305   /* if the request is as a printer and you can't print then refuse */
3306   strupper(dev);
3307   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3308     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3309     return(-6);
3310   }
3311
3312   /* lowercase the user name */
3313   strlower(user);
3314
3315   /* add it as a possible user name */
3316   add_session_user(service);
3317
3318   /* shall we let them in? */
3319   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3320     {
3321       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3322       return(-1);
3323     }
3324   
3325   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3326   if (cnum < 0)
3327     {
3328       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3329       return(-1);
3330     }
3331
3332   pcon = &Connections[cnum];
3333   bzero((char *)pcon,sizeof(*pcon));
3334
3335   /* find out some info about the user */
3336   pass = Get_Pwnam(user,True);
3337
3338   if (pass == NULL)
3339     {
3340       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3341       return(-7);
3342     }
3343
3344   pcon->read_only = lp_readonly(snum);
3345
3346   {
3347     pstring list;
3348     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3349     string_sub(list,"%S",service);
3350
3351     if (user_in_list(user,list))
3352       pcon->read_only = True;
3353
3354     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3355     string_sub(list,"%S",service);
3356
3357     if (user_in_list(user,list))
3358       pcon->read_only = False;    
3359   }
3360
3361   /* admin user check */
3362
3363   /* JRA - original code denied admin user if the share was
3364      marked read_only. Changed as I don't think this is needed,
3365      but old code left in case there is a problem here.
3366    */
3367   if (user_in_list(user,lp_admin_users(snum)) 
3368 #if 0
3369       && !pcon->read_only)
3370 #else
3371       )
3372 #endif
3373     {
3374       pcon->admin_user = True;
3375       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3376     }
3377   else
3378     pcon->admin_user = False;
3379     
3380   pcon->force_user = force;
3381   pcon->vuid = vuid;
3382   pcon->uid = pass->pw_uid;
3383   pcon->gid = pass->pw_gid;
3384   pcon->num_files_open = 0;
3385   pcon->lastused = time(NULL);
3386   pcon->service = snum;
3387   pcon->used = True;
3388   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3389   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3390   pcon->dirptr = NULL;
3391   pcon->veto_list = NULL;
3392   pcon->hide_list = NULL;
3393   string_set(&pcon->dirpath,"");
3394   string_set(&pcon->user,user);
3395
3396 #if HAVE_GETGRNAM 
3397   if (*lp_force_group(snum))
3398     {
3399       struct group *gptr;
3400       pstring gname;
3401
3402       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3403       /* default service may be a group name            */
3404       string_sub(gname,"%S",service);
3405       gptr = (struct group *)getgrnam(gname);
3406
3407       if (gptr)
3408         {
3409           pcon->gid = gptr->gr_gid;
3410           DEBUG(3,("Forced group %s\n",gname));
3411         }
3412       else
3413         DEBUG(1,("Couldn't find group %s\n",gname));
3414     }
3415 #endif
3416
3417   if (*lp_force_user(snum))
3418     {
3419       struct passwd *pass2;
3420       fstring fuser;
3421       fstrcpy(fuser,lp_force_user(snum));
3422       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3423       if (pass2)
3424         {
3425           pcon->uid = pass2->pw_uid;
3426           string_set(&pcon->user,fuser);
3427           fstrcpy(user,fuser);
3428           pcon->force_user = True;
3429           DEBUG(3,("Forced user %s\n",fuser));    
3430         }
3431       else
3432         DEBUG(1,("Couldn't find user %s\n",fuser));
3433     }
3434
3435   {
3436     pstring s;
3437     pstrcpy(s,lp_pathname(snum));
3438     standard_sub(cnum,s);
3439     string_set(&pcon->connectpath,s);
3440     DEBUG(3,("Connect path is %s\n",s));
3441   }
3442
3443   /* groups stuff added by ih */
3444   pcon->ngroups = 0;
3445   pcon->igroups = NULL;
3446   pcon->groups = NULL;
3447   pcon->attrs = NULL;
3448
3449   if (!IS_IPC(cnum))
3450     {
3451       /* Find all the groups this uid is in and store them. Used by become_user() */
3452       setup_groups(pcon->user,pcon->uid,pcon->gid,
3453                   &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3454       
3455       /* check number of connections */
3456       if (!claim_connection(cnum,
3457                             lp_servicename(SNUM(cnum)),
3458                             lp_max_connections(SNUM(cnum)),False))
3459         {
3460           DEBUG(1,("too many connections - rejected\n"));
3461           return(-8);
3462         }  
3463
3464       if (lp_status(SNUM(cnum)))
3465         claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3466
3467       first_connection = False;
3468     } /* IS_IPC */
3469
3470   pcon->open = True;
3471
3472   /* execute any "root preexec = " line */
3473   if (*lp_rootpreexec(SNUM(cnum)))
3474     {
3475       pstring cmd;
3476       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3477       standard_sub(cnum,cmd);
3478       DEBUG(5,("cmd=%s\n",cmd));
3479       smbrun(cmd,NULL,False);
3480     }
3481
3482   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3483     {
3484       DEBUG(0,("Can't become connected user!\n"));
3485       pcon->open = False;
3486       if (!IS_IPC(cnum)) {
3487         yield_connection(cnum,
3488                          lp_servicename(SNUM(cnum)),
3489                          lp_max_connections(SNUM(cnum)));
3490         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3491       }
3492       return(-1);
3493     }
3494
3495   if (ChDir(pcon->connectpath) != 0)
3496     {
3497       DEBUG(0,("Can't change directory to %s (%s)\n",
3498                pcon->connectpath,strerror(errno)));
3499       pcon->open = False;
3500       unbecome_user();
3501       if (!IS_IPC(cnum)) {
3502         yield_connection(cnum,
3503                          lp_servicename(SNUM(cnum)),
3504                          lp_max_connections(SNUM(cnum)));
3505         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3506       }
3507       return(-5);      
3508     }
3509
3510   string_set(&pcon->origpath,pcon->connectpath);
3511
3512 #if SOFTLINK_OPTIMISATION
3513   /* resolve any soft links early */
3514   {
3515     pstring s;
3516     pstrcpy(s,pcon->connectpath);
3517     GetWd(s);
3518     string_set(&pcon->connectpath,s);
3519     ChDir(pcon->connectpath);
3520   }
3521 #endif
3522
3523   num_connections_open++;
3524   add_session_user(user);
3525   
3526   /* execute any "preexec = " line */
3527   if (*lp_preexec(SNUM(cnum)))
3528     {
3529       pstring cmd;
3530       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3531       standard_sub(cnum,cmd);
3532       smbrun(cmd,NULL,False);
3533     }
3534   
3535   /* we've finished with the sensitive stuff */
3536   unbecome_user();
3537
3538   /* Add veto/hide lists */
3539   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3540   {
3541     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3542     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3543   }
3544
3545   {
3546     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3547                             timestring(),
3548                             remote_machine,
3549                             client_addr(),
3550                             lp_servicename(SNUM(cnum)),user,
3551                             pcon->uid,
3552                             pcon->gid,
3553                             (int)getpid()));
3554   }
3555
3556   return(cnum);
3557 }
3558
3559
3560 /****************************************************************************
3561   find first available file slot
3562 ****************************************************************************/
3563 int find_free_file(void )
3564 {
3565   int i;
3566   /* we start at 1 here for an obscure reason I can't now remember,
3567      but I think is important :-) */
3568   for (i=1;i<MAX_OPEN_FILES;i++)
3569     if (!Files[i].open)
3570       return(i);
3571   DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3572   return(-1);
3573 }
3574
3575 /****************************************************************************
3576   find first available connection slot, starting from a random position.
3577 The randomisation stops problems with the server dieing and clients
3578 thinking the server is still available.
3579 ****************************************************************************/
3580 static int find_free_connection(int hash )
3581 {
3582   int i;
3583   BOOL used=False;
3584   hash = (hash % (MAX_CONNECTIONS-2))+1;
3585
3586  again:
3587
3588   for (i=hash+1;i!=hash;)
3589     {
3590       if (!Connections[i].open && Connections[i].used == used) 
3591         {
3592           DEBUG(3,("found free connection number %d\n",i));
3593           return(i);
3594         }
3595       i++;
3596       if (i == MAX_CONNECTIONS)
3597         i = 1;
3598     }
3599
3600   if (!used)
3601     {
3602       used = !used;
3603       goto again;
3604     }
3605
3606   DEBUG(1,("ERROR! Out of connection structures\n"));
3607   return(-1);
3608 }
3609
3610
3611 /****************************************************************************
3612 reply for the core protocol
3613 ****************************************************************************/
3614 int reply_corep(char *outbuf)
3615 {
3616   int outsize = set_message(outbuf,1,0,True);
3617
3618   Protocol = PROTOCOL_CORE;
3619
3620   return outsize;
3621 }
3622
3623
3624 /****************************************************************************
3625 reply for the coreplus protocol
3626 ****************************************************************************/
3627 int reply_coreplus(char *outbuf)
3628 {
3629   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3630   int outsize = set_message(outbuf,13,0,True);
3631   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3632                                  readbraw and writebraw (possibly) */
3633   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3634   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3635
3636   Protocol = PROTOCOL_COREPLUS;
3637
3638   return outsize;
3639 }
3640
3641
3642 /****************************************************************************
3643 reply for the lanman 1.0 protocol
3644 ****************************************************************************/
3645 int reply_lanman1(char *outbuf)
3646 {
3647   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3648   int secword=0;
3649   BOOL doencrypt = SMBENCRYPT();
3650   time_t t = time(NULL);
3651
3652   if (lp_security()>=SEC_USER) secword |= 1;
3653   if (doencrypt) secword |= 2;
3654
3655   set_message(outbuf,13,doencrypt?8:0,True);
3656   SSVAL(outbuf,smb_vwv1,secword); 
3657   /* Create a token value and add it to the outgoing packet. */
3658   if (doencrypt) 
3659     generate_next_challenge(smb_buf(outbuf));
3660
3661   Protocol = PROTOCOL_LANMAN1;
3662
3663   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3664   SSVAL(outbuf,smb_vwv2,max_recv);
3665   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3666   SSVAL(outbuf,smb_vwv4,1);
3667   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3668                                  readbraw writebraw (possibly) */
3669   SIVAL(outbuf,smb_vwv6,getpid());
3670   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3671
3672   put_dos_date(outbuf,smb_vwv8,t);
3673
3674   return (smb_len(outbuf)+4);
3675 }
3676
3677
3678 /****************************************************************************
3679 reply for the lanman 2.0 protocol
3680 ****************************************************************************/
3681 int reply_lanman2(char *outbuf)
3682 {
3683   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3684   int secword=0;
3685   BOOL doencrypt = SMBENCRYPT();
3686   time_t t = time(NULL);
3687   struct cli_state *cli = NULL;
3688   char cryptkey[8];
3689   char crypt_len = 0;
3690
3691   if (lp_security() == SEC_SERVER) {
3692           cli = server_cryptkey();
3693   }
3694
3695   if (cli) {
3696           DEBUG(3,("using password server validation\n"));
3697           doencrypt = ((cli->sec_mode & 2) != 0);
3698   }
3699
3700   if (lp_security()>=SEC_USER) secword |= 1;
3701   if (doencrypt) secword |= 2;
3702
3703   if (doencrypt) {
3704           crypt_len = 8;
3705           if (!cli) {
3706                   generate_next_challenge(cryptkey);
3707           } else {
3708                   memcpy(cryptkey, cli->cryptkey, 8);
3709                   set_challenge(cli->cryptkey);
3710           }
3711   }
3712
3713   set_message(outbuf,13,crypt_len,True);
3714   SSVAL(outbuf,smb_vwv1,secword); 
3715   SIVAL(outbuf,smb_vwv6,getpid());
3716   if (doencrypt) 
3717           memcpy(smb_buf(outbuf), cryptkey, 8);
3718
3719   Protocol = PROTOCOL_LANMAN2;
3720
3721   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3722   SSVAL(outbuf,smb_vwv2,max_recv);
3723   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3724   SSVAL(outbuf,smb_vwv4,1);
3725   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3726   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3727   put_dos_date(outbuf,smb_vwv8,t);
3728
3729   return (smb_len(outbuf)+4);
3730 }
3731
3732
3733 /****************************************************************************
3734 reply for the nt protocol
3735 ****************************************************************************/
3736 int reply_nt1(char *outbuf)
3737 {
3738   /* dual names + lock_and_read + nt SMBs + remote API calls */
3739   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3740 /*
3741   other valid capabilities which we may support at some time...
3742                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3743                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3744  */
3745
3746   int secword=0;
3747   BOOL doencrypt = SMBENCRYPT();
3748   time_t t = time(NULL);
3749   int data_len;
3750   struct cli_state *cli = NULL;
3751   char cryptkey[8];
3752   char crypt_len = 0;
3753
3754   if (lp_security() == SEC_SERVER) {
3755           cli = server_cryptkey();
3756   }
3757
3758   if (cli) {
3759           DEBUG(3,("using password server validation\n"));
3760           doencrypt = ((cli->sec_mode & 2) != 0);
3761   }
3762
3763   if (doencrypt) {
3764           crypt_len = 8;
3765           if (!cli) {
3766                   generate_next_challenge(cryptkey);
3767           } else {
3768                   memcpy(cryptkey, cli->cryptkey, 8);
3769                   set_challenge(cli->cryptkey);
3770           }
3771   }
3772
3773   if (lp_readraw() && lp_writeraw()) {
3774           capabilities |= CAP_RAW_MODE;
3775   }
3776
3777   if (lp_security() >= SEC_USER) secword |= 1;
3778   if (doencrypt) secword |= 2;
3779
3780   /* decide where (if) to put the encryption challenge, and
3781      follow it with the OEM'd domain name
3782    */
3783   data_len = crypt_len + strlen(myworkgroup) + 1;
3784
3785   set_message(outbuf,17,data_len,True);
3786   strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3787
3788   CVAL(outbuf,smb_vwv1) = secword;
3789   SSVALS(outbuf,smb_vwv16+1,crypt_len);
3790   if (doencrypt) 
3791           memcpy(smb_buf(outbuf), cryptkey, 8);
3792
3793   Protocol = PROTOCOL_NT1;
3794
3795   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3796   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3797   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3798   SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3799   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3800   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3801   put_long_date(outbuf+smb_vwv11+1,t);
3802   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3803   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3804
3805   return (smb_len(outbuf)+4);
3806 }
3807
3808 /* these are the protocol lists used for auto architecture detection:
3809
3810 WinNT 3.51:
3811 protocol [PC NETWORK PROGRAM 1.0]
3812 protocol [XENIX CORE]
3813 protocol [MICROSOFT NETWORKS 1.03]
3814 protocol [LANMAN1.0]
3815 protocol [Windows for Workgroups 3.1a]
3816 protocol [LM1.2X002]
3817 protocol [LANMAN2.1]
3818 protocol [NT LM 0.12]
3819
3820 Win95:
3821 protocol [PC NETWORK PROGRAM 1.0]
3822 protocol [XENIX CORE]
3823 protocol [MICROSOFT NETWORKS 1.03]
3824 protocol [LANMAN1.0]
3825 protocol [Windows for Workgroups 3.1a]
3826 protocol [LM1.2X002]
3827 protocol [LANMAN2.1]
3828 protocol [NT LM 0.12]
3829
3830 OS/2:
3831 protocol [PC NETWORK PROGRAM 1.0]
3832 protocol [XENIX CORE]
3833 protocol [LANMAN1.0]
3834 protocol [LM1.2X002]
3835 protocol [LANMAN2.1]
3836 */
3837
3838 /*
3839   * Modified to recognize the architecture of the remote machine better.
3840   *
3841   * This appears to be the matrix of which protocol is used by which
3842   * MS product.
3843        Protocol                       WfWg    Win95   WinNT  OS/2
3844        PC NETWORK PROGRAM 1.0          1       1       1      1
3845        XENIX CORE                                      2      2
3846        MICROSOFT NETWORKS 3.0          2       2       
3847        DOS LM1.2X002                   3       3       
3848        MICROSOFT NETWORKS 1.03                         3
3849        DOS LANMAN2.1                   4       4       
3850        LANMAN1.0                                       4      3
3851        Windows for Workgroups 3.1a     5       5       5
3852        LM1.2X002                                       6      4
3853        LANMAN2.1                                       7      5
3854        NT LM 0.12                              6       8
3855   *
3856   *  tim@fsg.com 09/29/95
3857   */
3858   
3859 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
3860 #define ARCH_WIN95    0x2
3861 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
3862 #define ARCH_WINNT    0x8
3863 #define ARCH_SAMBA    0x10
3864  
3865 #define ARCH_ALL      0x1F
3866  
3867 /* List of supported protocols, most desired first */
3868 struct {
3869   char *proto_name;
3870   char *short_name;
3871   int (*proto_reply_fn)(char *);
3872   int protocol_level;
3873 } supported_protocols[] = {
3874   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
3875   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
3876   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3877   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3878   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
3879   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
3880   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
3881   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3882   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
3883   {NULL,NULL},
3884 };
3885
3886
3887 /****************************************************************************
3888   reply to a negprot
3889 ****************************************************************************/
3890 static int reply_negprot(char *inbuf,char *outbuf)
3891 {
3892   int outsize = set_message(outbuf,1,0,True);
3893   int Index=0;
3894   int choice= -1;
3895   int protocol;
3896   char *p;
3897   int bcc = SVAL(smb_buf(inbuf),-2);