Makefile.in: Moved UBIQX stuff into UTILOBJ.
[samba.git] / source3 / smbd / server.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Main SMB server routines
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "trans2.h"
24
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring global_myworkgroup;
29 extern pstring global_myname;
30
31 char *InBuffer = NULL;
32 char *OutBuffer = NULL;
33 char *last_inbuf = NULL;
34
35 int am_parent = 1;
36
37 /* the last message the was processed */
38 int last_message = -1;
39
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
42
43 extern pstring scope;
44 extern int DEBUGLEVEL;
45 extern int case_default;
46 extern BOOL case_sensitive;
47 extern BOOL case_preserve;
48 extern BOOL use_mangled_map;
49 extern BOOL short_case_preserve;
50 extern BOOL case_mangle;
51 time_t smb_last_time=(time_t)0;
52 extern BOOL global_machine_pasword_needs_changing;
53
54 extern int smb_read_error;
55
56 extern pstring user_socket_options;
57
58 #ifdef WITH_DFS
59 extern int dcelogin_atmost_once;
60 #endif /* WITH_DFS */
61
62 /*
63  * This is set on startup - it defines the SID for this
64  * machine.
65  */
66 extern DOM_SID global_machine_sid;
67
68 connection_struct Connections[MAX_CONNECTIONS];
69 files_struct Files[MAX_FNUMS];
70
71 /*
72  * Indirection for file fd's. Needed as POSIX locking
73  * is based on file/process, not fd/process.
74  */
75 file_fd_struct FileFd[MAX_OPEN_FILES];
76 int max_file_fd_used = 0;
77
78 extern int Protocol;
79
80 /* 
81  * Size of data we can send to client. Set
82  *  by the client for all protocols above CORE.
83  *  Set by us for CORE protocol.
84  */
85 int max_send = BUFFER_SIZE;
86 /*
87  * Size of the data we can receive. Set by us.
88  * Can be modified by the max xmit parameter.
89  */
90 int max_recv = BUFFER_SIZE;
91
92 /* a fnum to use when chaining */
93 int chain_fnum = -1;
94
95 /* number of open connections */
96 static int num_connections_open = 0;
97
98 /* Oplock ipc UDP socket. */
99 int oplock_sock = -1;
100 uint16 oplock_port = 0;
101 /* Current number of oplocks we have outstanding. */
102 int32 global_oplocks_open = 0;
103
104 BOOL global_oplock_break = False;
105
106 extern fstring remote_machine;
107
108 extern pstring OriginalDir;
109
110 /* these can be set by some functions to override the error codes */
111 int unix_ERR_class=SMB_SUCCESS;
112 int unix_ERR_code=0;
113
114
115 extern int extra_time_offset;
116
117 extern pstring myhostname;
118
119 static int find_free_connection(int hash);
120
121 /* for readability... */
122 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
123 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
124 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
125 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
126 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
127
128 /****************************************************************************
129   when exiting, take the whole family
130 ****************************************************************************/
131 void  *dflt_sig(void)
132 {
133   exit_server("caught signal");
134   return 0; /* Keep -Wall happy :-) */
135 }
136 /****************************************************************************
137   Send a SIGTERM to our process group.
138 *****************************************************************************/
139 void  killkids(void)
140 {
141   if(am_parent) kill(0,SIGTERM);
142 }
143
144 /****************************************************************************
145   change a dos mode to a unix mode
146     base permission for files:
147          everybody gets read bit set
148          dos readonly is represented in unix by removing everyone's write bit
149          dos archive is represented in unix by the user's execute bit
150          dos system is represented in unix by the group's execute bit
151          dos hidden is represented in unix by the other's execute bit
152          Then apply create mask,
153          then add force bits.
154     base permission for directories:
155          dos directory is represented in unix by unix's dir bit and the exec bit
156          Then apply create mask,
157          then add force bits.
158 ****************************************************************************/
159 mode_t unix_mode(int cnum,int dosmode)
160 {
161   mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
162
163   if ( !IS_DOS_READONLY(dosmode) )
164     result |= (S_IWUSR | S_IWGRP | S_IWOTH);
165  
166   if (IS_DOS_DIR(dosmode)) {
167     /* We never make directories read only for the owner as under DOS a user
168        can always create a file in a read-only directory. */
169     result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
170     /* Apply directory mask */
171     result &= lp_dir_mode(SNUM(cnum));
172     /* Add in force bits */
173     result |= lp_force_dir_mode(SNUM(cnum));
174   } else { 
175     if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
176       result |= S_IXUSR;
177
178     if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
179       result |= S_IXGRP;
180  
181     if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
182       result |= S_IXOTH;  
183  
184     /* Apply mode mask */
185     result &= lp_create_mode(SNUM(cnum));
186     /* Add in force bits */
187     result |= lp_force_create_mode(SNUM(cnum));
188   }
189   return(result);
190 }
191
192
193 /****************************************************************************
194   change a unix mode to a dos mode
195 ****************************************************************************/
196 int dos_mode(int cnum,char *path,struct stat *sbuf)
197 {
198   int result = 0;
199   extern struct current_user current_user;
200
201   DEBUG(8,("dos_mode: %d %s\n", cnum, path));
202
203   if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
204     if (!((sbuf->st_mode & S_IWOTH) ||
205           Connections[cnum].admin_user ||
206           ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
207           ((sbuf->st_mode & S_IWGRP) && 
208            in_group(sbuf->st_gid,current_user.gid,
209                     current_user.ngroups,current_user.groups))))
210       result |= aRONLY;
211   } else {
212     if ((sbuf->st_mode & S_IWUSR) == 0)
213       result |= aRONLY;
214   }
215
216   if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
217     result |= aARCH;
218
219   if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
220     result |= aSYSTEM;
221
222   if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
223     result |= aHIDDEN;   
224   
225   if (S_ISDIR(sbuf->st_mode))
226     result = aDIR | (result & aRONLY);
227
228 #ifdef S_ISLNK
229 #if LINKS_READ_ONLY
230   if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
231     result |= aRONLY;
232 #endif
233 #endif
234
235   /* hide files with a name starting with a . */
236   if (lp_hide_dot_files(SNUM(cnum)))
237     {
238       char *p = strrchr(path,'/');
239       if (p)
240         p++;
241       else
242         p = path;
243       
244       if (p[0] == '.' && p[1] != '.' && p[1] != 0)
245         result |= aHIDDEN;
246     }
247
248   /* Optimization : Only call is_hidden_path if it's not already
249      hidden. */
250   if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
251   {
252     result |= aHIDDEN;
253   }
254
255   DEBUG(8,("dos_mode returning "));
256
257   if (result & aHIDDEN) DEBUG(8, ("h"));
258   if (result & aRONLY ) DEBUG(8, ("r"));
259   if (result & aSYSTEM) DEBUG(8, ("s"));
260   if (result & aDIR   ) DEBUG(8, ("d"));
261   if (result & aARCH  ) DEBUG(8, ("a"));
262
263   DEBUG(8,("\n"));
264
265   return(result);
266 }
267
268 /*******************************************************************
269 chmod a file - but preserve some bits
270 ********************************************************************/
271 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
272 {
273   struct stat st1;
274   int mask=0;
275   int tmp;
276   int unixmode;
277
278   if (!st) {
279     st = &st1;
280     if (sys_stat(fname,st)) return(-1);
281   }
282
283   if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
284
285   if (dos_mode(cnum,fname,st) == dosmode) return(0);
286
287   unixmode = unix_mode(cnum,dosmode);
288
289   /* preserve the s bits */
290   mask |= (S_ISUID | S_ISGID);
291
292   /* preserve the t bit */
293 #ifdef S_ISVTX
294   mask |= S_ISVTX;
295 #endif
296
297   /* possibly preserve the x bits */
298   if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
299   if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
300   if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
301
302   unixmode |= (st->st_mode & mask);
303
304   /* if we previously had any r bits set then leave them alone */
305   if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
306     unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
307     unixmode |= tmp;
308   }
309
310   /* if we previously had any w bits set then leave them alone 
311    if the new mode is not rdonly */
312   if (!IS_DOS_READONLY(dosmode) &&
313       (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
314     unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
315     unixmode |= tmp;
316   }
317
318   return(sys_chmod(fname,unixmode));
319 }
320
321 /*******************************************************************
322 Wrapper around sys_utime that possibly allows DOS semantics rather
323 than POSIX.
324 *******************************************************************/
325
326 int file_utime(int cnum, char *fname, struct utimbuf *times)
327 {
328   extern struct current_user current_user;
329   struct stat sb;
330   int ret = -1;
331
332   errno = 0;
333
334   if(sys_utime(fname, times) == 0)
335     return 0;
336
337   if((errno != EPERM) && (errno != EACCES))
338     return -1;
339
340   if(!lp_dos_filetimes(SNUM(cnum)))
341     return -1;
342
343   /* We have permission (given by the Samba admin) to
344      break POSIX semantics and allow a user to change
345      the time on a file they don't own but can write to
346      (as DOS does).
347    */
348
349   if(sys_stat(fname,&sb) != 0)
350     return -1;
351
352   /* Check if we have write access. */
353   if (CAN_WRITE(cnum)) {
354           if (((sb.st_mode & S_IWOTH) ||
355                Connections[cnum].admin_user ||
356                ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
357                ((sb.st_mode & S_IWGRP) &&
358                 in_group(sb.st_gid,current_user.gid,
359                          current_user.ngroups,current_user.groups)))) {
360                   /* We are allowed to become root and change the filetime. */
361                   become_root(False);
362                   ret = sys_utime(fname, times);
363                   unbecome_root(False);
364           }
365   }
366
367   return ret;
368 }
369   
370 /*******************************************************************
371 Change a filetime - possibly allowing DOS semantics.
372 *******************************************************************/
373
374 BOOL set_filetime(int cnum, char *fname, time_t mtime)
375 {
376   struct utimbuf times;
377
378   if (null_mtime(mtime)) return(True);
379
380   times.modtime = times.actime = mtime;
381
382   if (file_utime(cnum, fname, &times)) {
383     DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
384   }
385   
386   return(True);
387
388
389 /****************************************************************************
390 check if two filenames are equal
391
392 this needs to be careful about whether we are case sensitive
393 ****************************************************************************/
394 static BOOL fname_equal(char *name1, char *name2)
395 {
396   int l1 = strlen(name1);
397   int l2 = strlen(name2);
398
399   /* handle filenames ending in a single dot */
400   if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
401     {
402       BOOL ret;
403       name1[l1-1] = 0;
404       ret = fname_equal(name1,name2);
405       name1[l1-1] = '.';
406       return(ret);
407     }
408
409   if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
410     {
411       BOOL ret;
412       name2[l2-1] = 0;
413       ret = fname_equal(name1,name2);
414       name2[l2-1] = '.';
415       return(ret);
416     }
417
418   /* now normal filename handling */
419   if (case_sensitive)
420     return(strcmp(name1,name2) == 0);
421
422   return(strequal(name1,name2));
423 }
424
425
426 /****************************************************************************
427 mangle the 2nd name and check if it is then equal to the first name
428 ****************************************************************************/
429 static BOOL mangled_equal(char *name1, char *name2)
430 {
431   pstring tmpname;
432
433   if (is_8_3(name2, True))
434     return(False);
435
436   pstrcpy(tmpname,name2);
437   mangle_name_83(tmpname,sizeof(tmpname));
438
439   return(strequal(name1,tmpname));
440 }
441
442
443 /****************************************************************************
444 scan a directory to find a filename, matching without case sensitivity
445
446 If the name looks like a mangled name then try via the mangling functions
447 ****************************************************************************/
448 static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
449 {
450   void *cur_dir;
451   char *dname;
452   BOOL mangled;
453   pstring name2;
454
455   mangled = is_mangled(name);
456
457   /* handle null paths */
458   if (*path == 0)
459     path = ".";
460
461   if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
462     pstrcpy(name, dname);       
463     return(True);
464   }      
465
466   /*
467    * The incoming name can be mangled, and if we de-mangle it
468    * here it will not compare correctly against the filename (name2)
469    * read from the directory and then mangled by the name_map_mangle()
470    * call. We need to mangle both names or neither.
471    * (JRA).
472    */
473   if (mangled)
474     mangled = !check_mangled_cache( name );
475
476   /* open the directory */
477   if (!(cur_dir = OpenDir(cnum, path, True))) 
478     {
479       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
480       return(False);
481     }
482
483   /* now scan for matching names */
484   while ((dname = ReadDirName(cur_dir))) 
485     {
486       if (*dname == '.' &&
487           (strequal(dname,".") || strequal(dname,"..")))
488         continue;
489
490       pstrcpy(name2,dname);
491       if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
492
493       if ((mangled && mangled_equal(name,name2))
494           || fname_equal(name, name2))
495         {
496           /* we've found the file, change it's name and return */
497           if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
498           pstrcpy(name, dname);
499           CloseDir(cur_dir);
500           return(True);
501         }
502     }
503
504   CloseDir(cur_dir);
505   return(False);
506 }
507
508 /****************************************************************************
509 This routine is called to convert names from the dos namespace to unix
510 namespace. It needs to handle any case conversions, mangling, format
511 changes etc.
512
513 We assume that we have already done a chdir() to the right "root" directory
514 for this service.
515
516 The function will return False if some part of the name except for the last
517 part cannot be resolved
518
519 If the saved_last_component != 0, then the unmodified last component
520 of the pathname is returned there. This is used in an exceptional
521 case in reply_mv (so far). If saved_last_component == 0 then nothing
522 is returned there.
523
524 The bad_path arg is set to True if the filename walk failed. This is
525 used to pick the correct error code to return between ENOENT and ENOTDIR
526 as Windows applications depend on ERRbadpath being returned if a component
527 of a pathname does not exist.
528 ****************************************************************************/
529 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
530 {
531   struct stat st;
532   char *start, *end;
533   pstring dirpath;
534   int saved_errno;
535
536   *dirpath = 0;
537   *bad_path = False;
538
539   if(saved_last_component)
540     *saved_last_component = 0;
541
542   /* convert to basic unix format - removing \ chars and cleaning it up */
543   unix_format(name);
544   unix_clean_name(name);
545
546   /* names must be relative to the root of the service - trim any leading /.
547    also trim trailing /'s */
548   trim_string(name,"/","/");
549
550   /*
551    * Ensure saved_last_component is valid even if file exists.
552    */
553   if(saved_last_component) {
554     end = strrchr(name, '/');
555     if(end)
556       pstrcpy(saved_last_component, end + 1);
557     else
558       pstrcpy(saved_last_component, name);
559   }
560
561   if (!case_sensitive && 
562       (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
563     strnorm(name);
564
565   /* check if it's a printer file */
566   if (Connections[cnum].printer)
567     {
568       if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
569         {
570           char *s;
571           fstring name2;
572           slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
573           /* sanitise the name */
574           for (s=name2 ; *s ; s++)
575             if (!issafe(*s)) *s = '_';
576           pstrcpy(name,(char *)mktemp(name2));    
577         }      
578       return(True);
579     }
580
581   /* stat the name - if it exists then we are all done! */
582   if (sys_stat(name,&st) == 0)
583     return(True);
584
585   saved_errno = errno;
586
587   DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
588
589   /* a special case - if we don't have any mangling chars and are case
590      sensitive then searching won't help */
591   if (case_sensitive && !is_mangled(name) && 
592       !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
593     return(False);
594
595   /* now we need to recursively match the name against the real 
596      directory structure */
597
598   start = name;
599   while (strncmp(start,"./",2) == 0)
600     start += 2;
601
602   /* now match each part of the path name separately, trying the names
603      as is first, then trying to scan the directory for matching names */
604   for (;start;start = (end?end+1:(char *)NULL)) 
605     {
606       /* pinpoint the end of this section of the filename */
607       end = strchr(start, '/');
608
609       /* chop the name at this point */
610       if (end)  *end = 0;
611
612       if(saved_last_component != 0)
613         pstrcpy(saved_last_component, end ? end + 1 : start);
614
615       /* check if the name exists up to this point */
616       if (sys_stat(name, &st) == 0) 
617         {
618           /* it exists. it must either be a directory or this must be
619              the last part of the path for it to be OK */
620           if (end && !(st.st_mode & S_IFDIR)) 
621             {
622               /* an intermediate part of the name isn't a directory */
623               DEBUG(5,("Not a dir %s\n",start));
624               *end = '/';
625               return(False);
626             }
627         }
628       else 
629         {
630           pstring rest;
631
632           *rest = 0;
633
634           /* remember the rest of the pathname so it can be restored
635              later */
636           if (end) pstrcpy(rest,end+1);
637
638           /* try to find this part of the path in the directory */
639           if (strchr(start,'?') || strchr(start,'*') ||
640               !scan_directory(dirpath, start, cnum, end?True:False))
641             {
642               if (end) 
643                 {
644                   /* an intermediate part of the name can't be found */
645                   DEBUG(5,("Intermediate not found %s\n",start));
646                   *end = '/';
647                   /* We need to return the fact that the intermediate
648                      name resolution failed. This is used to return an
649                      error of ERRbadpath rather than ERRbadfile. Some
650                      Windows applications depend on the difference between
651                      these two errors.
652                    */
653                   *bad_path = True;
654                   return(False);
655                 }
656               
657               /* just the last part of the name doesn't exist */
658               /* we may need to strupper() or strlower() it in case
659                  this conversion is being used for file creation 
660                  purposes */
661               /* if the filename is of mixed case then don't normalise it */
662               if (!case_preserve && 
663                   (!strhasupper(start) || !strhaslower(start)))         
664                 strnorm(start);
665
666               /* check on the mangled stack to see if we can recover the 
667                  base of the filename */
668               if (is_mangled(start))
669                 check_mangled_cache( start );
670
671               DEBUG(5,("New file %s\n",start));
672               return(True); 
673             }
674
675           /* restore the rest of the string */
676           if (end) 
677             {
678               pstrcpy(start+strlen(start)+1,rest);
679               end = start + strlen(start);
680             }
681         }
682
683       /* add to the dirpath that we have resolved so far */
684       if (*dirpath) pstrcat(dirpath,"/");
685       pstrcat(dirpath,start);
686
687       /* restore the / that we wiped out earlier */
688       if (end) *end = '/';
689     }
690   
691   /* the name has been resolved */
692   DEBUG(5,("conversion finished %s\n",name));
693   return(True);
694 }
695
696
697 /****************************************************************************
698 check a filename - possibly caling reducename
699
700 This is called by every routine before it allows an operation on a filename.
701 It does any final confirmation necessary to ensure that the filename is
702 a valid one for the user to access.
703 ****************************************************************************/
704 BOOL check_name(char *name,int cnum)
705 {
706   BOOL ret;
707
708   errno = 0;
709
710   if( IS_VETO_PATH(cnum, name)) 
711     {
712       DEBUG(5,("file path name %s vetoed\n",name));
713       return(0);
714     }
715
716   ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
717
718   /* Check if we are allowing users to follow symlinks */
719   /* Patch from David Clerc <David.Clerc@cui.unige.ch>
720      University of Geneva */
721
722 #ifdef S_ISLNK
723   if (!lp_symlinks(SNUM(cnum)))
724     {
725       struct stat statbuf;
726       if ( (sys_lstat(name,&statbuf) != -1) &&
727           (S_ISLNK(statbuf.st_mode)) )
728         {
729           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
730           ret=0; 
731         }
732     }
733 #endif
734
735   if (!ret)
736     DEBUG(5,("check_name on %s failed\n",name));
737
738   return(ret);
739 }
740
741 /****************************************************************************
742 check a filename - possibly caling reducename
743 ****************************************************************************/
744 static void check_for_pipe(char *fname)
745 {
746   /* special case of pipe opens */
747   char s[10];
748   StrnCpy(s,fname,9);
749   strlower(s);
750   if (strstr(s,"pipe/"))
751     {
752       DEBUG(3,("Rejecting named pipe open for %s\n",fname));
753       unix_ERR_class = ERRSRV;
754       unix_ERR_code = ERRaccess;
755     }
756 }
757
758 /****************************************************************************
759 fd support routines - attempt to do a sys_open
760 ****************************************************************************/
761 static int fd_attempt_open(char *fname, int flags, int mode)
762 {
763   int fd = sys_open(fname,flags,mode);
764
765   /* Fix for files ending in '.' */
766   if((fd == -1) && (errno == ENOENT) &&
767      (strchr(fname,'.')==NULL))
768     {
769       pstrcat(fname,".");
770       fd = sys_open(fname,flags,mode);
771     }
772
773 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
774   if ((fd == -1) && (errno == ENAMETOOLONG))
775     {
776       int max_len;
777       char *p = strrchr(fname, '/');
778
779       if (p == fname)   /* name is "/xxx" */
780         {
781           max_len = pathconf("/", _PC_NAME_MAX);
782           p++;
783         }
784       else if ((p == NULL) || (p == fname))
785         {
786           p = fname;
787           max_len = pathconf(".", _PC_NAME_MAX);
788         }
789       else
790         {
791           *p = '\0';
792           max_len = pathconf(fname, _PC_NAME_MAX);
793           *p = '/';
794           p++;
795         }
796       if (strlen(p) > max_len)
797         {
798           char tmp = p[max_len];
799
800           p[max_len] = '\0';
801           if ((fd = sys_open(fname,flags,mode)) == -1)
802             p[max_len] = tmp;
803         }
804     }
805 #endif
806   return fd;
807 }
808
809 /****************************************************************************
810 Cache a uid_t currently with this file open. This is an optimization only
811 used when multiple sessionsetup's have been done to one smbd.
812 ****************************************************************************/
813 static void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
814 {
815   if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
816     return;
817   fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
818 }
819
820 /****************************************************************************
821 Remove a uid_t that currently has this file open. This is an optimization only
822 used when multiple sessionsetup's have been done to one smbd.
823 ****************************************************************************/
824 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
825 {
826   int i;
827   for(i = 0; i < fd_ptr->uid_cache_count; i++)
828     if(fd_ptr->uid_users_cache[i] == u) {
829       if(i < (fd_ptr->uid_cache_count-1))
830         memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
831                sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
832       fd_ptr->uid_cache_count--;
833     }
834   return;
835 }
836
837 /****************************************************************************
838 Check if a uid_t that currently has this file open is present. This is an
839 optimization only used when multiple sessionsetup's have been done to one smbd.
840 ****************************************************************************/
841 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
842 {
843   int i;
844   for(i = 0; i < fd_ptr->uid_cache_count; i++)
845     if(fd_ptr->uid_users_cache[i] == u)
846       return True;
847   return False;
848 }
849
850 /****************************************************************************
851 fd support routines - attempt to find an already open file by dev
852 and inode - increments the ref_count of the returned file_fd_struct *.
853 ****************************************************************************/
854 static file_fd_struct *fd_get_already_open(struct stat *sbuf)
855 {
856   int i;
857   file_fd_struct *fd_ptr;
858
859   if(sbuf == 0)
860     return 0;
861
862   for(i = 0; i <= max_file_fd_used; i++) {
863     fd_ptr = &FileFd[i];
864     if((fd_ptr->ref_count > 0) &&
865        (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
866        (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
867       fd_ptr->ref_count++;
868       DEBUG(3,
869        ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
870         i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
871       return fd_ptr;
872     }
873   }
874   return 0;
875 }
876
877 /****************************************************************************
878 fd support routines - attempt to find a empty slot in the FileFd array.
879 Increments the ref_count of the returned entry.
880 ****************************************************************************/
881 static file_fd_struct *fd_get_new(void)
882 {
883   extern struct current_user current_user;
884   int i;
885   file_fd_struct *fd_ptr;
886
887   for(i = 0; i < MAX_OPEN_FILES; i++) {
888     fd_ptr = &FileFd[i];
889     if(fd_ptr->ref_count == 0) {
890       fd_ptr->dev = (uint32)-1;
891       fd_ptr->inode = (uint32)-1;
892       fd_ptr->fd = -1;
893       fd_ptr->fd_readonly = -1;
894       fd_ptr->fd_writeonly = -1;
895       fd_ptr->real_open_flags = -1;
896       fd_ptr->uid_cache_count = 0;
897       fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
898       fd_ptr->ref_count++;
899       /* Increment max used counter if neccessary, cuts down
900          on search time when re-using */
901       if(i > max_file_fd_used)
902         max_file_fd_used = i;
903       DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
904                i, fd_ptr->dev, fd_ptr->inode));
905       return fd_ptr;
906     }
907   }
908   DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\n"));
909   return 0;
910 }
911
912 /****************************************************************************
913 fd support routines - attempt to re-open an already open fd as O_RDWR.
914 Save the already open fd (we cannot close due to POSIX file locking braindamage.
915 ****************************************************************************/
916 static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
917 {
918   int fd = sys_open( fname, O_RDWR, mode);
919
920   if(fd == -1)
921     return;
922
923   if(fd_ptr->real_open_flags == O_RDONLY)
924     fd_ptr->fd_readonly = fd_ptr->fd;
925   if(fd_ptr->real_open_flags == O_WRONLY)
926     fd_ptr->fd_writeonly = fd_ptr->fd;
927
928   fd_ptr->fd = fd;
929   fd_ptr->real_open_flags = O_RDWR;
930 }
931
932 /****************************************************************************
933 fd support routines - attempt to close the file referenced by this fd.
934 Decrements the ref_count and returns it.
935 ****************************************************************************/
936 static int fd_attempt_close(file_fd_struct *fd_ptr)
937 {
938   extern struct current_user current_user;
939
940   DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
941           fd_ptr - &FileFd[0],
942           fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
943           fd_ptr->real_open_flags,
944           fd_ptr->ref_count));
945   if(fd_ptr->ref_count > 0) {
946     fd_ptr->ref_count--;
947     if(fd_ptr->ref_count == 0) {
948       if(fd_ptr->fd != -1)
949         close(fd_ptr->fd);
950       if(fd_ptr->fd_readonly != -1)
951         close(fd_ptr->fd_readonly);
952       if(fd_ptr->fd_writeonly != -1)
953         close(fd_ptr->fd_writeonly);
954       fd_ptr->fd = -1;
955       fd_ptr->fd_readonly = -1;
956       fd_ptr->fd_writeonly = -1;
957       fd_ptr->real_open_flags = -1;
958       fd_ptr->dev = (uint32)-1;
959       fd_ptr->inode = (uint32)-1;
960       fd_ptr->uid_cache_count = 0;
961     } else
962       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
963   } 
964  return fd_ptr->ref_count;
965 }
966
967 /****************************************************************************
968 fd support routines - check that current user has permissions
969 to open this file. Used when uid not found in optimization cache.
970 This is really ugly code, as due to POSIX locking braindamage we must
971 fork and then attempt to open the file, and return success or failure
972 via an exit code.
973 ****************************************************************************/
974 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
975 {
976   pid_t child_pid;
977
978   if((child_pid = fork()) < 0) {
979     DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
980     return False;
981   }
982
983   if(child_pid) {
984     /*
985      * Parent.
986      */
987     pid_t wpid;
988     int status_code;
989     if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
990       DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
991       return(False);
992     }
993
994     if (child_pid != wpid) {
995       DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
996       return(False);
997     }
998 #if defined(WIFEXITED) && defined(WEXITSTATUS)
999     if (WIFEXITED(status_code) == 0) {
1000       DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
1001       return(False);
1002     }
1003     if (WEXITSTATUS(status_code) != 0) {
1004       DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1005       return(False);
1006     }
1007 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1008     if(status_code != 0) {
1009       DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
1010       return(False);
1011     }
1012 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
1013
1014     /*
1015      * Success - the child could open the file.
1016      */
1017     DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
1018     return True;
1019   } else {
1020     /*
1021      * Child.
1022      */
1023     int fd;
1024     DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
1025     if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
1026       /* Access denied. */
1027       _exit(EACCES);
1028     }
1029     close(fd);
1030     DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
1031     _exit(0);
1032   }
1033
1034   return False;
1035 }
1036
1037 /****************************************************************************
1038 open a file
1039 ****************************************************************************/
1040 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
1041 {
1042   extern struct current_user current_user;
1043   pstring fname;
1044   struct stat statbuf;
1045   file_fd_struct *fd_ptr;
1046   files_struct *fsp = &Files[fnum];
1047   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1048
1049   fsp->open = False;
1050   fsp->f_u.fd_ptr = 0;
1051   fsp->granted_oplock = False;
1052   errno = EPERM;
1053
1054   pstrcpy(fname,fname1);
1055
1056   /* check permissions */
1057
1058   /*
1059    * This code was changed after seeing a client open request 
1060    * containing the open mode of (DENY_WRITE/read-only) with
1061    * the 'create if not exist' bit set. The previous code
1062    * would fail to open the file read only on a read-only share
1063    * as it was checking the flags parameter  directly against O_RDONLY,
1064    * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1065    * JRA.
1066    */
1067
1068   if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
1069     /* It's a read-only share - fail if we wanted to write. */
1070     if(accmode != O_RDONLY) {
1071       DEBUG(3,("Permission denied opening %s\n",fname));
1072       check_for_pipe(fname);
1073       return;
1074     }
1075     else if(flags & O_CREAT) {
1076       /* We don't want to write - but we must make sure that O_CREAT
1077          doesn't create the file if we have write access into the
1078          directory.
1079        */
1080       flags &= ~O_CREAT;
1081     }
1082   }
1083
1084   /* this handles a bug in Win95 - it doesn't say to create the file when it 
1085      should */
1086   if (Connections[cnum].printer)
1087     flags |= O_CREAT;
1088
1089 /*
1090   if (flags == O_WRONLY)
1091     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1092 */
1093
1094   /*
1095    * Ensure we have a valid struct stat so we can search the
1096    * open fd table.
1097    */
1098   if(sbuf == 0) {
1099     if(sys_stat(fname, &statbuf) < 0) {
1100       if(errno != ENOENT) {
1101         DEBUG(3,("Error doing stat on file %s (%s)\n",
1102                  fname,strerror(errno)));
1103
1104         check_for_pipe(fname);
1105         return;
1106       }
1107       sbuf = 0;
1108     } else {
1109       sbuf = &statbuf;
1110     }
1111   }
1112
1113   /*
1114    * Check to see if we have this file already
1115    * open. If we do, just use the already open fd and increment the
1116    * reference count (fd_get_already_open increments the ref_count).
1117    */
1118   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1119     /*
1120      * File was already open.
1121      */
1122
1123     /* 
1124      * Check it wasn't open for exclusive use.
1125      */
1126     if((flags & O_CREAT) && (flags & O_EXCL)) {
1127       fd_ptr->ref_count--;
1128       errno = EEXIST;
1129       return;
1130     }
1131
1132     /*
1133      * Ensure that the user attempting to open
1134      * this file has permissions to do so, if
1135      * the user who originally opened the file wasn't
1136      * the same as the current user.
1137      */
1138
1139     if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
1140       if(!check_access_allowed_for_current_user( fname, accmode )) {
1141         /* Error - permission denied. */
1142         DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
1143               fname, flags, accmode));
1144         /* Ensure the ref_count is decremented. */
1145         fd_ptr->ref_count--;
1146         fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1147         errno = EACCES;
1148         return;
1149       }
1150     }
1151
1152     fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
1153
1154     /* 
1155      * If not opened O_RDWR try
1156      * and do that here - a chmod may have been done
1157      * between the last open and now. 
1158      */
1159     if(fd_ptr->real_open_flags != O_RDWR)
1160       fd_attempt_reopen(fname, mode, fd_ptr);
1161
1162     /*
1163      * Ensure that if we wanted write access
1164      * it has been opened for write, and if we wanted read it
1165      * was open for read. 
1166      */
1167     if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
1168        ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
1169        ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
1170       DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1171                fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
1172       check_for_pipe(fname);
1173       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
1174       fd_ptr->ref_count--;
1175       return;
1176     }
1177
1178   } else {
1179     int open_flags;
1180     /* We need to allocate a new file_fd_struct (this increments the
1181        ref_count). */
1182     if((fd_ptr = fd_get_new()) == 0)
1183       return;
1184     /*
1185      * Whatever the requested flags, attempt read/write access,
1186      * as we don't know what flags future file opens may require.
1187      * If this fails, try again with the required flags. 
1188      * Even if we open read/write when only read access was 
1189      * requested the setting of the can_write flag in
1190      * the file_struct will protect us from errant
1191      * write requests. We never need to worry about O_APPEND
1192      * as this is not set anywhere in Samba.
1193      */
1194     fd_ptr->real_open_flags = O_RDWR;
1195     /* Set the flags as needed without the read/write modes. */
1196     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
1197     fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
1198     /*
1199      * On some systems opening a file for R/W access on a read only
1200      * filesystems sets errno to EROFS.
1201      */
1202 #ifdef EROFS
1203     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
1204 #else /* No EROFS */
1205     if((fd_ptr->fd == -1) && (errno == EACCES)) {
1206 #endif /* EROFS */
1207       if(accmode != O_RDWR) {
1208         fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
1209         fd_ptr->real_open_flags = accmode;
1210       }
1211     }
1212   }
1213
1214   if ((fd_ptr->fd >=0) && 
1215       Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
1216     pstring dname;
1217     int dum1,dum2,dum3;
1218     char *p;
1219     pstrcpy(dname,fname);
1220     p = strrchr(dname,'/');
1221     if (p) *p = 0;
1222     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
1223         lp_minprintspace(SNUM(cnum))) {
1224       fd_attempt_close(fd_ptr);
1225       fsp->f_u.fd_ptr = 0;
1226       if(fd_ptr->ref_count == 0)
1227         sys_unlink(fname);
1228       errno = ENOSPC;
1229       return;
1230     }
1231   }
1232     
1233   if (fd_ptr->fd < 0)
1234   {
1235     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1236       fname,strerror(errno),flags));
1237     /* Ensure the ref_count is decremented. */
1238     fd_attempt_close(fd_ptr);
1239     check_for_pipe(fname);
1240     return;
1241   }
1242
1243   if (fd_ptr->fd >= 0)
1244   {
1245     if(sbuf == 0) {
1246       /* Do the fstat */
1247       if(fstat(fd_ptr->fd, &statbuf) == -1) {
1248         /* Error - backout !! */
1249         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1250                  fd_ptr->fd, fname,strerror(errno)));
1251         /* Ensure the ref_count is decremented. */
1252         fd_attempt_close(fd_ptr);
1253         return;
1254       }
1255       sbuf = &statbuf;
1256     }
1257
1258     /* Set the correct entries in fd_ptr. */
1259     fd_ptr->dev = (uint32)sbuf->st_dev;
1260     fd_ptr->inode = (uint32)sbuf->st_ino;
1261
1262     fsp->f_u.fd_ptr = fd_ptr;
1263     Connections[cnum].num_files_open++;
1264     fsp->mode = sbuf->st_mode;
1265     GetTimeOfDay(&fsp->open_time);
1266     fsp->vuid = current_user.vuid;
1267     fsp->size = 0;
1268     fsp->pos = -1;
1269     fsp->open = True;
1270     fsp->mmap_ptr = NULL;
1271     fsp->mmap_size = 0;
1272     fsp->can_lock = True;
1273     fsp->can_read = ((flags & O_WRONLY)==0);
1274     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
1275     fsp->share_mode = 0;
1276     fsp->print_file = Connections[cnum].printer;
1277     fsp->modified = False;
1278     fsp->granted_oplock = False;
1279     fsp->sent_oplock_break = False;
1280     fsp->is_directory = False;
1281     fsp->cnum = cnum;
1282     /*
1283      * Note that the file name here is the *untranslated* name
1284      * ie. it is still in the DOS codepage sent from the client.
1285      * All use of this filename will pass though the sys_xxxx
1286      * functions which will do the dos_to_unix translation before
1287      * mapping into a UNIX filename. JRA.
1288      */
1289     string_set(&fsp->name,fname);
1290     fsp->wbmpx_ptr = NULL;      
1291
1292     /*
1293      * If the printer is marked as postscript output a leading
1294      * file identifier to ensure the file is treated as a raw
1295      * postscript file.
1296      * This has a similar effect as CtrlD=0 in WIN.INI file.
1297      * tim@fsg.com 09/06/94
1298      */
1299     if (fsp->print_file && POSTSCRIPT(cnum) && fsp->can_write) 
1300     {
1301       DEBUG(3,("Writing postscript line\n"));
1302       write_file(fnum,"%!\n",3);
1303     }
1304       
1305     DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1306           timestring(),
1307           *sesssetup_user ? sesssetup_user : Connections[cnum].user,fname,
1308           BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
1309           Connections[cnum].num_files_open,fnum));
1310
1311   }
1312
1313 #if WITH_MMAP
1314   /* mmap it if read-only */
1315   if (!fsp->can_write)
1316   {
1317     fsp->mmap_size = file_size(fname);
1318     fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
1319                                  PROT_READ,MAP_SHARED,fsp->f_u.fd_ptr->fd,0);
1320
1321     if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1322     {
1323       DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1324       fsp->mmap_ptr = NULL;
1325     }
1326   }
1327 #endif
1328 }
1329
1330 /*******************************************************************
1331 sync a file
1332 ********************************************************************/
1333 void sync_file(int cnum, int fnum)
1334 {
1335 #ifdef HAVE_FSYNC
1336     if(lp_strict_sync(SNUM(cnum)))
1337       fsync(Files[fnum].f_u.fd_ptr->fd);
1338 #endif
1339 }
1340
1341 /****************************************************************************
1342 run a file if it is a magic script
1343 ****************************************************************************/
1344 static void check_magic(int fnum,int cnum)
1345 {
1346   if (!*lp_magicscript(SNUM(cnum)))
1347     return;
1348
1349   DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1350
1351   {
1352     char *p;
1353     if (!(p = strrchr(Files[fnum].name,'/')))
1354       p = Files[fnum].name;
1355     else
1356       p++;
1357
1358     if (!strequal(lp_magicscript(SNUM(cnum)),p))
1359       return;
1360   }
1361
1362   {
1363     int ret;
1364     pstring magic_output;
1365     pstring fname;
1366     pstrcpy(fname,Files[fnum].name);
1367
1368     if (*lp_magicoutput(SNUM(cnum)))
1369       pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1370     else
1371       slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
1372
1373     chmod(fname,0755);
1374     ret = smbrun(fname,magic_output,False);
1375     DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
1376     unlink(fname);
1377   }
1378 }
1379
1380 /****************************************************************************
1381   Common code to close a file or a directory.
1382 ****************************************************************************/
1383     
1384 static void close_filestruct(files_struct *fsp)
1385 {   
1386   int cnum = fsp->cnum;
1387     
1388   fsp->reserved = False; 
1389   fsp->open = False;
1390   fsp->is_directory = False; 
1391     
1392   Connections[cnum].num_files_open--;
1393   if(fsp->wbmpx_ptr)
1394   {  
1395     free((char *)fsp->wbmpx_ptr);
1396     fsp->wbmpx_ptr = NULL; 
1397   }  
1398      
1399 #if WITH_MMAP
1400   if(fsp->mmap_ptr) 
1401   {
1402     munmap(fsp->mmap_ptr,fsp->mmap_size);
1403     fsp->mmap_ptr = NULL;
1404   }  
1405 #endif 
1406 }    
1407
1408 /****************************************************************************
1409  Close a file - possibly invalidating the read prediction.
1410
1411  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1412  operation otherwise it came as the result of some other operation such as
1413  the closing of the connection. In the latter case printing and
1414  magic scripts are not run.
1415 ****************************************************************************/
1416
1417 void close_file(int fnum, BOOL normal_close)
1418 {
1419   files_struct *fs_p = &Files[fnum];
1420   int cnum = fs_p->cnum;
1421   uint32 dev = fs_p->f_u.fd_ptr->dev;
1422   uint32 inode = fs_p->f_u.fd_ptr->inode;
1423   int token;
1424
1425   close_filestruct(fs_p);
1426
1427 #if USE_READ_PREDICTION
1428   invalidate_read_prediction(fs_p->f_u.fd_ptr->fd);
1429 #endif
1430
1431   if (lp_share_modes(SNUM(cnum)))
1432   {
1433     lock_share_entry( cnum, dev, inode, &token);
1434     del_share_mode(token, fnum);
1435   }
1436
1437   fd_attempt_close(fs_p->f_u.fd_ptr);
1438
1439   if (lp_share_modes(SNUM(cnum)))
1440     unlock_share_entry( cnum, dev, inode, token);
1441
1442   /* NT uses smbclose to start a print - weird */
1443   if (normal_close && fs_p->print_file)
1444     print_file(fnum);
1445
1446   /* check for magic scripts */
1447   if (normal_close)
1448     check_magic(fnum,cnum);
1449
1450   if(fs_p->granted_oplock == True)
1451     global_oplocks_open--;
1452
1453   fs_p->sent_oplock_break = False;
1454
1455   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1456            timestring(),Connections[cnum].user,fs_p->name,
1457            Connections[cnum].num_files_open));
1458
1459   if (fs_p->name) {
1460           string_free(&fs_p->name);
1461   }
1462
1463   /* we will catch bugs faster by zeroing this structure */
1464   memset(fs_p, 0, sizeof(*fs_p));
1465 }
1466
1467 /****************************************************************************
1468  Close a directory opened by an NT SMB call. 
1469 ****************************************************************************/
1470   
1471 void close_directory(int fnum)
1472 {
1473   files_struct *fsp = &Files[fnum];
1474
1475   /* TODO - walk the list of pending
1476      change notify requests and free
1477      any pertaining to this fnum. */
1478
1479   /*
1480    * Do the code common to files and directories.
1481    */
1482   close_filestruct(fsp);
1483
1484   if (fsp->name)
1485     string_free(&fsp->name);
1486
1487   if (fsp->f_u.dir_ptr)
1488     free((char *)fsp->f_u.dir_ptr);
1489
1490   /* we will catch bugs faster by zeroing this structure */
1491   memset(fsp, 0, sizeof(*fsp));
1492 }
1493
1494 /****************************************************************************
1495  Open a directory from an NT SMB call.
1496 ****************************************************************************/
1497
1498 int open_directory(int fnum,int cnum,char *fname, int smb_ofun, int unixmode, int *action)
1499 {
1500   extern struct current_user current_user;
1501   files_struct *fsp = &Files[fnum];
1502   struct stat st;
1503
1504   if (smb_ofun & 0x10) {
1505     /*
1506      * Create the directory.
1507      */
1508
1509     if(sys_mkdir(fname, unixmode) < 0) {
1510       DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
1511             fname, strerror(errno) ));
1512       return -1;
1513     }
1514
1515     *action = FILE_WAS_CREATED;
1516
1517   } else {
1518
1519     /*
1520      * Check that it *was* a directory.
1521      */
1522
1523     if(sys_stat(fname, &st) < 0) {
1524       DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
1525             fname, strerror(errno) ));
1526       return -1;
1527     }
1528
1529     if(!S_ISDIR(st.st_mode)) {
1530       DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1531       return -1;
1532     }
1533     *action = FILE_WAS_OPENED;
1534   }
1535
1536   /*
1537    * Setup the files_struct for it.
1538    */
1539
1540   fsp->f_u.dir_ptr = NULL;
1541   Connections[cnum].num_files_open++;
1542   fsp->mode = 0;
1543   GetTimeOfDay(&fsp->open_time);
1544   fsp->vuid = current_user.vuid;
1545   fsp->size = 0;
1546   fsp->pos = -1;
1547   fsp->open = True;
1548   fsp->mmap_ptr = NULL;
1549   fsp->mmap_size = 0;
1550   fsp->can_lock = True;
1551   fsp->can_read = False;
1552   fsp->can_write = False;
1553   fsp->share_mode = 0;
1554   fsp->print_file = False;
1555   fsp->modified = False;
1556   fsp->granted_oplock = False;
1557   fsp->sent_oplock_break = False;
1558   fsp->is_directory = True;
1559   fsp->cnum = cnum;
1560   /*
1561    * Note that the file name here is the *untranslated* name
1562    * ie. it is still in the DOS codepage sent from the client.
1563    * All use of this filename will pass though the sys_xxxx
1564    * functions which will do the dos_to_unix translation before
1565    * mapping into a UNIX filename. JRA.
1566    */
1567   string_set(&fsp->name,fname);
1568   fsp->wbmpx_ptr = NULL;
1569
1570   return 0;
1571 }
1572
1573 enum {AFAIL,AREAD,AWRITE,AALL};
1574
1575 /*******************************************************************
1576 reproduce the share mode access table
1577 ********************************************************************/
1578 static int access_table(int new_deny,int old_deny,int old_mode,
1579                         int share_pid,char *fname)
1580 {
1581   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1582
1583   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1584     int pid = getpid();
1585     if (old_deny == new_deny && share_pid == pid) 
1586         return(AALL);    
1587
1588     if (old_mode == 0) return(AREAD);
1589
1590     /* the new smbpub.zip spec says that if the file extension is
1591        .com, .dll, .exe or .sym then allow the open. I will force
1592        it to read-only as this seems sensible although the spec is
1593        a little unclear on this. */
1594     if ((fname = strrchr(fname,'.'))) {
1595       if (strequal(fname,".com") ||
1596           strequal(fname,".dll") ||
1597           strequal(fname,".exe") ||
1598           strequal(fname,".sym"))
1599         return(AREAD);
1600     }
1601
1602     return(AFAIL);
1603   }
1604
1605   switch (new_deny) 
1606     {
1607     case DENY_WRITE:
1608       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1609       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1610       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1611       return(AFAIL);
1612     case DENY_READ:
1613       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1614       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1615       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1616       return(AFAIL);
1617     case DENY_NONE:
1618       if (old_deny==DENY_WRITE) return(AREAD);
1619       if (old_deny==DENY_READ) return(AWRITE);
1620       if (old_deny==DENY_NONE) return(AALL);
1621       return(AFAIL);      
1622     }
1623   return(AFAIL);      
1624 }
1625
1626 /*******************************************************************
1627 check if the share mode on a file allows it to be deleted or unlinked
1628 return True if sharing doesn't prevent the operation
1629 ********************************************************************/
1630 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1631 {
1632   int i;
1633   int ret = False;
1634   share_mode_entry *old_shares = 0;
1635   int num_share_modes;
1636   struct stat sbuf;
1637   int token;
1638   int pid = getpid();
1639   uint32 dev, inode;
1640
1641   if(!lp_share_modes(SNUM(cnum)))
1642     return True;
1643
1644   if (sys_stat(fname,&sbuf) == -1) return(True);
1645
1646   dev = (uint32)sbuf.st_dev;
1647   inode = (uint32)sbuf.st_ino;
1648
1649   lock_share_entry(cnum, dev, inode, &token);
1650   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1651
1652   /*
1653    * Check if the share modes will give us access.
1654    */
1655
1656   if(num_share_modes != 0)
1657   {
1658     BOOL broke_oplock;
1659
1660     do
1661     {
1662
1663       broke_oplock = False;
1664       for(i = 0; i < num_share_modes; i++)
1665       {
1666         share_mode_entry *share_entry = &old_shares[i];
1667
1668         /* 
1669          * Break oplocks before checking share modes. See comment in
1670          * open_file_shared for details. 
1671          * Check if someone has an oplock on this file. If so we must 
1672          * break it before continuing. 
1673          */
1674         if(share_entry->op_type & BATCH_OPLOCK)
1675         {
1676
1677           /*
1678            * It appears that the NT redirector may have a bug, in that
1679            * it tries to do an SMBmv on a file that it has open with a
1680            * batch oplock, and then fails to respond to the oplock break
1681            * request. This only seems to occur when the client is doing an
1682            * SMBmv to the smbd it is using - thus we try and detect this
1683            * condition by checking if the file being moved is open and oplocked by
1684            * this smbd process, and then not sending the oplock break in this
1685            * special case. If the file was open with a deny mode that 
1686            * prevents the move the SMBmv will fail anyway with a share
1687            * violation error. JRA.
1688            */
1689           if(rename_op && (share_entry->pid == pid))
1690           {
1691             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1692 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1693             /* 
1694              * This next line is a test that allows the deny-mode
1695              * processing to be skipped. This seems to be needed as
1696              * NT insists on the rename succeeding (in Office 9x no less !).
1697              * This should be removed as soon as (a) MS fix the redirector
1698              * bug or (b) NT SMB support in Samba makes NT not issue the
1699              * call (as is my fervent hope). JRA.
1700              */ 
1701             continue;
1702           }
1703           else
1704           {
1705             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1706 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1707
1708             /* Oplock break.... */
1709             unlock_share_entry(cnum, dev, inode, token);
1710             if(request_oplock_break(share_entry, dev, inode) == False)
1711             {
1712               free((char *)old_shares);
1713               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1714 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1715               return False;
1716             }
1717             lock_share_entry(cnum, dev, inode, &token);
1718             broke_oplock = True;
1719             break;
1720           }
1721         }
1722
1723         /* someone else has a share lock on it, check to see 
1724            if we can too */
1725         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1726           goto free_and_exit;
1727
1728       } /* end for */
1729
1730       if(broke_oplock)
1731       {
1732         free((char *)old_shares);
1733         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1734       }
1735     } while(broke_oplock);
1736   }
1737
1738   /* XXXX exactly what share mode combinations should be allowed for
1739      deleting/renaming? */
1740   /* If we got here then either there were no share modes or
1741      all share modes were DENY_DOS and the pid == getpid() */
1742   ret = True;
1743
1744 free_and_exit:
1745
1746   unlock_share_entry(cnum, dev, inode, token);
1747   if(old_shares != NULL)
1748     free((char *)old_shares);
1749   return(ret);
1750 }
1751
1752 /****************************************************************************
1753   C. Hoch 11/22/95
1754   Helper for open_file_shared. 
1755   Truncate a file after checking locking; close file if locked.
1756   **************************************************************************/
1757 static void truncate_unless_locked(int fnum, int cnum, int token, 
1758                                    BOOL *share_locked)
1759 {
1760   if (Files[fnum].can_write){
1761     if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){
1762       /* If share modes are in force for this connection we
1763          have the share entry locked. Unlock it before closing. */
1764       if (*share_locked && lp_share_modes(SNUM(cnum)))
1765         unlock_share_entry( cnum, Files[fnum].f_u.fd_ptr->dev, 
1766                             Files[fnum].f_u.fd_ptr->inode, token);
1767       close_file(fnum,False);   
1768       /* Share mode no longer locked. */
1769       *share_locked = False;
1770       errno = EACCES;
1771       unix_ERR_class = ERRDOS;
1772       unix_ERR_code = ERRlock;
1773     }
1774     else
1775       ftruncate(Files[fnum].f_u.fd_ptr->fd,0); 
1776   }
1777 }
1778
1779 /****************************************************************************
1780 check if we can open a file with a share mode
1781 ****************************************************************************/
1782 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1783                       BOOL fcbopen, int *flags)
1784 {
1785   int old_open_mode = share->share_mode &0xF;
1786   int old_deny_mode = (share->share_mode >>4)&7;
1787
1788   if (old_deny_mode > 4 || old_open_mode > 2)
1789   {
1790     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1791                deny_mode,old_deny_mode,old_open_mode,fname));
1792     return False;
1793   }
1794
1795   {
1796     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1797                                 share->pid,fname);
1798
1799     if ((access_allowed == AFAIL) ||
1800         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1801         (access_allowed == AREAD && *flags == O_WRONLY) ||
1802         (access_allowed == AWRITE && *flags == O_RDONLY))
1803     {
1804       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1805                 deny_mode,old_deny_mode,old_open_mode,
1806                 share->pid,fname, fcbopen, *flags, access_allowed));
1807       return False;
1808     }
1809
1810     if (access_allowed == AREAD)
1811       *flags = O_RDONLY;
1812
1813     if (access_allowed == AWRITE)
1814       *flags = O_WRONLY;
1815
1816   }
1817   return True;
1818 }
1819
1820 /****************************************************************************
1821 open a file with a share mode
1822 ****************************************************************************/
1823 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1824                       int mode,int oplock_request, int *Access,int *action)
1825 {
1826   files_struct *fs_p = &Files[fnum];
1827   int flags=0;
1828   int flags2=0;
1829   int deny_mode = (share_mode>>4)&7;
1830   struct stat sbuf;
1831   BOOL file_existed = file_exist(fname,&sbuf);
1832   BOOL share_locked = False;
1833   BOOL fcbopen = False;
1834   int token;
1835   uint32 dev = 0;
1836   uint32 inode = 0;
1837   int num_share_modes = 0;
1838
1839   fs_p->open = False;
1840   fs_p->f_u.fd_ptr = 0;
1841
1842   /* this is for OS/2 EAs - try and say we don't support them */
1843   if (strstr(fname,".+,;=[].")) 
1844   {
1845     unix_ERR_class = ERRDOS;
1846     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1847 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1848     unix_ERR_code = ERRcannotopen;
1849 #else /* OS2_WPS_FIX */
1850     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1851 #endif /* OS2_WPS_FIX */
1852
1853     return;
1854   }
1855
1856   if ((ofun & 0x3) == 0 && file_existed)  
1857   {
1858     errno = EEXIST;
1859     return;
1860   }
1861       
1862   if (ofun & 0x10)
1863     flags2 |= O_CREAT;
1864   if ((ofun & 0x3) == 2)
1865     flags2 |= O_TRUNC;
1866
1867   /* note that we ignore the append flag as 
1868      append does not mean the same thing under dos and unix */
1869
1870   switch (share_mode&0xF)
1871   {
1872     case 1: 
1873       flags = O_WRONLY; 
1874       break;
1875     case 0xF: 
1876       fcbopen = True;
1877       flags = O_RDWR; 
1878       break;
1879     case 2: 
1880       flags = O_RDWR; 
1881       break;
1882     default:
1883       flags = O_RDONLY;
1884       break;
1885   }
1886
1887 #if defined(O_SYNC)
1888   if (share_mode&(1<<14)) {
1889           flags2 |= O_SYNC;
1890   }
1891 #endif /* O_SYNC */
1892   
1893   if (flags != O_RDONLY && file_existed && 
1894       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
1895   {
1896     if (!fcbopen) 
1897     {
1898       errno = EACCES;
1899       return;
1900     }
1901     flags = O_RDONLY;
1902   }
1903
1904   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
1905   {
1906     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1907     errno = EINVAL;
1908     return;
1909   }
1910
1911   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1912
1913   if (lp_share_modes(SNUM(cnum))) 
1914   {
1915     int i;
1916     share_mode_entry *old_shares = 0;
1917
1918     if (file_existed)
1919     {
1920       dev = (uint32)sbuf.st_dev;
1921       inode = (uint32)sbuf.st_ino;
1922       lock_share_entry(cnum, dev, inode, &token);
1923       share_locked = True;
1924       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1925     }
1926
1927     /*
1928      * Check if the share modes will give us access.
1929      */
1930
1931     if(share_locked && (num_share_modes != 0))
1932     {
1933       BOOL broke_oplock;
1934
1935       do
1936       {
1937
1938         broke_oplock = False;
1939         for(i = 0; i < num_share_modes; i++)
1940         {
1941           share_mode_entry *share_entry = &old_shares[i];
1942
1943           /* 
1944            * By observation of NetBench, oplocks are broken *before* share
1945            * modes are checked. This allows a file to be closed by the client
1946            * if the share mode would deny access and the client has an oplock. 
1947            * Check if someone has an oplock on this file. If so we must break 
1948            * it before continuing. 
1949            */
1950           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1951           {
1952
1953             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1954 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1955
1956             /* Oplock break.... */
1957             unlock_share_entry(cnum, dev, inode, token);
1958             if(request_oplock_break(share_entry, dev, inode) == False)
1959             {
1960               free((char *)old_shares);
1961               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1962 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1963               errno = EACCES;
1964               unix_ERR_class = ERRDOS;
1965               unix_ERR_code = ERRbadshare;
1966               return;
1967             }
1968             lock_share_entry(cnum, dev, inode, &token);
1969             broke_oplock = True;
1970             break;
1971           }
1972
1973           /* someone else has a share lock on it, check to see 
1974              if we can too */
1975           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1976           {
1977             free((char *)old_shares);
1978             unlock_share_entry(cnum, dev, inode, token);
1979             errno = EACCES;
1980             unix_ERR_class = ERRDOS;
1981             unix_ERR_code = ERRbadshare;
1982             return;
1983           }
1984
1985         } /* end for */
1986
1987         if(broke_oplock)
1988         {
1989           free((char *)old_shares);
1990           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1991         }
1992       } while(broke_oplock);
1993     }
1994
1995     if(old_shares != 0)
1996       free((char *)old_shares);
1997   }
1998
1999   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
2000            flags,flags2,mode));
2001
2002   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
2003   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
2004   {
2005     flags = O_RDONLY;
2006     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
2007   }
2008
2009   if (fs_p->open) 
2010   {
2011     int open_mode=0;
2012
2013     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
2014     {
2015       /* We created the file - thus we must now lock the share entry before creating it. */
2016       dev = fs_p->f_u.fd_ptr->dev;
2017       inode = fs_p->f_u.fd_ptr->inode;
2018       lock_share_entry(cnum, dev, inode, &token);
2019       share_locked = True;
2020     }
2021
2022     switch (flags) 
2023     {
2024       case O_RDONLY:
2025         open_mode = 0;
2026         break;
2027       case O_RDWR:
2028         open_mode = 2;
2029         break;
2030       case O_WRONLY:
2031         open_mode = 1;
2032         break;
2033     }
2034
2035     fs_p->share_mode = (deny_mode<<4) | open_mode;
2036
2037     if (Access)
2038       (*Access) = open_mode;
2039
2040     if (action) 
2041     {
2042       if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
2043       if (!file_existed) *action = FILE_WAS_CREATED;
2044       if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
2045     }
2046     /* We must create the share mode entry before truncate as
2047        truncate can fail due to locking and have to close the
2048        file (which expects the share_mode_entry to be there).
2049      */
2050     if (lp_share_modes(SNUM(cnum)))
2051     {
2052       uint16 port = 0;
2053       /* JRA. Currently this only services Exlcusive and batch
2054          oplocks (no other opens on this file). This needs to
2055          be extended to level II oplocks (multiple reader
2056          oplocks). */
2057
2058       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
2059               !IS_VETO_OPLOCK_PATH(cnum,fname))
2060       {
2061         fs_p->granted_oplock = True;
2062         fs_p->sent_oplock_break = False;
2063         global_oplocks_open++;
2064         port = oplock_port;
2065
2066         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2067 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2068
2069       }
2070       else
2071       {
2072         port = 0;
2073         oplock_request = 0;
2074       }
2075       set_share_mode(token, fnum, port, oplock_request);
2076     }
2077
2078     if ((flags2&O_TRUNC) && file_existed)
2079       truncate_unless_locked(fnum,cnum,token,&share_locked);
2080   }
2081
2082   if (share_locked && lp_share_modes(SNUM(cnum)))
2083     unlock_share_entry( cnum, dev, inode, token);
2084 }
2085
2086 /****************************************************************************
2087 seek a file. Try to avoid the seek if possible
2088 ****************************************************************************/
2089 int seek_file(int fnum,uint32 pos)
2090 {
2091   uint32 offset = 0;
2092   files_struct *fsp = &Files[fnum];
2093
2094   if (fsp->print_file && POSTSCRIPT(fsp->cnum))
2095     offset = 3;
2096
2097   fsp->pos = (int)(lseek(fsp->f_u.fd_ptr->fd,pos+offset,SEEK_SET) - offset);
2098   return(fsp->pos);
2099 }
2100
2101 /****************************************************************************
2102 read from a file
2103 ****************************************************************************/
2104 int read_file(int fnum,char *data,uint32 pos,int n)
2105 {
2106   int ret=0,readret;
2107   files_struct *fsp = &Files[fnum];
2108
2109 #if USE_READ_PREDICTION
2110   if (!fsp->can_write)
2111     {
2112       ret = read_predict(fsp->f_u.fd_ptr->fd,pos,data,NULL,n);
2113
2114       data += ret;
2115       n -= ret;
2116       pos += ret;
2117     }
2118 #endif
2119
2120 #if WITH_MMAP
2121   if (fsp->mmap_ptr)
2122     {
2123       int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1;
2124       num = MIN(n,num);
2125       if (num > 0)
2126         {
2127           memcpy(data,fsp->mmap_ptr+pos,num);
2128           data += num;
2129           pos += num;
2130           n -= num;
2131           ret += num;
2132         }
2133     }
2134 #endif
2135
2136   if (n <= 0)
2137     return(ret);
2138
2139   if (seek_file(fnum,pos) != pos)
2140     {
2141       DEBUG(3,("Failed to seek to %d\n",pos));
2142       return(ret);
2143     }
2144   
2145   if (n > 0) {
2146     readret = read(fsp->f_u.fd_ptr->fd,data,n);
2147     if (readret > 0) ret += readret;
2148   }
2149
2150   return(ret);
2151 }
2152
2153
2154 /****************************************************************************
2155 write to a file
2156 ****************************************************************************/
2157 int write_file(int fnum,char *data,int n)
2158 {
2159   files_struct *fsp = &Files[fnum];
2160
2161   if (!fsp->can_write) {
2162     errno = EPERM;
2163     return(0);
2164   }
2165
2166   if (!fsp->modified) {
2167     struct stat st;
2168     fsp->modified = True;
2169     if (fstat(fsp->f_u.fd_ptr->fd,&st) == 0) {
2170       int dosmode = dos_mode(fsp->cnum,fsp->name,&st);
2171       if (MAP_ARCHIVE(fsp->cnum) && !IS_DOS_ARCHIVE(dosmode)) { 
2172         dos_chmod(fsp->cnum,fsp->name,dosmode | aARCH,&st);
2173       }
2174     }  
2175   }
2176
2177   return(write_data(fsp->f_u.fd_ptr->fd,data,n));
2178 }
2179
2180
2181 /****************************************************************************
2182 load parameters specific to a connection/service
2183 ****************************************************************************/
2184 BOOL become_service(int cnum,BOOL do_chdir)
2185 {
2186   extern char magic_char;
2187   static int last_cnum = -1;
2188   int snum;
2189
2190   if (!OPEN_CNUM(cnum))
2191     {
2192       last_cnum = -1;
2193       return(False);
2194     }
2195
2196   Connections[cnum].lastused = smb_last_time;
2197
2198   snum = SNUM(cnum);
2199   
2200   if (do_chdir &&
2201       ChDir(Connections[cnum].connectpath) != 0 &&
2202       ChDir(Connections[cnum].origpath) != 0)
2203     {
2204       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2205             Connections[cnum].connectpath,cnum));     
2206       return(False);
2207     }
2208
2209   if (cnum == last_cnum)
2210     return(True);
2211
2212   last_cnum = cnum;
2213
2214   case_default = lp_defaultcase(snum);
2215   case_preserve = lp_preservecase(snum);
2216   short_case_preserve = lp_shortpreservecase(snum);
2217   case_mangle = lp_casemangle(snum);
2218   case_sensitive = lp_casesensitive(snum);
2219   magic_char = lp_magicchar(snum);
2220   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2221   return(True);
2222 }
2223
2224
2225 /****************************************************************************
2226   find a service entry
2227 ****************************************************************************/
2228 int find_service(char *service)
2229 {
2230    int iService;
2231
2232    string_sub(service,"\\","/");
2233
2234    iService = lp_servicenumber(service);
2235
2236    /* now handle the special case of a home directory */
2237    if (iService < 0)
2238    {
2239       char *phome_dir = get_home_dir(service);
2240
2241       if(!phome_dir)
2242       {
2243         /*
2244          * Try mapping the servicename, it may
2245          * be a Windows to unix mapped user name.
2246          */
2247         if(map_username(service))
2248           phome_dir = get_home_dir(service);
2249       }
2250
2251       DEBUG(3,("checking for home directory %s gave %s\n",service,
2252             phome_dir?phome_dir:"(NULL)"));
2253
2254       if (phome_dir)
2255       {   
2256         int iHomeService;
2257         if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2258         {
2259           lp_add_home(service,iHomeService,phome_dir);
2260           iService = lp_servicenumber(service);
2261         }
2262       }
2263    }
2264
2265    /* If we still don't have a service, attempt to add it as a printer. */
2266    if (iService < 0)
2267    {
2268       int iPrinterService;
2269
2270       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2271       {
2272          char *pszTemp;
2273
2274          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2275          pszTemp = PRINTCAP;
2276          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2277          {
2278             DEBUG(3,("%s is a valid printer name\n", service));
2279             DEBUG(3,("adding %s as a printer service\n", service));
2280             lp_add_printer(service,iPrinterService);
2281             iService = lp_servicenumber(service);
2282             if (iService < 0)
2283                DEBUG(0,("failed to add %s as a printer service!\n", service));
2284          }
2285          else
2286             DEBUG(3,("%s is not a valid printer name\n", service));
2287       }
2288    }
2289
2290    /* just possibly it's a default service? */
2291    if (iService < 0) 
2292    {
2293      char *pdefservice = lp_defaultservice();
2294      if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2295      {
2296        /*
2297         * We need to do a local copy here as lp_defaultservice() 
2298         * returns one of the rotating lp_string buffers that
2299         * could get overwritten by the recursive find_service() call
2300         * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2301         */
2302        pstring defservice;
2303        pstrcpy(defservice, pdefservice);
2304        iService = find_service(defservice);
2305        if (iService >= 0)
2306        {
2307          string_sub(service,"_","/");
2308          iService = lp_add_service(service,iService);
2309        }
2310      }
2311    }
2312
2313    if (iService >= 0)
2314      if (!VALID_SNUM(iService))
2315      {
2316        DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2317        iService = -1;
2318      }
2319
2320    if (iService < 0)
2321      DEBUG(3,("find_service() failed to find service %s\n", service));
2322
2323    return (iService);
2324 }
2325
2326
2327 /****************************************************************************
2328   create an error packet from a cached error.
2329 ****************************************************************************/
2330 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2331 {
2332   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2333
2334   int32 eclass = wbmpx->wr_errclass;
2335   int32 err = wbmpx->wr_error;
2336
2337   /* We can now delete the auxiliary struct */
2338   free((char *)wbmpx);
2339   Files[fnum].wbmpx_ptr = NULL;
2340   return error_packet(inbuf,outbuf,eclass,err,line);
2341 }
2342
2343
2344 struct
2345 {
2346   int unixerror;
2347   int smbclass;
2348   int smbcode;
2349 } unix_smb_errmap[] =
2350 {
2351   {EPERM,ERRDOS,ERRnoaccess},
2352   {EACCES,ERRDOS,ERRnoaccess},
2353   {ENOENT,ERRDOS,ERRbadfile},
2354   {ENOTDIR,ERRDOS,ERRbadpath},
2355   {EIO,ERRHRD,ERRgeneral},
2356   {EBADF,ERRSRV,ERRsrverror},
2357   {EINVAL,ERRSRV,ERRsrverror},
2358   {EEXIST,ERRDOS,ERRfilexists},
2359   {ENFILE,ERRDOS,ERRnofids},
2360   {EMFILE,ERRDOS,ERRnofids},
2361   {ENOSPC,ERRHRD,ERRdiskfull},
2362 #ifdef EDQUOT
2363   {EDQUOT,ERRHRD,ERRdiskfull},
2364 #endif
2365 #ifdef ENOTEMPTY
2366   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2367 #endif
2368 #ifdef EXDEV
2369   {EXDEV,ERRDOS,ERRdiffdevice},
2370 #endif
2371   {EROFS,ERRHRD,ERRnowrite},
2372   {0,0,0}
2373 };
2374
2375 /****************************************************************************
2376   create an error packet from errno
2377 ****************************************************************************/
2378 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2379 {
2380   int eclass=def_class;
2381   int ecode=def_code;
2382   int i=0;
2383
2384   if (unix_ERR_class != SMB_SUCCESS)
2385     {
2386       eclass = unix_ERR_class;
2387       ecode = unix_ERR_code;
2388       unix_ERR_class = SMB_SUCCESS;
2389       unix_ERR_code = 0;
2390     }
2391   else
2392     {
2393       while (unix_smb_errmap[i].smbclass != 0)
2394       {
2395             if (unix_smb_errmap[i].unixerror == errno)
2396             {
2397               eclass = unix_smb_errmap[i].smbclass;
2398               ecode = unix_smb_errmap[i].smbcode;
2399               break;
2400             }
2401           i++;
2402       }
2403     }
2404
2405   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2406 }
2407
2408
2409 /****************************************************************************
2410   create an error packet. Normally called using the ERROR() macro
2411 ****************************************************************************/
2412 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2413 {
2414   int outsize = set_message(outbuf,0,0,True);
2415   int cmd = CVAL(inbuf,smb_com);
2416   int flgs2 = SVAL(outbuf,smb_flg2); 
2417
2418   if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2419   {
2420     SIVAL(outbuf,smb_rcls,error_code);
2421     
2422     DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2423            timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2424   }
2425   else
2426   {
2427     CVAL(outbuf,smb_rcls) = error_class;
2428     SSVAL(outbuf,smb_err,error_code);  
2429     DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2430            timestring(),
2431            line,
2432            (int)CVAL(inbuf,smb_com),
2433            smb_fn_name(CVAL(inbuf,smb_com)),
2434            error_class,
2435            error_code));
2436
2437   }
2438   
2439   if (errno != 0)
2440     DEBUG(3,("error string = %s\n",strerror(errno)));
2441   
2442   return(outsize);
2443 }
2444
2445
2446 /****************************************************************************
2447   this is called when the client exits abruptly
2448   **************************************************************************/
2449 static int sig_pipe(void)
2450 {
2451         struct cli_state *cli;
2452         BlockSignals(True,SIGPIPE);
2453
2454         if ((cli = server_client()) && cli->initialised) {
2455                 DEBUG(3,("lost connection to password server\n"));
2456                 cli_shutdown(cli);
2457                 BlockSignals(False,SIGPIPE);
2458                 return 0;
2459         }
2460
2461         exit_server("Got sigpipe\n");
2462         return(0);
2463 }
2464
2465 /****************************************************************************
2466   open the socket communication
2467 ****************************************************************************/
2468 static BOOL open_sockets(BOOL is_daemon,int port)
2469 {
2470   extern int Client;
2471
2472   if (is_daemon)
2473   {
2474     int num_interfaces = iface_count();
2475     int fd_listenset[FD_SETSIZE];
2476     fd_set listen_set;
2477     int s;
2478     int i;
2479
2480 #ifdef HAVE_ATEXIT
2481     static int atexit_set;
2482     if(atexit_set == 0) {
2483             atexit_set=1;
2484             atexit(killkids);
2485     }
2486 #endif
2487
2488     /* Stop zombies */
2489     CatchChild();
2490
2491
2492     FD_ZERO(&listen_set);
2493
2494     if(lp_interfaces() && lp_bind_interfaces_only())
2495     {
2496        /* We have been given an interfaces line, and been 
2497           told to only bind to those interfaces. Create a
2498           socket per interface and bind to only these.
2499         */
2500
2501       if(num_interfaces > FD_SETSIZE)
2502       {
2503         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2504 max can be %d\n", num_interfaces, FD_SETSIZE));
2505         return False;
2506       }
2507
2508       /* Now open a listen socket for each of the interfaces. */
2509       for(i = 0; i < num_interfaces; i++)
2510       {
2511         struct in_addr *ifip = iface_n_ip(i);
2512
2513         if(ifip == NULL)
2514         {
2515           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2516           continue;
2517         }
2518         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2519         if(s == -1)
2520           return False;
2521         /* ready to listen */
2522         if (listen(s, 5) == -1) 
2523         {
2524           DEBUG(0,("listen: %s\n",strerror(errno)));
2525           close(s);
2526           return False;
2527         }
2528         FD_SET(s,&listen_set);
2529       }
2530     }
2531     else
2532     {
2533       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2534       num_interfaces = 1;
2535
2536       /* open an incoming socket */
2537       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2538       if (s == -1)
2539         return(False);
2540
2541       /* ready to listen */
2542       if (listen(s, 5) == -1) 
2543       {
2544         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2545         close(s);
2546         return False;
2547       }
2548
2549       fd_listenset[0] = s;
2550       FD_SET(s,&listen_set);
2551     }      
2552
2553     /* now accept incoming connections - forking a new process
2554        for each incoming connection */
2555     DEBUG(2,("waiting for a connection\n"));
2556     while (1)
2557     {
2558       fd_set lfds;
2559       int num;
2560
2561       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2562
2563       num = sys_select(&lfds,NULL);
2564
2565       if (num == -1 && errno == EINTR)
2566         continue;
2567
2568       /* Find the sockets that are read-ready - accept on these. */
2569       for( ; num > 0; num--)
2570       {
2571         struct sockaddr addr;
2572         int in_addrlen = sizeof(addr);
2573
2574         s = -1;
2575         for(i = 0; i < num_interfaces; i++)
2576         {
2577           if(FD_ISSET(fd_listenset[i],&lfds))
2578           {
2579             s = fd_listenset[i];
2580             /* Clear this so we don't look at it again. */
2581             FD_CLR(fd_listenset[i],&lfds);
2582             break;
2583           }
2584         }
2585
2586         Client = accept(s,&addr,&in_addrlen);
2587
2588         if (Client == -1 && errno == EINTR)
2589           continue;
2590
2591         if (Client == -1)
2592         {
2593           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2594           continue;
2595         }
2596
2597         if (Client != -1 && fork()==0)
2598         {
2599           /* Child code ... */
2600
2601           CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2602
2603           /* close the listening socket(s) */
2604           for(i = 0; i < num_interfaces; i++)
2605             close(fd_listenset[i]);
2606
2607           /* close our standard file descriptors */
2608           close_low_fds();
2609           am_parent = 0;
2610   
2611           set_socket_options(Client,"SO_KEEPALIVE");
2612           set_socket_options(Client,user_socket_options);
2613
2614           /* Reset global variables in util.c so that
2615              client substitutions will be done correctly
2616              in the process.
2617            */
2618           reset_globals_after_fork();
2619           return True; 
2620         }
2621         close(Client); /* The parent doesn't need this socket */
2622
2623         /*
2624          * Force parent to check log size after spawning child.
2625          * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
2626          * The parent smbd will log to logserver.smb. 
2627          * It writes only two messages for each child
2628          * started/finished. But each child writes, say, 50 messages also in
2629          * logserver.smb, begining with the debug_count of the parent, before the
2630          * child opens its own log file logserver.client. In a worst case
2631          * scenario the size of logserver.smb would be checked after about
2632          * 50*50=2500 messages (ca. 100kb).
2633          */
2634         force_check_log_size();
2635  
2636       } /* end for num */
2637     } /* end while 1 */
2638   } /* end if is_daemon */
2639   else
2640   {
2641     /* Started from inetd. fd 0 is the socket. */
2642     /* We will abort gracefully when the client or remote system 
2643        goes away */
2644     CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2645     Client = dup(0);
2646
2647     /* close our standard file descriptors */
2648     close_low_fds();
2649
2650     set_socket_options(Client,"SO_KEEPALIVE");
2651     set_socket_options(Client,user_socket_options);
2652   }
2653
2654   return True;
2655 }
2656
2657 /****************************************************************************
2658   process an smb from the client - split out from the process() code so
2659   it can be used by the oplock break code.
2660 ****************************************************************************/
2661
2662 static void process_smb(char *inbuf, char *outbuf)
2663 {
2664   extern int Client;
2665 #ifdef WITH_SSL
2666   extern BOOL sslEnabled;     /* don't use function for performance reasons */
2667   static int sslConnected = 0;
2668 #endif /* WITH_SSL */
2669   static int trans_num;
2670   int msg_type = CVAL(inbuf,0);
2671   int32 len = smb_len(inbuf);
2672   int nread = len + 4;
2673
2674   if (trans_num == 0) {
2675           /* on the first packet, check the global hosts allow/ hosts
2676              deny parameters before doing any parsing of the packet
2677              passed to us by the client.  This prevents attacks on our
2678              parsing code from hosts not in the hosts allow list */
2679           if (!check_access(-1)) {
2680                   /* send a negative session response "not listining on calling
2681                    name" */
2682                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2683                   DEBUG(1,("%s Connection denied from %s\n",
2684                            timestring(),client_addr(Client)));
2685                   send_smb(Client,(char *)buf);
2686                   exit_server("connection denied");
2687           }
2688   }
2689
2690   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2691   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2692
2693 #ifdef WITH_SSL
2694     if(sslEnabled && !sslConnected){
2695         sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2696         if(sslConnected < 0){   /* an error occured */
2697             exit_server("SSL negotiation failed");
2698         }else if(sslConnected){
2699             trans_num++;
2700             return;
2701         }
2702     }
2703 #endif  /* WITH_SSL */
2704
2705 #ifdef WITH_VTP
2706   if(trans_num == 1 && VT_Check(inbuf)) 
2707   {
2708     VT_Process();
2709     return;
2710   }
2711 #endif
2712
2713   if (msg_type == 0)
2714     show_msg(inbuf);
2715   else if(msg_type == 0x85)
2716     return; /* Keepalive packet. */
2717
2718   nread = construct_reply(inbuf,outbuf,nread,max_send);
2719       
2720   if(nread > 0) 
2721   {
2722     if (CVAL(outbuf,0) == 0)
2723       show_msg(outbuf);
2724         
2725     if (nread != smb_len(outbuf) + 4) 
2726     {
2727       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2728                  nread, smb_len(outbuf)));
2729     }
2730     else
2731       send_smb(Client,outbuf);
2732   }
2733   trans_num++;
2734 }
2735
2736 /****************************************************************************
2737   open the oplock IPC socket communication
2738 ****************************************************************************/
2739 static BOOL open_oplock_ipc(void)
2740 {
2741   struct sockaddr_in sock_name;
2742   int len = sizeof(sock_name);
2743
2744   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2745
2746   /* Open a lookback UDP socket on a random port. */
2747   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2748   if (oplock_sock == -1)
2749   {
2750     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2751 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2752     oplock_port = 0;
2753     return(False);
2754   }
2755
2756   /* Find out the transient UDP port we have been allocated. */
2757   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2758   {
2759     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2760             strerror(errno)));
2761     close(oplock_sock);
2762     oplock_sock = -1;
2763     oplock_port = 0;
2764     return False;
2765   }
2766   oplock_port = ntohs(sock_name.sin_port);
2767
2768   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2769             getpid(), oplock_port));
2770
2771   return True;
2772 }
2773
2774 /****************************************************************************
2775   process an oplock break message.
2776 ****************************************************************************/
2777 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2778 {
2779   int32 msg_len;
2780   uint16 from_port;
2781   char *msg_start;
2782
2783   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2784   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2785
2786   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2787
2788   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2789             msg_len, from_port));
2790
2791   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2792      only valid request. */
2793
2794   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2795   {
2796     case OPLOCK_BREAK_CMD:
2797       /* Ensure that the msg length is correct. */
2798       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2799       {
2800         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2801 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2802         return False;
2803       }
2804       {
2805         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2806         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2807         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2808         struct timeval tval;
2809         struct sockaddr_in toaddr;
2810
2811         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2812         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2813
2814         DEBUG(5,("process_local_message: oplock break request from \
2815 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2816
2817         /*
2818          * If we have no record of any currently open oplocks,
2819          * it's not an error, as a close command may have
2820          * just been issued on the file that was oplocked.
2821          * Just return success in this case.
2822          */
2823
2824         if(global_oplocks_open != 0)
2825         {
2826           if(oplock_break(dev, inode, &tval) == False)
2827           {
2828             DEBUG(0,("process_local_message: oplock break failed - \
2829 not returning udp message.\n"));
2830             return False;
2831           }
2832         }
2833         else
2834         {
2835           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2836 oplocks. Returning success.\n"));
2837         }
2838
2839         /* Send the message back after OR'ing in the 'REPLY' bit. */
2840         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2841   
2842         bzero((char *)&toaddr,sizeof(toaddr));
2843         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2844         toaddr.sin_port = htons(from_port);
2845         toaddr.sin_family = AF_INET;
2846
2847         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2848                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2849         {
2850           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2851                     remotepid, strerror(errno)));
2852           return False;
2853         }
2854
2855         DEBUG(5,("process_local_message: oplock break reply sent to \
2856 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2857                 from_port, dev, inode));
2858
2859       }
2860       break;
2861     /* 
2862      * Keep this as a debug case - eventually we can remove it.
2863      */
2864     case 0x8001:
2865       DEBUG(0,("process_local_message: Received unsolicited break \
2866 reply - dumping info.\n"));
2867
2868       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2869       {
2870         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2871 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2872         return False;
2873       }
2874
2875       {
2876         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2877         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2878         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2879
2880         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2881 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2882
2883        }
2884        return False;
2885
2886     default:
2887       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2888                 (unsigned int)SVAL(msg_start,0)));
2889       return False;
2890   }
2891   return True;
2892 }
2893
2894 /****************************************************************************
2895  Process an oplock break directly.
2896 ****************************************************************************/
2897 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2898 {
2899   extern struct current_user current_user;
2900   extern int Client;
2901   char *inbuf = NULL;
2902   char *outbuf = NULL;
2903   files_struct *fsp = NULL;
2904   int fnum;
2905   time_t start_time;
2906   BOOL shutdown_server = False;
2907   int saved_cnum;
2908   int saved_vuid;
2909   pstring saved_dir; 
2910
2911   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2912 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2913
2914   /* We need to search the file open table for the
2915      entry containing this dev and inode, and ensure
2916      we have an oplock on it. */
2917   for( fnum = 0; fnum < MAX_FNUMS; fnum++)
2918   {
2919     if(OPEN_FNUM(fnum))
2920     {
2921       if((Files[fnum].f_u.fd_ptr->dev == dev) && (Files[fnum].f_u.fd_ptr->inode == inode) &&
2922          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
2923          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2924               fsp = &Files[fnum];
2925               break;
2926       }
2927     }
2928   }
2929
2930   if(fsp == NULL)
2931   {
2932     /* The file could have been closed in the meantime - return success. */
2933     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2934 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2935     return True;
2936   }
2937
2938   /* Ensure we have an oplock on the file */
2939
2940   /* There is a potential race condition in that an oplock could
2941      have been broken due to another udp request, and yet there are
2942      still oplock break messages being sent in the udp message
2943      queue for this file. So return true if we don't have an oplock,
2944      as we may have just freed it.
2945    */
2946
2947   if(!fsp->granted_oplock)
2948   {
2949     DEBUG(0,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2950     return True;
2951   }
2952
2953   /* mark the oplock break as sent - we don't want to send twice! */
2954   if (fsp->sent_oplock_break)
2955   {
2956     DEBUG(0,("%s oplock_break: ERROR: oplock_break already sent for file %s (fnum = %d, dev = %x, inode = %x)\n", timestring(), fsp->name, fnum, dev, inode));
2957
2958     /* We have to fail the open here as we cannot send another oplock break on this
2959        file whilst we are awaiting a response from the client - neither can we
2960        allow another open to succeed while we are waiting for the client. */
2961     return False;
2962   }
2963
2964   /* Now comes the horrid part. We must send an oplock break to the client,
2965      and then process incoming messages until we get a close or oplock release.
2966      At this point we know we need a new inbuf/outbuf buffer pair.
2967      We cannot use these staticaly as we may recurse into here due to
2968      messages crossing on the wire.
2969    */
2970
2971   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2972   {
2973     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2974     return False;
2975   }
2976
2977   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2978   {
2979     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2980     free(inbuf);
2981     inbuf = NULL;
2982     return False;
2983   }
2984
2985   /* Prepare the SMBlockingX message. */
2986   bzero(outbuf,smb_size);
2987   set_message(outbuf,8,0,True);
2988
2989   SCVAL(outbuf,smb_com,SMBlockingX);
2990   SSVAL(outbuf,smb_tid,fsp->cnum);
2991   SSVAL(outbuf,smb_pid,0xFFFF);
2992   SSVAL(outbuf,smb_uid,0);
2993   SSVAL(outbuf,smb_mid,0xFFFF);
2994   SCVAL(outbuf,smb_vwv0,0xFF);
2995   SSVAL(outbuf,smb_vwv2,fnum);
2996   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2997   /* Change this when we have level II oplocks. */
2998   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2999  
3000   send_smb(Client, outbuf);
3001
3002   /* Remember we just sent an oplock break on this file. */
3003   fsp->sent_oplock_break = True;
3004
3005   /* We need this in case a readraw crosses on the wire. */
3006   global_oplock_break = True;
3007  
3008   /* Process incoming messages. */
3009
3010   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
3011      seconds we should just die.... */
3012
3013   start_time = time(NULL);
3014
3015   /*
3016    * Save the information we need to re-become the
3017    * user, then unbecome the user whilst we're doing this.
3018    */
3019   saved_cnum = fsp->cnum;
3020   saved_vuid = current_user.vuid;
3021   GetWd(saved_dir);
3022   unbecome_user();
3023
3024   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
3025   {
3026     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
3027     {
3028       /*
3029        * Die if we got an error.
3030        */
3031
3032       if (smb_read_error == READ_EOF)
3033         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
3034  
3035       if (smb_read_error == READ_ERROR)
3036         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
3037                   timestring(), strerror(errno)));
3038
3039       if (smb_read_error == READ_TIMEOUT)
3040         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
3041                   timestring(), OPLOCK_BREAK_TIMEOUT));
3042
3043       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3044 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3045       shutdown_server = True;
3046       break;
3047     }
3048
3049     /*
3050      * There are certain SMB requests that we shouldn't allow
3051      * to recurse. opens, renames and deletes are the obvious
3052      * ones. This is handled in the switch_message() function.
3053      * If global_oplock_break is set they will push the packet onto
3054      * the pending smb queue and return -1 (no reply).
3055      * JRA.
3056      */
3057
3058     process_smb(inbuf, outbuf);
3059
3060     /*
3061      * Die if we go over the time limit.
3062      */
3063
3064     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3065     {
3066       DEBUG(0,("%s oplock_break: no break received from client within \
3067 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3068       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3069 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3070       shutdown_server = True;
3071       break;
3072     }
3073   }
3074
3075   /*
3076    * Go back to being the user who requested the oplock
3077    * break.
3078    */
3079   if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3080   {
3081     DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3082           timestring()));
3083     close_sockets();
3084     close(oplock_sock);
3085     exit_server("unable to re-become user");
3086   }
3087   /* Including the directory. */
3088   ChDir(saved_dir);
3089
3090   /* Free the buffers we've been using to recurse. */
3091   free(inbuf);
3092   free(outbuf);
3093
3094   /* We need this in case a readraw crossed on the wire. */
3095   if(global_oplock_break)
3096     global_oplock_break = False;
3097
3098   /*
3099    * If the client did not respond we must die.
3100    */
3101
3102   if(shutdown_server)
3103   {
3104     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3105           timestring()));
3106     close_sockets();
3107     close(oplock_sock);
3108     exit_server("oplock break failure");
3109   }
3110
3111   if(OPEN_FNUM(fnum))
3112   {
3113     /* The lockingX reply will have removed the oplock flag 
3114        from the sharemode. */
3115     /* Paranoia.... */
3116     fsp->granted_oplock = False;
3117     fsp->sent_oplock_break = False;
3118     global_oplocks_open--;
3119   }
3120
3121   /* Santity check - remove this later. JRA */
3122   if(global_oplocks_open < 0)
3123   {
3124     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3125               global_oplocks_open));
3126     exit_server("oplock_break: global_oplocks_open < 0");
3127   }
3128
3129   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3130 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3131
3132   return True;
3133 }
3134
3135 /****************************************************************************
3136 Send an oplock break message to another smbd process. If the oplock is held 
3137 by the local smbd then call the oplock break function directly.
3138 ****************************************************************************/
3139
3140 BOOL request_oplock_break(share_mode_entry *share_entry, 
3141                           uint32 dev, uint32 inode)
3142 {
3143   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3144   struct sockaddr_in addr_out;
3145   int pid = getpid();
3146   time_t start_time;
3147   int time_left;
3148
3149   if(pid == share_entry->pid)
3150   {
3151     /* We are breaking our own oplock, make sure it's us. */
3152     if(share_entry->op_port != oplock_port)
3153     {
3154       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3155 should be %d\n", pid, share_entry->op_port, oplock_port));
3156       return False;
3157     }
3158
3159     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3160
3161     /* Call oplock break direct. */
3162     return oplock_break(dev, inode, &share_entry->time);
3163   }
3164
3165   /* We need to send a OPLOCK_BREAK_CMD message to the
3166      port in the share mode entry. */
3167
3168   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3169   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3170   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3171   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3172   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3173   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3174
3175   /* set the address and port */
3176   bzero((char *)&addr_out,sizeof(addr_out));
3177   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3178   addr_out.sin_port = htons( share_entry->op_port );
3179   addr_out.sin_family = AF_INET;
3180    
3181   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3182 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3183
3184   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3185          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3186   {
3187     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3188 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3189          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3190          strerror(errno)));
3191     return False;
3192   }
3193
3194   /*
3195    * Now we must await the oplock broken message coming back
3196    * from the target smbd process. Timeout if it fails to
3197    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3198    * While we get messages that aren't ours, loop.
3199    */
3200
3201   start_time = time(NULL);
3202   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3203
3204   while(time_left >= 0)
3205   {
3206     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3207     int32 reply_msg_len;
3208     uint16 reply_from_port;
3209     char *reply_msg_start;
3210
3211     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3212                time_left ? time_left * 1000 : 1) == False)
3213     {
3214       if(smb_read_error == READ_TIMEOUT)
3215       {
3216         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3217 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3218                            share_entry->op_port, dev, inode));
3219         /*
3220          * This is a hack to make handling of failing clients more robust.
3221          * If a oplock break response message is not received in the timeout
3222          * period we may assume that the smbd servicing that client holding
3223          * the oplock has died and the client changes were lost anyway, so
3224          * we should continue to try and open the file.
3225          */
3226         break;
3227       }
3228       else
3229         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3230 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3231                          share_entry->op_port, dev, inode, strerror(errno)));
3232       return False;
3233     }
3234
3235     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3236     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3237
3238     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3239
3240     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3241     {
3242       /* Ignore it. */
3243       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3244              timestring()));
3245       continue;
3246     }
3247
3248     /*
3249      * Test to see if this is the reply we are awaiting.
3250      */
3251
3252     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3253        (reply_from_port == share_entry->op_port) && 
3254        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3255                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3256                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3257     {
3258       /*
3259        * This is the reply we've been waiting for.
3260        */
3261       break;
3262     }
3263     else
3264     {
3265       /*
3266        * This is another message - probably a break request.
3267        * Process it to prevent potential deadlock.
3268        * Note that the code in switch_message() prevents
3269        * us from recursing into here as any SMB requests
3270        * we might process that would cause another oplock
3271        * break request to be made will be queued.
3272        * JRA.
3273        */
3274
3275       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3276     }
3277
3278     time_left -= (time(NULL) - start_time);
3279   }
3280
3281   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3282
3283   return True;
3284 }
3285
3286 /****************************************************************************
3287 Get the next SMB packet, doing the local message processing automatically.
3288 ****************************************************************************/
3289
3290 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3291 {
3292   BOOL got_smb = False;
3293   BOOL ret;
3294
3295   do
3296   {
3297     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3298                                  timeout,&got_smb);
3299
3300     if(ret && !got_smb)
3301     {
3302       /* Deal with oplock break requests from other smbd's. */
3303       process_local_message(oplock_sock, inbuf, bufsize);
3304       continue;
3305     }
3306
3307     if(ret && (CVAL(inbuf,0) == 0x85))
3308     {
3309       /* Keepalive packet. */
3310       got_smb = False;
3311     }
3312
3313   }
3314   while(ret && !got_smb);
3315
3316   return ret;
3317 }
3318
3319 /****************************************************************************
3320 check if a snum is in use
3321 ****************************************************************************/
3322 BOOL snum_used(int snum)
3323 {
3324   int i;
3325   for (i=0;i<MAX_CONNECTIONS;i++)
3326     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3327       return(True);
3328   return(False);
3329 }
3330
3331 /****************************************************************************
3332   reload the services file
3333   **************************************************************************/
3334 BOOL reload_services(BOOL test)
3335 {
3336   BOOL ret;
3337
3338   if (lp_loaded())
3339   {
3340     pstring fname;
3341     pstrcpy(fname,lp_configfile());
3342     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3343     {
3344       pstrcpy(servicesf,fname);
3345       test = False;
3346     }
3347   }
3348
3349   reopen_logs();
3350
3351   if (test && !lp_file_list_changed())
3352     return(True);
3353
3354   lp_killunused(snum_used);
3355
3356   ret = lp_load(servicesf,False,False,True);
3357
3358   /* perhaps the config filename is now set */
3359   if (!test)
3360     reload_services(True);
3361
3362   reopen_logs();
3363
3364   load_interfaces();
3365
3366   {
3367     extern int Client;
3368     if (Client != -1) {      
3369       set_socket_options(Client,"SO_KEEPALIVE");
3370       set_socket_options(Client,user_socket_options);
3371     }
3372   }
3373
3374   reset_mangled_cache();
3375
3376   /* this forces service parameters to be flushed */
3377   become_service(-1,True);
3378
3379   return(ret);
3380 }
3381
3382
3383
3384 /****************************************************************************
3385 this prevents zombie child processes
3386 ****************************************************************************/
3387 static BOOL reload_after_sighup = False;
3388
3389 static int sig_hup(void)
3390 {
3391   BlockSignals(True,SIGHUP);
3392   DEBUG(0,("Got SIGHUP\n"));
3393
3394   /*
3395    * Fix from <branko.cibej@hermes.si> here.
3396    * We used to reload in the signal handler - this
3397    * is a *BIG* no-no.
3398    */
3399
3400   reload_after_sighup = True;
3401   BlockSignals(False,SIGHUP);
3402   return(0);
3403 }
3404
3405
3406 /****************************************************************************
3407   make a connection to a service
3408 ****************************************************************************/
3409 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3410 {
3411   int cnum;
3412   int snum;
3413   struct passwd *pass = NULL;
3414   connection_struct *pcon;
3415   BOOL guest = False;
3416   BOOL force = False;
3417
3418   strlower(service);
3419
3420   snum = find_service(service);
3421   if (snum < 0)
3422     {
3423       extern int Client;
3424       if (strequal(service,"IPC$"))
3425         {         
3426           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3427           return(-3);
3428         }
3429
3430       DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));      
3431       return(-2);
3432     }
3433
3434   if (strequal(service,HOMES_NAME))
3435     {
3436       if (*user && Get_Pwnam(user,True))
3437         return(make_connection(user,user,password,pwlen,dev,vuid));
3438
3439       if(lp_security() != SEC_SHARE)
3440       {
3441         if (validated_username(vuid))
3442         {
3443           pstrcpy(user,validated_username(vuid));
3444           return(make_connection(user,user,password,pwlen,dev,vuid));
3445         }
3446       }
3447       else
3448       {
3449         /*
3450          * Security = share. Try with sesssetup_user as the username.
3451          */
3452         if(*sesssetup_user)
3453         {
3454           pstrcpy(user,sesssetup_user);
3455           return(make_connection(user,user,password,pwlen,dev,vuid));
3456         }
3457       }
3458     }
3459
3460   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3461     return(-4);
3462   }
3463
3464   /* you can only connect to the IPC$ service as an ipc device */
3465   if (strequal(service,"IPC$"))
3466     pstrcpy(dev,"IPC");
3467
3468   if (*dev == '?' || !*dev)
3469     {
3470       if (lp_print_ok(snum))
3471         pstrcpy(dev,"LPT1:");
3472       else
3473         pstrcpy(dev,"A:");
3474     }
3475
3476   /* if the request is as a printer and you can't print then refuse */
3477   strupper(dev);
3478   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3479     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3480     return(-6);
3481   }
3482
3483   /* lowercase the user name */
3484   strlower(user);
3485
3486   /* add it as a possible user name */
3487   add_session_user(service);
3488
3489   /* shall we let them in? */
3490   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3491     {
3492       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3493       return(-1);
3494     }
3495   
3496   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3497   if (cnum < 0)
3498     {
3499       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3500       return(-1);
3501     }
3502
3503   pcon = &Connections[cnum];
3504   bzero((char *)pcon,sizeof(*pcon));
3505
3506   /* find out some info about the user */
3507   pass = Get_Pwnam(user,True);
3508
3509   if (pass == NULL)
3510     {
3511       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3512       return(-7);
3513     }
3514
3515   pcon->read_only = lp_readonly(snum);
3516
3517   {
3518     pstring list;
3519     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3520     string_sub(list,"%S",service);
3521
3522     if (user_in_list(user,list))
3523       pcon->read_only = True;
3524
3525     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3526     string_sub(list,"%S",service);
3527
3528     if (user_in_list(user,list))
3529       pcon->read_only = False;    
3530   }
3531
3532   /* admin user check */
3533
3534   /* JRA - original code denied admin user if the share was
3535      marked read_only. Changed as I don't think this is needed,
3536      but old code left in case there is a problem here.
3537    */
3538   if (user_in_list(user,lp_admin_users(snum)) 
3539 #if 0
3540       && !pcon->read_only)
3541 #else
3542       )
3543 #endif
3544     {
3545       pcon->admin_user = True;
3546       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3547     }
3548   else
3549     pcon->admin_user = False;
3550     
3551   pcon->force_user = force;
3552   pcon->vuid = vuid;
3553   pcon->uid = pass->pw_uid;
3554   pcon->gid = pass->pw_gid;
3555   pcon->num_files_open = 0;
3556   pcon->lastused = time(NULL);
3557   pcon->service = snum;
3558   pcon->used = True;
3559   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3560   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3561   pcon->dirptr = NULL;
3562   pcon->veto_list = NULL;
3563   pcon->hide_list = NULL;
3564   pcon->veto_oplock_list = NULL;
3565   string_set(&pcon->dirpath,"");
3566   string_set(&pcon->user,user);
3567
3568 #ifdef HAVE_GETGRNAM 
3569   if (*lp_force_group(snum))
3570     {
3571       struct group *gptr;
3572       pstring gname;
3573
3574       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3575       /* default service may be a group name            */
3576       string_sub(gname,"%S",service);
3577       gptr = (struct group *)getgrnam(gname);
3578
3579       if (gptr)
3580         {
3581           pcon->gid = gptr->gr_gid;
3582           DEBUG(3,("Forced group %s\n",gname));
3583         }
3584       else
3585         DEBUG(1,("Couldn't find group %s\n",gname));
3586     }
3587 #endif
3588
3589   if (*lp_force_user(snum))
3590     {
3591       struct passwd *pass2;
3592       fstring fuser;
3593       fstrcpy(fuser,lp_force_user(snum));
3594       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3595       if (pass2)
3596         {
3597           pcon->uid = pass2->pw_uid;
3598           string_set(&pcon->user,fuser);
3599           fstrcpy(user,fuser);
3600           pcon->force_user = True;
3601           DEBUG(3,("Forced user %s\n",fuser));    
3602         }
3603       else
3604         DEBUG(1,("Couldn't find user %s\n",fuser));
3605     }
3606
3607   {
3608     pstring s;
3609     pstrcpy(s,lp_pathname(snum));
3610     standard_sub(cnum,s);
3611     string_set(&pcon->connectpath,s);
3612     DEBUG(3,("Connect path is %s\n",s));
3613   }
3614
3615   /* groups stuff added by ih */
3616   pcon->ngroups = 0;
3617   pcon->groups = NULL;
3618
3619   if (!IS_IPC(cnum))
3620     {
3621       /* Find all the groups this uid is in and store them. Used by become_user() */
3622       setup_groups(pcon->user,pcon->uid,pcon->gid,
3623                   &pcon->ngroups,&pcon->groups);
3624       
3625       /* check number of connections */
3626       if (!claim_connection(cnum,
3627                             lp_servicename(SNUM(cnum)),
3628                             lp_max_connections(SNUM(cnum)),False))
3629         {
3630           DEBUG(1,("too many connections - rejected\n"));
3631           return(-8);
3632         }  
3633
3634       if (lp_status(SNUM(cnum)))
3635         claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3636     } /* IS_IPC */
3637
3638   pcon->open = True;
3639
3640   /* execute any "root preexec = " line */
3641   if (*lp_rootpreexec(SNUM(cnum)))
3642     {
3643       pstring cmd;
3644       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3645       standard_sub(cnum,cmd);
3646       DEBUG(5,("cmd=%s\n",cmd));
3647       smbrun(cmd,NULL,False);
3648     }
3649
3650   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3651     {
3652       DEBUG(0,("Can't become connected user!\n"));
3653       pcon->open = False;
3654       if (!IS_IPC(cnum)) {
3655         yield_connection(cnum,
3656                          lp_servicename(SNUM(cnum)),
3657                          lp_max_connections(SNUM(cnum)));
3658         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3659       }
3660       return(-1);
3661     }
3662
3663   if (ChDir(pcon->connectpath) != 0)
3664     {
3665       DEBUG(0,("Can't change directory to %s (%s)\n",
3666                pcon->connectpath,strerror(errno)));
3667       pcon->open = False;
3668       unbecome_user();
3669       if (!IS_IPC(cnum)) {
3670         yield_connection(cnum,
3671                          lp_servicename(SNUM(cnum)),
3672                          lp_max_connections(SNUM(cnum)));
3673         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3674       }
3675       return(-5);      
3676     }
3677
3678   string_set(&pcon->origpath,pcon->connectpath);
3679
3680 #if SOFTLINK_OPTIMISATION
3681   /* resolve any soft links early */
3682   {
3683     pstring s;
3684     pstrcpy(s,pcon->connectpath);
3685     GetWd(s);
3686     string_set(&pcon->connectpath,s);
3687     ChDir(pcon->connectpath);
3688   }
3689 #endif
3690
3691   num_connections_open++;
3692   add_session_user(user);
3693   
3694   /* execute any "preexec = " line */
3695   if (*lp_preexec(SNUM(cnum)))
3696     {
3697       pstring cmd;
3698       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3699       standard_sub(cnum,cmd);
3700       smbrun(cmd,NULL,False);
3701     }
3702   
3703   /* we've finished with the sensitive stuff */
3704   unbecome_user();
3705
3706   /* Add veto/hide lists */
3707   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3708   {
3709     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3710     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3711     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3712   }
3713
3714   {
3715     extern int Client;
3716     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3717                             timestring(),
3718                             remote_machine,
3719                             client_addr(Client),
3720                             lp_servicename(SNUM(cnum)),user,
3721                             pcon->uid,
3722                             pcon->gid,
3723                             (int)getpid()));
3724   }
3725
3726   return(cnum);
3727 }
3728
3729 /****************************************************************************
3730   Attempt to break an oplock on a file (if oplocked).
3731   Returns True if the file was closed as a result of
3732   the oplock break, False otherwise.
3733   Used as a last ditch attempt to free a space in the 
3734   file table when we have run out.
3735 ****************************************************************************/
3736
3737 static BOOL attempt_close_oplocked_file(files_struct *fsp)
3738 {
3739
3740   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->name));
3741
3742   if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
3743
3744     /* Try and break the oplock. */
3745     file_fd_struct *fd_ptr = fsp->f_u.fd_ptr;
3746     if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
3747       if(!fsp->open) /* Did the oplock break close the file ? */
3748         return True;
3749     }
3750   }
3751
3752   return False;
3753 }
3754
3755 /****************************************************************************
3756   find first available file slot
3757 ****************************************************************************/
3758 int find_free_file(void )
3759 {
3760         int i;
3761         static int first_file;
3762
3763         /* we want to give out file handles differently on each new
3764            connection because of a common bug in MS clients where they try to
3765            reuse a file descriptor from an earlier smb connection. This code
3766            increases the chance that the errant client will get an error rather
3767            than causing corruption */
3768         if (first_file == 0) {
3769                 first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
3770                 if (first_file == 0) first_file = 1;
3771         }
3772
3773         if (first_file >= MAX_FNUMS)
3774                 first_file = 1;
3775
3776         for (i=first_file;i<MAX_FNUMS;i++)
3777                 if (!Files[i].open && !Files[i].reserved) {
3778                         memset(&Files[i], 0, sizeof(Files[i]));
3779                         first_file = i+1;
3780                         Files[i].reserved = True;
3781                         return(i);
3782                 }
3783
3784         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3785         for (i=1;i<first_file;i++)
3786                 if (!Files[i].open && !Files[i].reserved) {
3787                         memset(&Files[i], 0, sizeof(Files[i]));
3788                         first_file = i+1;
3789                         Files[i].reserved = True;
3790                         return(i);
3791                 }
3792
3793         /* 
3794          * Before we give up, go through the open files 
3795          * and see if there are any files opened with a
3796          * batch oplock. If so break the oplock and then
3797          * re-use that entry (if it becomes closed).
3798          * This may help as NT/95 clients tend to keep
3799          * files batch oplocked for quite a long time
3800          * after they have finished with them.
3801          */
3802         for (i=first_file;i<MAX_FNUMS;i++) {
3803           if(attempt_close_oplocked_file( &Files[i])) {
3804             memset(&Files[i], 0, sizeof(Files[i]));
3805             first_file = i+1;
3806             Files[i].reserved = True;
3807             return(i);
3808           }
3809         }
3810
3811         for (i=1;i<MAX_FNUMS;i++) {
3812           if(attempt_close_oplocked_file( &Files[i])) {
3813             memset(&Files[i], 0, sizeof(Files[i]));
3814             first_file = i+1;
3815             Files[i].reserved = True;
3816             return(i);
3817           }
3818         }
3819
3820         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3821         return(-1);
3822 }
3823
3824 /****************************************************************************
3825   find first available connection slot, starting from a random position.
3826 The randomisation stops problems with the server dieing and clients
3827 thinking the server is still available.
3828 ****************************************************************************/
3829 static int find_free_connection(int hash )
3830 {
3831   int i;
3832   BOOL used=False;
3833   hash = (hash % (MAX_CONNECTIONS-2))+1;
3834
3835  again:
3836
3837   for (i=hash+1;i!=hash;)
3838     {
3839       if (!Connections[i].open && Connections[i].used == used) 
3840         {
3841           DEBUG(3,("found free connection number %d\n",i));
3842           return(i);
3843         }
3844       i++;
3845       if (i == MAX_CONNECTIONS)
3846         i = 1;
3847     }
3848
3849   if (!used)
3850     {
3851       used = !used;
3852       goto again;
3853     }
3854
3855   DEBUG(1,("ERROR! Out of connection structures\n"));
3856   return(-1);
3857 }
3858
3859
3860 /****************************************************************************
3861 reply for the core protocol
3862 ****************************************************************************/
3863 int reply_corep(char *outbuf)
3864 {
3865   int outsize = set_message(outbuf,1,0,True);
3866
3867   Protocol = PROTOCOL_CORE;
3868
3869   return outsize;
3870 }
3871
3872
3873 /****************************************************************************
3874 reply for the coreplus protocol
3875 ****************************************************************************/
3876 int reply_coreplus(char *outbuf)
3877 {
3878   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3879   int outsize = set_message(outbuf,13,0,True);
3880   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3881                                  readbraw and writebraw (possibly) */
3882   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3883   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3884
3885   Protocol = PROTOCOL_COREPLUS;
3886
3887   return outsize;
3888 }
3889
3890
3891 /****************************************************************************
3892 reply for the lanman 1.0 protocol
3893 ****************************************************************************/
3894 int reply_lanman1(char *outbuf)
3895 {
3896   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3897   int secword=0;
3898   BOOL doencrypt = SMBENCRYPT();
3899   time_t t = time(NULL);
3900
3901   if (lp_security()>=SEC_USER) secword |= 1;
3902   if (doencrypt) secword |= 2;
3903
3904   set_message(outbuf,13,doencrypt?8:0,True);
3905   SSVAL(outbuf,smb_vwv1,secword); 
3906   /* Create a token value and add it to the outgoing packet. */
3907   if (doencrypt) 
3908     generate_next_challenge(smb_buf(outbuf));
3909
3910   Protocol = PROTOCOL_LANMAN1;
3911
3912   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3913   SSVAL(outbuf,smb_vwv2,max_recv);
3914   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3915   SSVAL(outbuf,smb_vwv4,1);
3916   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3917                                  readbraw writebraw (possibly) */
3918   SIVAL(outbuf,smb_vwv6,getpid());
3919   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3920
3921   put_dos_date(outbuf,smb_vwv8,t);
3922
3923   return (smb_len(outbuf)+4);
3924 }
3925
3926
3927 /****************************************************************************
3928 reply for the lanman 2.0 protocol
3929 ****************************************************************************/
3930 int reply_lanman2(char *outbuf)
3931 {
3932   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3933   int secword=0;
3934   BOOL doencrypt = SMBENCRYPT();
3935   time_t t = time(NULL);
3936   struct cli_state *cli = NULL;
3937   char cryptkey[8];
3938   char crypt_len = 0;
3939
3940   if (lp_security() == SEC_SERVER) {
3941           cli = server_cryptkey();
3942   }
3943
3944   if (cli) {
3945           DEBUG(3,("using password server validation\n"));
3946           doencrypt = ((cli->sec_mode & 2) != 0);
3947   }
3948
3949   if (lp_security()>=SEC_USER) secword |= 1;
3950   if (doencrypt) secword |= 2;
3951
3952   if (doencrypt) {
3953           crypt_len = 8;
3954           if (!cli) {
3955                   generate_next_challenge(cryptkey);
3956           } else {
3957                   memcpy(cryptkey, cli->cryptkey, 8);
3958                   set_challenge(cli->cryptkey);
3959           }
3960   }
3961
3962   set_message(outbuf,13,crypt_len,True);
3963   SSVAL(outbuf,smb_vwv1,secword); 
3964   SIVAL(outbuf,smb_vwv6,getpid());
3965   if (doencrypt) 
3966           memcpy(smb_buf(outbuf), cryptkey, 8);
3967
3968   Protocol = PROTOCOL_LANMAN2;
3969
3970   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3971   SSVAL(outbuf,smb_vwv2,max_recv);
3972   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3973   SSVAL(outbuf,smb_vwv4,1);
3974   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3975   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3976   put_dos_date(outbuf,smb_vwv8,t);
3977
3978   return (smb_len(outbuf)+4);
3979 }
3980
3981
3982 /****************************************************************************
3983 reply for the nt protocol
3984 ****************************************************************************/
3985 int reply_nt1(char *outbuf)
3986 {
3987   /* dual names + lock_and_read + nt SMBs + remote API calls */
3988   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
3989
3990 /*
3991   other valid capabilities which we may support at some time...
3992                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3993                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3994  */
3995
3996   int secword=0;
3997   BOOL doencrypt = SMBENCRYPT();
3998   time_t t = time(NULL);
3999   int data_len;
4000   struct cli_state *cli = NULL;
4001   char cryptkey[8];
4002   char crypt_len = 0;
4003
4004   if (lp_security() == SEC_SERVER) {
4005           cli = server_cryptkey();
4006   }
4007
4008   if (cli) {
4009           DEBUG(3,("using password server validation\n"));
4010           doencrypt = ((cli->sec_mode & 2) != 0);
4011   }
4012
4013   if (doencrypt) {
4014           crypt_len = 8;
4015           if (!cli) {
4016                   generate_next_challenge(cryptkey);
4017           } else {
4018                   memcpy(cryptkey, cli->cryptkey, 8);
4019                   set_challenge(cli->cryptkey);
4020           }
4021   }
4022
4023   if (lp_readraw() && lp_writeraw()) {
4024           capabilities |= CAP_RAW_MODE;
4025   }
4026
4027   if (lp_security() >= SEC_USER) secword |= 1;
4028   if (doencrypt) secword |= 2;
4029
4030   /* decide where (if) to put the encryption challenge, and
4031      follow it with the OEM'd domain name
4032    */
4033   data_len = crypt_len + strlen(global_myworkgroup) + 1;
4034
4035   set_message(outbuf,17,data_len,True);
4036   pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
4037
4038   CVAL(outbuf,smb_vwv1) = secword;
4039   SSVALS(outbuf,smb_vwv16+1,crypt_len);
4040   if (doencrypt) 
4041           memcpy(smb_buf(outbuf), cryptkey, 8);
4042
4043   Protocol = PROTOCOL_NT1;
4044
4045   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4046   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4047   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4048   SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4049   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4050   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4051   put_long_date(outbuf+smb_vwv11+1,t);
4052   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4053   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4054
4055   return (smb_len(outbuf)+4);
4056 }
4057
4058 /* these are the protocol lists used for auto architecture detection:
4059
4060 WinNT 3.51:
4061 protocol [PC NETWORK PROGRAM 1.0]
4062 protocol [XENIX CORE]
4063 protocol [MICROSOFT NETWORKS 1.03]
4064 protocol [LANMAN1.0]
4065 protocol [Windows for Workgroups 3.1a]
4066 protocol [LM1.2X002]
4067 protocol [LANMAN2.1]
4068 protocol [NT LM 0.12]
4069
4070 Win95:
4071 protocol [PC NETWORK PROGRAM 1.0]
4072 protocol [XENIX CORE]
4073 protocol [MICROSOFT NETWORKS 1.03]
4074 protocol [LANMAN1.0]
4075 protocol [Windows for Workgroups 3.1a]
4076 protocol [LM1.2X002]
4077 protocol [LANMAN2.1]
4078 protocol [NT LM 0.12]
4079
4080 OS/2:
4081 protocol [PC NETWORK PROGRAM 1.0]
4082 protocol [XENIX CORE]
4083 protocol [LANMAN1.0]
4084 protocol [LM1.2X002]
4085 protocol [LANMAN2.1]
4086 */
4087
4088 /*
4089   * Modified to recognize the architecture of the remote machine better.
4090   *
4091   * This appears to be the matrix of which protocol is used by which
4092   * MS product.
4093        Protocol                       WfWg    Win95   WinNT  OS/2
4094        PC NETWORK PROGRAM 1.0          1       1       1      1
4095        XENIX CORE                                      2      2
4096        MICROSOFT NETWORKS 3.0          2       2       
4097        DOS LM1.2X002                   3       3       
4098        MICROSOFT NETWORKS 1.03                         3
4099        DOS LANMAN2.1                   4       4       
4100        LANMAN1.0                                       4      3
4101        Windows for Workgroups 3.1a     5       5       5
4102        LM1.2X002                                       6      4
4103        LANMAN2.1                                       7      5
4104        NT LM 0.12                              6       8
4105   *
4106   *  tim@fsg.com 09/29/95
4107   */
4108   
4109 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4110 #define ARCH_WIN95    0x2
4111 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4112 #define ARCH_WINNT    0x8
4113 #define ARCH_SAMBA    0x10
4114  
4115 #define ARCH_ALL      0x1F
4116  
4117 /* List of supported protocols, most desired first */
4118 struct {
4119   char *proto_name;
4120   char *short_name;
4121   int (*proto_reply_fn)(char *);
4122   int protocol_level;
4123 } supported_protocols[] = {
4124   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4125   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4126   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4127   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4128   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4129   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4130   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4131   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4132   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4133   {NULL,NULL},
4134 };
4135
4136
4137 /****************************************************************************
4138   reply to a negprot
4139 ****************************************************************************/
4140 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4141 {
4142   int outsize = set_message(outbuf,1,0,True);
4143   int Index=0;
4144   int choice= -1;
4145   int protocol;
4146   char *p;
4147   int bcc = SVAL(smb_buf(inbuf),-2);
4148   int arch = ARCH_ALL;
4149
4150   p = smb_buf(inbuf)+1;
4151   while (p < (smb_buf(inbuf) + bcc))
4152     { 
4153       Index++;
4154       DEBUG(3,("Requested protocol [%s]\n",p));
4155       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4156         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4157       else if (strcsequal(p,"DOS LM1.2X002"))
4158         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4159       else if (strcsequal(p,"DOS LANMAN2.1"))
4160         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4161       else if (strcsequal(p,"NT LM 0.12"))
4162         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4163       else if (strcsequal(p,"LANMAN2.1"))
4164         arch &= ( ARCH_WINNT | ARCH_OS2 );
4165       else if (strcsequal(p,"LM1.2X002"))
4166         arch &= ( ARCH_WINNT | ARCH_OS2 );
4167       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4168         arch &= ARCH_WINNT;
4169       else if (strcsequal(p,"XENIX CORE"))
4170         arch &= ( ARCH_WINNT | ARCH_OS2 );
4171       else if (strcsequal(p,"Samba")) {
4172         arch = ARCH_SAMBA;
4173         break;
4174       }
4175  
4176       p += strlen(p) + 2;
4177     }
4178     
4179   switch ( arch ) {
4180   case ARCH_SAMBA:
4181     set_remote_arch(RA_SAMBA);
4182     break;
4183   case ARCH_WFWG:
4184     set_remote_arch(RA_WFWG);
4185     break;
4186   case ARCH_WIN95:
4187     set_remote_arch(RA_WIN95);
4188     break;
4189   case ARCH_WINNT:
4190     set_remote_arch(RA_WINNT);
4191     break;
4192   case ARCH_OS2:
4193     set_remote_arch(RA_OS2);
4194     break;
4195   default:
4196     set_remote_arch(RA_UNKNOWN);
4197     break;
4198   }
4199  
4200   /* possibly reload - change of architecture */
4201   reload_services(True);      
4202     
4203   /* a special case to stop password server loops */
4204   if (Index == 1 && strequal(remote_machine,myhostname) && 
4205       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4206     exit_server("Password server loop!");
4207   
4208   /* Check for protocols, most desirable first */
4209   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4210     {
4211       p = smb_buf(inbuf)+1;
4212       Index = 0;
4213       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4214         while (p < (smb_buf(inbuf) + bcc))
4215           { 
4216             if (strequal(p,supported_protocols[protocol].proto_name))
4217               choice = Index;
4218             Index++;
4219             p += strlen(p) + 2;
4220           }
4221       if(choice != -1)
4222         break;
4223     }
4224   
4225   SSVAL(outbuf,smb_vwv0,choice);
4226   if(choice != -1) {
4227     extern fstring remote_proto;
4228     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4229     reload_services(True);          
4230     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4231     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4232   }
4233   else {
4234     DEBUG(0,("No protocol supported !\n"));
4235   }
4236   SSVAL(outbuf,smb_vwv0,choice);
4237   
4238   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4239
4240   return(outsize);
4241 }
4242
4243
4244 /****************************************************************************
4245 close all open files for a connection
4246 ****************************************************************************/
4247 static void close_open_files(int cnum)
4248 {
4249   int i;
4250   for (i=0;i<MAX_FNUMS;i++)
4251     if( Files[i].cnum == cnum && Files[i].open) {
4252       if(Files[i].is_directory)
4253         close_directory(i); 
4254       else                  
4255         close_file(i,False); 
4256     }
4257 }
4258
4259
4260
4261 /****************************************************************************
4262 close a cnum
4263 ****************************************************************************/
4264 void close_cnum(int cnum, uint16 vuid)
4265 {
4266   extern int Client;
4267   DirCacheFlush(SNUM(cnum));
4268
4269   unbecome_user();
4270
4271   if (!OPEN_CNUM(cnum))
4272     {
4273       DEBUG(0,("Can't close cnum %d\n",cnum));
4274       return;
4275     }
4276
4277   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4278                           timestring(),
4279                           remote_machine,client_addr(Client),
4280                           lp_servicename(SNUM(cnum))));
4281
4282   yield_connection(cnum,
4283                    lp_servicename(SNUM(cnum)),
4284                    lp_max_connections(SNUM(cnum)));
4285
4286   if (lp_status(SNUM(cnum)))
4287     yield_connection(cnum,"STATUS.",MAXSTATUS);
4288
4289   close_open_files(cnum);
4290   dptr_closecnum(cnum);
4291
4292   /* execute any "postexec = " line */
4293   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4294     {
4295       pstring cmd;
4296       pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4297       standard_sub(cnum,cmd);
4298       smbrun(cmd,NULL,False);
4299       unbecome_user();
4300     }
4301
4302   unbecome_user();
4303   /* execute any "root postexec = " line */
4304   if (*lp_rootpostexec(SNUM(cnum)))
4305     {
4306       pstring cmd;
4307       pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4308       standard_sub(cnum,cmd);
4309       smbrun(cmd,NULL,False);
4310     }
4311
4312   Connections[cnum].open = False;
4313   num_connections_open--;
4314   if (Connections[cnum].ngroups && Connections[cnum].groups)
4315     {
4316       free(Connections[cnum].groups);
4317       Connections[cnum].groups = NULL;
4318       Connections[cnum].ngroups = 0;
4319     }
4320
4321   free_namearray(Connections[cnum].veto_list);
4322   free_namearray(Connections[cnum].hide_list);
4323   free_namearray(Connections[cnum].veto_oplock_list);
4324
4325   string_set(&Connections[cnum].user,"");
4326   string_set(&Connections[cnum].dirpath,"");
4327   string_set(&Connections[cnum].connectpath,"");
4328 }
4329
4330
4331
4332 #if DUMP_CORE
4333 /*******************************************************************
4334 prepare to dump a core file - carefully!
4335 ********************************************************************/
4336 static BOOL dump_core(void)
4337 {
4338   char *p;
4339   pstring dname;
4340   pstrcpy(dname,debugf);
4341   if ((p=strrchr(dname,'/'))) *p=0;
4342   pstrcat(dname,"/corefiles");
4343   mkdir(dname,0700);
4344   sys_chown(dname,getuid(),getgid());
4345   chmod(dname,0700);
4346   if (chdir(dname)) return(False);
4347   umask(~(0700));
4348
4349 #ifdef HAVE_GETRLIMIT
4350 #ifdef RLIMIT_CORE
4351   {
4352     struct rlimit rlp;
4353     getrlimit(RLIMIT_CORE, &rlp);
4354     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4355     setrlimit(RLIMIT_CORE, &rlp);
4356     getrlimit(RLIMIT_CORE, &rlp);
4357     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4358   }
4359 #endif
4360 #endif
4361
4362
4363   DEBUG(0,("Dumping core in %s\n",dname));
4364   return(True);
4365 }
4366 #endif
4367
4368 /****************************************************************************
4369 exit the server
4370 ****************************************************************************/
4371 void exit_server(char *reason)
4372 {
4373   static int firsttime=1;
4374   int i;
4375
4376   if (!firsttime) exit(0);
4377   firsttime = 0;
4378
4379   unbecome_user();
4380   DEBUG(2,("Closing connections\n"));
4381   for (i=0;i<MAX_CONNECTIONS;i++)
4382     if (Connections[i].open)
4383       close_cnum(i,(uint16)-1);
4384 #ifdef WITH_DFS
4385   if (dcelogin_atmost_once)
4386     dfs_unlogin();
4387 #endif
4388   if (!reason) {   
4389     int oldlevel = DEBUGLEVEL;
4390     DEBUGLEVEL = 10;
4391     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4392     if (last_inbuf)
4393       show_msg(last_inbuf);
4394     DEBUGLEVEL = oldlevel;
4395     DEBUG(0,("===============================================================\n"));
4396 #if DUMP_CORE
4397     if (dump_core()) return;
4398 #endif
4399   }    
4400
4401   locking_end();
4402
4403   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4404   exit(0);
4405 }
4406
4407 /****************************************************************************
4408 do some standard substitutions in a string
4409 ****************************************************************************/
4410 void standard_sub(int cnum,char *str)
4411 {
4412   if (VALID_CNUM(cnum)) {
4413     char *p, *s, *home;
4414
4415     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4416       switch (*(p+1)) {
4417         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4418                      string_sub(p,"%H",home);
4419                    else
4420                      p += 2;
4421                    break;
4422         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4423         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4424         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4425         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4426         /* 
4427          * Patch from jkf@soton.ac.uk
4428          * Left the %N (NIS server name) in standard_sub_basic as it
4429          * is a feature for logon servers, hence uses the username.
4430          * The %p (NIS server path) code is here as it is used
4431          * instead of the default "path =" string in [homes] and so
4432          * needs the service name, not the username. 
4433          */
4434         case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4435         case '\0' : p++; break; /* don't run off the end of the string */
4436         default  : p+=2; break;
4437       }
4438     }
4439   }
4440   standard_sub_basic(str);
4441 }
4442
4443 /*
4444 These flags determine some of the permissions required to do an operation 
4445
4446 Note that I don't set NEED_WRITE on some write operations because they
4447 are used by some brain-dead clients when printing, and I don't want to
4448 force write permissions on print services.
4449 */
4450 #define AS_USER (1<<0)
4451 #define NEED_WRITE (1<<1)
4452 #define TIME_INIT (1<<2)
4453 #define CAN_IPC (1<<3)
4454 #define AS_GUEST (1<<5)
4455 #define QUEUE_IN_OPLOCK (1<<6)
4456
4457 /* 
4458    define a list of possible SMB messages and their corresponding
4459    functions. Any message that has a NULL function is unimplemented -
4460    please feel free to contribute implementations!
4461 */
4462 struct smb_message_struct
4463 {
4464   int code;
4465   char *name;
4466   int (*fn)(char *, char *, int, int);
4467   int flags;
4468 #if PROFILING
4469   unsigned long time;
4470 #endif
4471 }
4472  smb_messages[] = {
4473
4474     /* CORE PROTOCOL */
4475
4476    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4477    {SMBtcon,"SMBtcon",reply_tcon,0},
4478    {SMBtdis,"SMBtdis",reply_tdis,0},
4479    {SMBexit,"SMBexit",reply_exit,0},
4480    {SMBioctl,"SMBioctl",reply_ioctl,0},
4481    {SMBecho,"SMBecho",reply_echo,0},
4482    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4483    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4484    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4485    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4486    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4487    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4488    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4489    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4490
4491    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4492    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4493    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4494
4495    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4496    {SMBread,"SMBread",reply_read,AS_USER},
4497    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4498    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4499    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4500    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4501    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4502    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4503
4504    /* this is a Pathworks specific call, allowing the 
4505       changing of the root path */
4506    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4507
4508    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4509    {SMBflush,"SMBflush",reply_flush,AS_USER},
4510    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4511    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4512    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4513    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4514    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4515    {SMBlock,"SMBlock",reply_lock,AS_USER},
4516    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4517    
4518    /* CORE+ PROTOCOL FOLLOWS */
4519    
4520    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4521    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4522    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4523    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4524    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4525    
4526    /* LANMAN1.0 PROTOCOL FOLLOWS */
4527    
4528    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4529    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4530    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4531    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4532    {SMBwritec,"SMBwritec",NULL,AS_USER},
4533    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4534    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4535    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4536    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4537    {SMBioctls,"SMBioctls",NULL,AS_USER},
4538    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4539    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4540    
4541    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4542    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4543    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4544    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4545    
4546    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4547    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4548    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4549
4550    /* LANMAN2.0 PROTOCOL FOLLOWS */
4551    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4552    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4553    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4554    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4555
4556    /* NT PROTOCOL FOLLOWS */
4557    {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4558    {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
4559    {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
4560    {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
4561
4562    /* messaging routines */
4563    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4564    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4565    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4566    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4567
4568    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4569    
4570    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4571    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4572    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4573    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4574  };
4575
4576 /****************************************************************************
4577 return a string containing the function name of a SMB command
4578 ****************************************************************************/
4579 char *smb_fn_name(int type)
4580 {
4581   static char *unknown_name = "SMBunknown";
4582   static int num_smb_messages = 
4583     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4584   int match;
4585
4586   for (match=0;match<num_smb_messages;match++)
4587     if (smb_messages[match].code == type)
4588       break;
4589
4590   if (match == num_smb_messages)
4591     return(unknown_name);
4592
4593   return(smb_messages[match].name);
4594 }
4595
4596
4597 /****************************************************************************
4598 do a switch on the message type, and return the response size
4599 ****************************************************************************/
4600 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4601 {
4602   static int pid= -1;
4603   int outsize = 0;
4604   static int num_smb_messages = 
4605     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4606   int match;
4607
4608 #if PROFILING
4609   struct timeval msg_start_time;
4610   struct timeval msg_end_time;
4611   static unsigned long total_time = 0;
4612
4613   GetTimeOfDay(&msg_start_time);
4614 #endif
4615
4616   if (pid == -1)
4617     pid = getpid();
4618
4619   errno = 0;
4620   last_message = type;
4621
4622   /* make sure this is an SMB packet */
4623   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4624   {
4625     DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4626     return(-1);
4627   }
4628
4629   for (match=0;match<num_smb_messages;match++)
4630     if (smb_messages[match].code == type)
4631       break;
4632
4633   if (match == num_smb_messages)
4634   {
4635     DEBUG(0,("Unknown message type %d!\n",type));
4636     outsize = reply_unknown(inbuf,outbuf);
4637   }
4638   else
4639   {
4640     DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4641
4642     if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4643     {
4644       /* 
4645        * Queue this message as we are the process of an oplock break.
4646        */
4647
4648       DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4649              timestring() ));
4650
4651       push_oplock_pending_smb_message( inbuf, size);
4652       return -1;
4653     }          
4654
4655     if (smb_messages[match].fn)
4656     {
4657       int cnum = SVAL(inbuf,smb_tid);
4658       int flags = smb_messages[match].flags;
4659       static uint16 last_session_tag = UID_FIELD_INVALID;
4660       /* In share mode security we must ignore the vuid. */
4661       uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4662       /* Ensure this value is replaced in the incoming packet. */
4663       SSVAL(inbuf,smb_uid,session_tag);
4664
4665       /*
4666        * Ensure the correct username is in sesssetup_user.
4667        * This is a really ugly bugfix for problems with
4668        * multiple session_setup_and_X's being done and
4669        * allowing %U and %G substitutions to work correctly.
4670        * There is a reason this code is done here, don't
4671        * move it unless you know what you're doing... :-).
4672        * JRA.
4673        */
4674       if(session_tag != last_session_tag ) {
4675         user_struct *vuser = NULL;
4676
4677         last_session_tag = session_tag;
4678         if(session_tag != UID_FIELD_INVALID)
4679           vuser = get_valid_user_struct(session_tag);           
4680         if(vuser != NULL)
4681           pstrcpy( sesssetup_user, vuser->requested_name);
4682       }
4683
4684       /* does this protocol need to be run as root? */
4685       if (!(flags & AS_USER))
4686         unbecome_user();
4687
4688       /* does this protocol need to be run as the connected user? */
4689       if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4690         if (flags & AS_GUEST) 
4691           flags &= ~AS_USER;
4692         else
4693           return(ERROR(ERRSRV,ERRinvnid));
4694       }
4695       /* this code is to work around a bug is MS client 3 without
4696          introducing a security hole - it needs to be able to do
4697          print queue checks as guest if it isn't logged in properly */
4698       if (flags & AS_USER)
4699         flags &= ~AS_GUEST;
4700
4701       /* does it need write permission? */
4702       if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4703         return(ERROR(ERRSRV,ERRaccess));
4704
4705       /* ipc services are limited */
4706       if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4707         return(ERROR(ERRSRV,ERRaccess));            
4708
4709       /* load service specific parameters */
4710       if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4711         return(ERROR(ERRSRV,ERRaccess));
4712
4713       /* does this protocol need to be run as guest? */
4714       if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4715         return(ERROR(ERRSRV,ERRaccess));
4716
4717       last_inbuf = inbuf;
4718
4719       outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4720     }
4721     else
4722     {
4723       outsize = reply_unknown(inbuf,outbuf);
4724     }
4725   }
4726
4727 #if PROFILING
4728   GetTimeOfDay(&msg_end_time);
4729   if (!(smb_messages[match].flags & TIME_INIT))
4730   {
4731     smb_messages[match].time = 0;
4732     smb_messages[match].flags |= TIME_INIT;
4733   }
4734   {
4735     unsigned long this_time =     
4736       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4737       (msg_end_time.tv_usec - msg_start_time.tv_usec);
4738     smb_messages[match].time += this_time;
4739     total_time += this_time;
4740   }
4741   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4742         smb_fn_name(type),smb_messages[match].time,
4743         (100.0*smb_messages[match].time) / total_time));
4744 #endif
4745
4746   return(outsize);
4747 }
4748
4749
4750 /****************************************************************************
4751   construct a chained reply and add it to the already made reply
4752   **************************************************************************/
4753 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4754 {
4755   static char *orig_inbuf;
4756   static char *orig_outbuf;
4757   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4758   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4759   char *inbuf2, *outbuf2;
4760   int outsize2;
4761   char inbuf_saved[smb_wct];
4762   char outbuf_saved[smb_wct];
4763   extern int chain_size;
4764   int wct = CVAL(outbuf,smb_wct);
4765   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4766
4767   /* maybe its not chained */
4768   if (smb_com2 == 0xFF) {
4769     CVAL(outbuf,smb_vwv0) = 0xFF;
4770     return outsize;
4771   }
4772
4773   if (chain_size == 0) {
4774     /* this is the first part of the chain */
4775     orig_inbuf = inbuf;
4776     orig_outbuf = outbuf;
4777   }
4778
4779   /* we need to tell the client where the next part of the reply will be */
4780   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4781   CVAL(outbuf,smb_vwv0) = smb_com2;
4782
4783   /* remember how much the caller added to the chain, only counting stuff
4784      after the parameter words */
4785   chain_size += outsize - smb_wct;
4786
4787   /* work out pointers into the original packets. The
4788      headers on these need to be filled in */
4789   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4790   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4791
4792   /* remember the original command type */
4793   smb_com1 = CVAL(orig_inbuf,smb_com);
4794
4795   /* save the data which will be overwritten by the new headers */
4796   memcpy(inbuf_saved,inbuf2,smb_wct);
4797   memcpy(outbuf_saved,outbuf2,smb_wct);
4798
4799   /* give the new packet the same header as the last part of the SMB */
4800   memmove(inbuf2,inbuf,smb_wct);
4801
4802   /* create the in buffer */
4803   CVAL(inbuf2,smb_com) = smb_com2;
4804
4805   /* create the out buffer */
4806   bzero(outbuf2,smb_size);
4807   set_message(outbuf2,0,0,True);
4808   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4809   
4810   memcpy(outbuf2+4,inbuf2+4,4);
4811   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4812   CVAL(outbuf2,smb_reh) = 0;
4813   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4814                                                                   means a reply */
4815   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4816   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4817   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4818   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4819   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4820   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4821
4822   DEBUG(3,("Chained message\n"));
4823   show_msg(inbuf2);
4824
4825   /* process the request */
4826   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4827                             bufsize-chain_size);
4828
4829   /* copy the new reply and request headers over the old ones, but
4830      preserve the smb_com field */
4831   memmove(orig_outbuf,outbuf2,smb_wct);
4832   CVAL(orig_outbuf,smb_com) = smb_com1;
4833
4834   /* restore the saved data, being careful not to overwrite any
4835    data from the reply header */
4836   memcpy(inbuf2,inbuf_saved,smb_wct);
4837   {
4838     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4839     if (ofs < 0) ofs = 0;
4840     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4841   }
4842
4843   return outsize2;
4844 }
4845
4846
4847
4848 /****************************************************************************
4849   construct a reply to the incoming packet
4850 ****************************************************************************/
4851 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4852 {
4853   int type = CVAL(inbuf,smb_com);
4854   int outsize = 0;
4855   int msg_type = CVAL(inbuf,0);
4856   extern int chain_size;
4857
4858   smb_last_time = time(NULL);
4859
4860   chain_size = 0;
4861   chain_fnum = -1;
4862   reset_chain_pnum();
4863
4864   bzero(outbuf,smb_size);
4865
4866   if (msg_type != 0)
4867     return(reply_special(inbuf,outbuf));  
4868
4869   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4870   set_message(outbuf,0,0,True);
4871   
4872   memcpy(outbuf+4,inbuf+4,4);
4873   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4874   CVAL(outbuf,smb_reh) = 0;
4875   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4876                                                              means a reply */
4877   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4878   SSVAL(outbuf,smb_err,SMB_SUCCESS);
4879   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4880   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4881   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4882   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4883
4884   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4885
4886   outsize += chain_size;
4887
4888   if(outsize > 4)
4889     smb_setlen(outbuf,outsize - 4);
4890   return(outsize);
4891 }
4892
4893 /****************************************************************************
4894   process commands from the client
4895 ****************************************************************************/
4896 static void process(void)
4897 {
4898   extern int Client;
4899
4900   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4901   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4902   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
4903     return;
4904
4905   InBuffer += SMB_ALIGNMENT;
4906   OutBuffer += SMB_ALIGNMENT;
4907
4908 #if PRIME_NMBD
4909   DEBUG(3,("priming nmbd\n"));
4910   {
4911     struct in_addr ip;
4912     ip = *interpret_addr2("localhost");
4913     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4914     *OutBuffer = 0;
4915     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4916   }
4917 #endif    
4918
4919   /* re-initialise the timezone */
4920   TimeInit();
4921
4922   while (True)
4923   {
4924     int deadtime = lp_deadtime()*60;
4925     int counter;
4926     int last_keepalive=0;
4927     int service_load_counter = 0;
4928     BOOL got_smb = False;
4929
4930     if (deadtime <= 0)
4931       deadtime = DEFAULT_SMBD_TIMEOUT;
4932
4933 #if USE_READ_PREDICTION
4934     if (lp_readprediction())
4935       do_read_prediction();
4936 #endif
4937
4938     errno = 0;      
4939
4940     for (counter=SMBD_SELECT_LOOP; 
4941           !receive_message_or_smb(Client,oplock_sock,
4942                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
4943           counter += SMBD_SELECT_LOOP)
4944     {
4945       int i;
4946       time_t t;
4947       BOOL allidle = True;
4948       extern int keepalive;
4949
4950       if (counter > 365 * 3600) /* big number of seconds. */
4951       {
4952         counter = 0;
4953         service_load_counter = 0;
4954       }
4955
4956       if (smb_read_error == READ_EOF) 
4957       {
4958         DEBUG(3,("end of file from client\n"));
4959         return;
4960       }
4961
4962       if (smb_read_error == READ_ERROR) 
4963       {
4964         DEBUG(3,("receive_smb error (%s) exiting\n",
4965                   strerror(errno)));
4966         return;
4967       }
4968
4969       t = time(NULL);
4970
4971       /* become root again if waiting */
4972       unbecome_user();
4973
4974       /* check for smb.conf reload */
4975       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4976       {
4977         service_load_counter = counter;
4978
4979         /* reload services, if files have changed. */
4980         reload_services(True);
4981       }
4982
4983       /*
4984        * If reload_after_sighup == True then we got a SIGHUP
4985        * and are being asked to reload. Fix from <branko.cibej@hermes.si>
4986        */
4987
4988       if (reload_after_sighup)
4989       {
4990         DEBUG(0,("Reloading services after SIGHUP\n"));
4991         reload_services(False);
4992         reload_after_sighup = False;
4993       }
4994
4995       /* automatic timeout if all connections are closed */      
4996       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
4997       {
4998         DEBUG(2,("%s Closing idle connection\n",timestring()));
4999         return;
5000       }
5001
5002       if (keepalive && (counter-last_keepalive)>keepalive) 
5003       {
5004               struct cli_state *cli = server_client();
5005               if (!send_keepalive(Client)) { 
5006                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
5007                       return;
5008               }     
5009               /* also send a keepalive to the password server if its still
5010                  connected */
5011               if (cli && cli->initialised)
5012                       send_keepalive(cli->fd);
5013               last_keepalive = counter;
5014       }
5015
5016       /* check for connection timeouts */
5017       for (i=0;i<MAX_CONNECTIONS;i++)
5018         if (Connections[i].open)
5019         {
5020           /* close dirptrs on connections that are idle */
5021           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
5022             dptr_idlecnum(i);
5023
5024           if (Connections[i].num_files_open > 0 ||
5025                      (t-Connections[i].lastused)<deadtime)
5026             allidle = False;
5027         }
5028
5029       if (allidle && num_connections_open>0) 
5030       {
5031         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
5032         return;
5033       }
5034
5035       if(global_machine_pasword_needs_changing)
5036       {
5037         unsigned char trust_passwd_hash[16];
5038         time_t lct;
5039         pstring remote_machine_list;
5040
5041         /*
5042          * We're in domain level security, and the code that
5043          * read the machine password flagged that the machine
5044          * password needs changing.
5045          */
5046
5047         /*
5048          * First, open the machine password file with an exclusive lock.
5049          */
5050
5051         if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5052           DEBUG(0,("process: unable to open the machine account password file for \
5053 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5054           continue;
5055         }
5056
5057         if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5058           DEBUG(0,("process: unable to read the machine account password for \
5059 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5060           trust_password_unlock();
5061           continue;
5062         }
5063
5064         /*
5065          * Make sure someone else hasn't already done this.
5066          */
5067
5068         if(t < lct + lp_machine_password_timeout()) {
5069           trust_password_unlock();
5070           global_machine_pasword_needs_changing = False;
5071           continue;
5072         }
5073
5074         pstrcpy(remote_machine_list, lp_passwordserver());
5075
5076         change_trust_account_password( global_myworkgroup, remote_machine_list);
5077         trust_password_unlock();
5078         global_machine_pasword_needs_changing = False;
5079       }
5080     }
5081
5082     if(got_smb)
5083       process_smb(InBuffer, OutBuffer);
5084     else
5085       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5086   }
5087 }
5088
5089
5090 /****************************************************************************
5091   initialise connect, service and file structs
5092 ****************************************************************************/
5093 static void init_structs(void )
5094 {
5095   int i;
5096   get_myname(myhostname,NULL);
5097
5098   /*
5099    * Set the machine NETBIOS name if not already
5100    * set from the config file.
5101    */
5102
5103   if (!*global_myname)
5104   {
5105     char *p;
5106     fstrcpy( global_myname, myhostname );
5107     p = strchr( global_myname, '.' );
5108     if (p) 
5109       *p = 0;
5110   }
5111   strupper( global_myname );
5112
5113   for (i=0;i<MAX_CONNECTIONS;i++)
5114     {
5115       Connections[i].open = False;
5116       Connections[i].num_files_open=0;
5117       Connections[i].lastused=0;
5118       Connections[i].used=False;
5119       string_init(&Connections[i].user,"");
5120       string_init(&Connections[i].dirpath,"");
5121       string_init(&Connections[i].connectpath,"");
5122       string_init(&Connections[i].origpath,"");
5123     }
5124
5125   for (i=0;i<MAX_FNUMS;i++)
5126     {
5127       Files[i].open = False;
5128       string_init(&Files[i].name,"");
5129     }
5130
5131   for (i=0;i<MAX_OPEN_FILES;i++)
5132     {
5133       file_fd_struct *fd_ptr = &FileFd[i];
5134       fd_ptr->ref_count = 0;
5135       fd_ptr->dev = (int32)-1;
5136       fd_ptr->inode = (int32)-1;
5137       fd_ptr->fd = -1;
5138       fd_ptr->fd_readonly = -1;
5139       fd_ptr->fd_writeonly = -1;
5140       fd_ptr->real_open_flags = -1;
5141     }
5142
5143   /* for RPC pipes */
5144   init_rpc_pipe_hnd();
5145
5146   /* for LSA handles */
5147   init_lsa_policy_hnd();
5148
5149   init_dptrs();
5150 }
5151
5152 /****************************************************************************
5153 usage on the program
5154 ****************************************************************************/
5155 static void usage(char *pname)
5156 {
5157   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5158
5159   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5160   printf("Version %s\n",VERSION);
5161   printf("\t-D                    become a daemon\n");
5162   printf("\t-p port               listen on the specified port\n");
5163   printf("\t-d debuglevel         set the debuglevel\n");
5164   printf("\t-l log basename.      Basename for log/debug files\n");
5165   printf("\t-s services file.     Filename of services file\n");
5166   printf("\t-P                    passive only\n");
5167   printf("\t-a                    overwrite log file, don't append\n");
5168   printf("\n");
5169 }
5170
5171
5172 /****************************************************************************
5173   main program
5174 ****************************************************************************/
5175  int main(int argc,char *argv[])
5176 {
5177   extern BOOL append_log;
5178   /* shall I run as a daemon */
5179   BOOL is_daemon = False;
5180   int port = SMB_PORT;
5181   int opt;
5182   extern char *optarg;
5183
5184 #ifdef HAVE_SET_AUTH_PARAMETERS
5185   set_auth_parameters(argc,argv);
5186 #endif
5187
5188 #ifdef HAVE_SETLUID
5189   /* needed for SecureWare on SCO */
5190   setluid(0);
5191 #endif
5192
5193   append_log = True;
5194
5195   TimeInit();
5196
5197   pstrcpy(debugf,SMBLOGFILE);  
5198
5199   pstrcpy(remote_machine, "smb");
5200
5201   setup_logging(argv[0],False);
5202
5203   charset_initialise();
5204
5205   /* make absolutely sure we run as root - to handle cases where people
5206      are crazy enough to have it setuid */
5207 #ifdef HAVE_SETRESUID
5208   setresuid(0,0,0);
5209 #else
5210   setuid(0);
5211   seteuid(0);
5212   setuid(0);
5213   seteuid(0);
5214 #endif
5215
5216   fault_setup((void (*)(void *))exit_server);
5217   CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
5218
5219   /* we want total control over the permissions on created files,
5220      so set our umask to 0 */
5221   umask(0);
5222
5223   GetWd(OriginalDir);
5224
5225   init_uid();
5226
5227   /* this is for people who can't start the program correctly */
5228   while (argc > 1 && (*argv[1] != '-'))
5229     {
5230       argv++;
5231       argc--;
5232     }
5233
5234   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5235     switch (opt)
5236       {
5237       case 'O':
5238         pstrcpy(user_socket_options,optarg);
5239         break;
5240       case 'i':
5241         pstrcpy(scope,optarg);
5242         break;
5243       case 'P':
5244         {
5245           extern BOOL passive;
5246           passive = True;
5247         }
5248         break;  
5249       case 's':
5250         pstrcpy(servicesf,optarg);
5251         break;
5252       case 'l':
5253         pstrcpy(debugf,optarg);
5254         break;
5255       case 'a':
5256         {
5257           extern BOOL append_log;
5258           append_log = !append_log;
5259         }
5260         break;
5261       case 'D':
5262         is_daemon = True;
5263         break;
5264       case 'd':
5265         if (*optarg == 'A')
5266           DEBUGLEVEL = 10000;
5267         else
5268           DEBUGLEVEL = atoi(optarg);
5269         break;
5270       case 'p':
5271         port = atoi(optarg);
5272         break;
5273       case 'h':
5274         usage(argv[0]);
5275         exit(0);
5276         break;
5277       default:
5278         usage(argv[0]);
5279         exit(1);
5280       }
5281
5282   reopen_logs();
5283
5284   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5285   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5286
5287 #ifdef HAVE_GETRLIMIT
5288 #ifdef RLIMIT_NOFILE
5289   {
5290     struct rlimit rlp;
5291     getrlimit(RLIMIT_NOFILE, &rlp);
5292     /*
5293      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5294      * extra fd we need to read directories, as well as the log files
5295      * and standard handles etc.
5296      */
5297     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5298     setrlimit(RLIMIT_NOFILE, &rlp);
5299     getrlimit(RLIMIT_NOFILE, &rlp);
5300     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5301   }
5302 #endif
5303 #endif
5304
5305   
5306   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5307         getuid(),getgid(),geteuid(),getegid()));
5308
5309   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5310     {
5311       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5312       exit(1);
5313     }
5314
5315   init_structs();
5316
5317   if (!reload_services(False))
5318     return(-1); 
5319
5320 #ifdef WITH_SSL
5321   {
5322     extern BOOL sslEnabled;
5323     sslEnabled = lp_ssl_enabled();
5324     if(sslEnabled)
5325       sslutil_init(True);
5326   }
5327 #endif        /* WITH_SSL */
5328
5329   codepage_initialise(lp_client_code_page());
5330
5331   pstrcpy(global_myworkgroup, lp_workgroup());
5332
5333   if(!pdb_generate_machine_sid()) {
5334           DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5335           exit(1);
5336   }
5337
5338   CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
5339
5340   /* Setup the signals that allow the debug log level
5341      to by dynamically changed. */
5342  
5343   /* If we are using the malloc debug code we can't use
5344      SIGUSR1 and SIGUSR2 to do debug level changes. */
5345
5346 #ifndef MEM_MAN
5347 #if defined(SIGUSR1)
5348   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5349 #endif /* SIGUSR1 */
5350    
5351 #if defined(SIGUSR2)
5352   CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5353 #endif /* SIGUSR2 */
5354 #endif /* MEM_MAN */
5355
5356   DEBUG(3,("%s loaded services\n",timestring()));
5357
5358   if (!is_daemon && !is_a_socket(0))
5359     {
5360       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5361       is_daemon = True;
5362     }
5363
5364   if (is_daemon)
5365     {
5366       DEBUG(3,("%s becoming a daemon\n",timestring()));
5367       become_daemon();
5368     }
5369
5370   if (!directory_exist(lp_lockdir(), NULL)) {
5371           mkdir(lp_lockdir(), 0755);
5372   }
5373
5374   if (is_daemon) {
5375           pidfile_create("smbd");
5376   }
5377
5378   if (!open_sockets(is_daemon,port))
5379     exit(1);
5380
5381   if (!locking_init(0))
5382     exit(1);
5383
5384   if(!initialize_password_db())
5385     exit(1);
5386
5387   /* possibly reload the services file. */
5388   reload_services(True);
5389
5390   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5391
5392   if (*lp_rootdir())
5393     {
5394       if (sys_chroot(lp_rootdir()) == 0)
5395         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5396     }
5397
5398   /* Setup the oplock IPC socket. */
5399   if(!open_oplock_ipc())
5400     exit(1);
5401
5402   process();
5403   close_sockets();
5404
5405   exit_server("normal exit");
5406   return(0);
5407 }