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