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