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