merge from the autoconf2 branch to the main branch
[ira/wip.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.igroups))))
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.igroups)))) {
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->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->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->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->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].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 *fs_p)
1385 {   
1386   int cnum = fs_p->cnum;
1387     
1388   fs_p->reserved = False; 
1389   fs_p->open = False;
1390   fs_p->is_directory = False; 
1391     
1392   Connections[cnum].num_files_open--;
1393   if(fs_p->wbmpx_ptr)
1394   {  
1395     free((char *)fs_p->wbmpx_ptr);
1396     fs_p->wbmpx_ptr = NULL; 
1397   }  
1398      
1399 #if WITH_MMAP
1400   if(fs_p->mmap_ptr) 
1401   {
1402     munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1403     fs_p->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->fd_ptr->dev;
1422   uint32 inode = fs_p->fd_ptr->inode;
1423   int token;
1424
1425   close_filestruct(fs_p);
1426
1427 #if USE_READ_PREDICTION
1428   invalidate_read_prediction(fs_p->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->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 *fs_p = &Files[fnum];
1474
1475   /*
1476    * Do the code common to files and directories.
1477    */
1478   close_filestruct(fs_p);
1479
1480   if (fs_p->name) {
1481       string_free(&fs_p->name);
1482   }
1483
1484   /* we will catch bugs faster by zeroing this structure */
1485   memset(fs_p, 0, sizeof(*fs_p));
1486 }
1487
1488 /****************************************************************************
1489  Open a directory from an NT SMB call.
1490 ****************************************************************************/
1491
1492 void open_directory(int fnum,int cnum,char *fname, int *action)
1493 {
1494   extern struct current_user current_user;
1495   files_struct *fsp = &Files[fnum];
1496
1497   fsp->fd_ptr = NULL;
1498   Connections[cnum].num_files_open++;
1499   fsp->mode = 0;
1500   GetTimeOfDay(&fsp->open_time);
1501   fsp->vuid = current_user.vuid;
1502   fsp->size = 0;
1503   fsp->pos = -1;
1504   fsp->open = True;
1505   fsp->mmap_ptr = NULL;
1506   fsp->mmap_size = 0;
1507   fsp->can_lock = True;
1508   fsp->can_read = False;
1509   fsp->can_write = False;
1510   fsp->share_mode = 0;
1511   fsp->print_file = False;
1512   fsp->modified = False;
1513   fsp->granted_oplock = False;
1514   fsp->sent_oplock_break = False;
1515   fsp->is_directory = True;
1516   fsp->cnum = cnum;
1517   /*
1518    * Note that the file name here is the *untranslated* name
1519    * ie. it is still in the DOS codepage sent from the client.
1520    * All use of this filename will pass though the sys_xxxx
1521    * functions which will do the dos_to_unix translation before
1522    * mapping into a UNIX filename. JRA.
1523    */
1524   string_set(&fsp->name,fname);
1525   fsp->wbmpx_ptr = NULL;
1526
1527   *action = FILE_WAS_OPENED;
1528 }
1529
1530 enum {AFAIL,AREAD,AWRITE,AALL};
1531
1532 /*******************************************************************
1533 reproduce the share mode access table
1534 ********************************************************************/
1535 static int access_table(int new_deny,int old_deny,int old_mode,
1536                         int share_pid,char *fname)
1537 {
1538   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1539
1540   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1541     int pid = getpid();
1542     if (old_deny == new_deny && share_pid == pid) 
1543         return(AALL);    
1544
1545     if (old_mode == 0) return(AREAD);
1546
1547     /* the new smbpub.zip spec says that if the file extension is
1548        .com, .dll, .exe or .sym then allow the open. I will force
1549        it to read-only as this seems sensible although the spec is
1550        a little unclear on this. */
1551     if ((fname = strrchr(fname,'.'))) {
1552       if (strequal(fname,".com") ||
1553           strequal(fname,".dll") ||
1554           strequal(fname,".exe") ||
1555           strequal(fname,".sym"))
1556         return(AREAD);
1557     }
1558
1559     return(AFAIL);
1560   }
1561
1562   switch (new_deny) 
1563     {
1564     case DENY_WRITE:
1565       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1566       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1567       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1568       return(AFAIL);
1569     case DENY_READ:
1570       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1571       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1572       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1573       return(AFAIL);
1574     case DENY_NONE:
1575       if (old_deny==DENY_WRITE) return(AREAD);
1576       if (old_deny==DENY_READ) return(AWRITE);
1577       if (old_deny==DENY_NONE) return(AALL);
1578       return(AFAIL);      
1579     }
1580   return(AFAIL);      
1581 }
1582
1583 /*******************************************************************
1584 check if the share mode on a file allows it to be deleted or unlinked
1585 return True if sharing doesn't prevent the operation
1586 ********************************************************************/
1587 BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
1588 {
1589   int i;
1590   int ret = False;
1591   share_mode_entry *old_shares = 0;
1592   int num_share_modes;
1593   struct stat sbuf;
1594   int token;
1595   int pid = getpid();
1596   uint32 dev, inode;
1597
1598   if(!lp_share_modes(SNUM(cnum)))
1599     return True;
1600
1601   if (sys_stat(fname,&sbuf) == -1) return(True);
1602
1603   dev = (uint32)sbuf.st_dev;
1604   inode = (uint32)sbuf.st_ino;
1605
1606   lock_share_entry(cnum, dev, inode, &token);
1607   num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1608
1609   /*
1610    * Check if the share modes will give us access.
1611    */
1612
1613   if(num_share_modes != 0)
1614   {
1615     BOOL broke_oplock;
1616
1617     do
1618     {
1619
1620       broke_oplock = False;
1621       for(i = 0; i < num_share_modes; i++)
1622       {
1623         share_mode_entry *share_entry = &old_shares[i];
1624
1625         /* 
1626          * Break oplocks before checking share modes. See comment in
1627          * open_file_shared for details. 
1628          * Check if someone has an oplock on this file. If so we must 
1629          * break it before continuing. 
1630          */
1631         if(share_entry->op_type & BATCH_OPLOCK)
1632         {
1633
1634           /*
1635            * It appears that the NT redirector may have a bug, in that
1636            * it tries to do an SMBmv on a file that it has open with a
1637            * batch oplock, and then fails to respond to the oplock break
1638            * request. This only seems to occur when the client is doing an
1639            * SMBmv to the smbd it is using - thus we try and detect this
1640            * condition by checking if the file being moved is open and oplocked by
1641            * this smbd process, and then not sending the oplock break in this
1642            * special case. If the file was open with a deny mode that 
1643            * prevents the move the SMBmv will fail anyway with a share
1644            * violation error. JRA.
1645            */
1646           if(rename_op && (share_entry->pid == pid))
1647           {
1648             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1649 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1650             /* 
1651              * This next line is a test that allows the deny-mode
1652              * processing to be skipped. This seems to be needed as
1653              * NT insists on the rename succeeding (in Office 9x no less !).
1654              * This should be removed as soon as (a) MS fix the redirector
1655              * bug or (b) NT SMB support in Samba makes NT not issue the
1656              * call (as is my fervent hope). JRA.
1657              */ 
1658             continue;
1659           }
1660           else
1661           {
1662             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1663 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1664
1665             /* Oplock break.... */
1666             unlock_share_entry(cnum, dev, inode, token);
1667             if(request_oplock_break(share_entry, dev, inode) == False)
1668             {
1669               free((char *)old_shares);
1670               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1671 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1672               return False;
1673             }
1674             lock_share_entry(cnum, dev, inode, &token);
1675             broke_oplock = True;
1676             break;
1677           }
1678         }
1679
1680         /* someone else has a share lock on it, check to see 
1681            if we can too */
1682         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1683           goto free_and_exit;
1684
1685       } /* end for */
1686
1687       if(broke_oplock)
1688       {
1689         free((char *)old_shares);
1690         num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1691       }
1692     } while(broke_oplock);
1693   }
1694
1695   /* XXXX exactly what share mode combinations should be allowed for
1696      deleting/renaming? */
1697   /* If we got here then either there were no share modes or
1698      all share modes were DENY_DOS and the pid == getpid() */
1699   ret = True;
1700
1701 free_and_exit:
1702
1703   unlock_share_entry(cnum, dev, inode, token);
1704   if(old_shares != NULL)
1705     free((char *)old_shares);
1706   return(ret);
1707 }
1708
1709 /****************************************************************************
1710   C. Hoch 11/22/95
1711   Helper for open_file_shared. 
1712   Truncate a file after checking locking; close file if locked.
1713   **************************************************************************/
1714 static void truncate_unless_locked(int fnum, int cnum, int token, 
1715                                    BOOL *share_locked)
1716 {
1717   if (Files[fnum].can_write){
1718     if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){
1719       /* If share modes are in force for this connection we
1720          have the share entry locked. Unlock it before closing. */
1721       if (*share_locked && lp_share_modes(SNUM(cnum)))
1722         unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, 
1723                             Files[fnum].fd_ptr->inode, token);
1724       close_file(fnum,False);   
1725       /* Share mode no longer locked. */
1726       *share_locked = False;
1727       errno = EACCES;
1728       unix_ERR_class = ERRDOS;
1729       unix_ERR_code = ERRlock;
1730     }
1731     else
1732       ftruncate(Files[fnum].fd_ptr->fd,0); 
1733   }
1734 }
1735
1736 /****************************************************************************
1737 check if we can open a file with a share mode
1738 ****************************************************************************/
1739 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1740                       BOOL fcbopen, int *flags)
1741 {
1742   int old_open_mode = share->share_mode &0xF;
1743   int old_deny_mode = (share->share_mode >>4)&7;
1744
1745   if (old_deny_mode > 4 || old_open_mode > 2)
1746   {
1747     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1748                deny_mode,old_deny_mode,old_open_mode,fname));
1749     return False;
1750   }
1751
1752   {
1753     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1754                                 share->pid,fname);
1755
1756     if ((access_allowed == AFAIL) ||
1757         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1758         (access_allowed == AREAD && *flags == O_WRONLY) ||
1759         (access_allowed == AWRITE && *flags == O_RDONLY))
1760     {
1761       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1762                 deny_mode,old_deny_mode,old_open_mode,
1763                 share->pid,fname, fcbopen, *flags, access_allowed));
1764       return False;
1765     }
1766
1767     if (access_allowed == AREAD)
1768       *flags = O_RDONLY;
1769
1770     if (access_allowed == AWRITE)
1771       *flags = O_WRONLY;
1772
1773   }
1774   return True;
1775 }
1776
1777 /****************************************************************************
1778 open a file with a share mode
1779 ****************************************************************************/
1780 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1781                       int mode,int oplock_request, int *Access,int *action)
1782 {
1783   files_struct *fs_p = &Files[fnum];
1784   int flags=0;
1785   int flags2=0;
1786   int deny_mode = (share_mode>>4)&7;
1787   struct stat sbuf;
1788   BOOL file_existed = file_exist(fname,&sbuf);
1789   BOOL share_locked = False;
1790   BOOL fcbopen = False;
1791   int token;
1792   uint32 dev = 0;
1793   uint32 inode = 0;
1794   int num_share_modes = 0;
1795
1796   fs_p->open = False;
1797   fs_p->fd_ptr = 0;
1798
1799   /* this is for OS/2 EAs - try and say we don't support them */
1800   if (strstr(fname,".+,;=[].")) 
1801   {
1802     unix_ERR_class = ERRDOS;
1803     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
1804 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
1805     unix_ERR_code = ERRcannotopen;
1806 #else /* OS2_WPS_FIX */
1807     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1808 #endif /* OS2_WPS_FIX */
1809
1810     return;
1811   }
1812
1813   if ((ofun & 0x3) == 0 && file_existed)  
1814   {
1815     errno = EEXIST;
1816     return;
1817   }
1818       
1819   if (ofun & 0x10)
1820     flags2 |= O_CREAT;
1821   if ((ofun & 0x3) == 2)
1822     flags2 |= O_TRUNC;
1823
1824   /* note that we ignore the append flag as 
1825      append does not mean the same thing under dos and unix */
1826
1827   switch (share_mode&0xF)
1828   {
1829     case 1: 
1830       flags = O_WRONLY; 
1831       break;
1832     case 0xF: 
1833       fcbopen = True;
1834       flags = O_RDWR; 
1835       break;
1836     case 2: 
1837       flags = O_RDWR; 
1838       break;
1839     default:
1840       flags = O_RDONLY;
1841       break;
1842   }
1843
1844 #if defined(O_SYNC)
1845   if (share_mode&(1<<14)) {
1846           flags2 |= O_SYNC;
1847   }
1848 #endif /* O_SYNC */
1849   
1850   if (flags != O_RDONLY && file_existed && 
1851       (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) 
1852   {
1853     if (!fcbopen) 
1854     {
1855       errno = EACCES;
1856       return;
1857     }
1858     flags = O_RDONLY;
1859   }
1860
1861   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
1862   {
1863     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1864     errno = EINVAL;
1865     return;
1866   }
1867
1868   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1869
1870   if (lp_share_modes(SNUM(cnum))) 
1871   {
1872     int i;
1873     share_mode_entry *old_shares = 0;
1874
1875     if (file_existed)
1876     {
1877       dev = (uint32)sbuf.st_dev;
1878       inode = (uint32)sbuf.st_ino;
1879       lock_share_entry(cnum, dev, inode, &token);
1880       share_locked = True;
1881       num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1882     }
1883
1884     /*
1885      * Check if the share modes will give us access.
1886      */
1887
1888     if(share_locked && (num_share_modes != 0))
1889     {
1890       BOOL broke_oplock;
1891
1892       do
1893       {
1894
1895         broke_oplock = False;
1896         for(i = 0; i < num_share_modes; i++)
1897         {
1898           share_mode_entry *share_entry = &old_shares[i];
1899
1900           /* 
1901            * By observation of NetBench, oplocks are broken *before* share
1902            * modes are checked. This allows a file to be closed by the client
1903            * if the share mode would deny access and the client has an oplock. 
1904            * Check if someone has an oplock on this file. If so we must break 
1905            * it before continuing. 
1906            */
1907           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1908           {
1909
1910             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1911 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1912
1913             /* Oplock break.... */
1914             unlock_share_entry(cnum, dev, inode, token);
1915             if(request_oplock_break(share_entry, dev, inode) == False)
1916             {
1917               free((char *)old_shares);
1918               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1919 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1920               errno = EACCES;
1921               unix_ERR_class = ERRDOS;
1922               unix_ERR_code = ERRbadshare;
1923               return;
1924             }
1925             lock_share_entry(cnum, dev, inode, &token);
1926             broke_oplock = True;
1927             break;
1928           }
1929
1930           /* someone else has a share lock on it, check to see 
1931              if we can too */
1932           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1933           {
1934             free((char *)old_shares);
1935             unlock_share_entry(cnum, dev, inode, token);
1936             errno = EACCES;
1937             unix_ERR_class = ERRDOS;
1938             unix_ERR_code = ERRbadshare;
1939             return;
1940           }
1941
1942         } /* end for */
1943
1944         if(broke_oplock)
1945         {
1946           free((char *)old_shares);
1947           num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1948         }
1949       } while(broke_oplock);
1950     }
1951
1952     if(old_shares != 0)
1953       free((char *)old_shares);
1954   }
1955
1956   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1957            flags,flags2,mode));
1958
1959   open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1960   if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
1961   {
1962     flags = O_RDONLY;
1963     open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1964   }
1965
1966   if (fs_p->open) 
1967   {
1968     int open_mode=0;
1969
1970     if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1971     {
1972       /* We created the file - thus we must now lock the share entry before creating it. */
1973       dev = fs_p->fd_ptr->dev;
1974       inode = fs_p->fd_ptr->inode;
1975       lock_share_entry(cnum, dev, inode, &token);
1976       share_locked = True;
1977     }
1978
1979     switch (flags) 
1980     {
1981       case O_RDONLY:
1982         open_mode = 0;
1983         break;
1984       case O_RDWR:
1985         open_mode = 2;
1986         break;
1987       case O_WRONLY:
1988         open_mode = 1;
1989         break;
1990     }
1991
1992     fs_p->share_mode = (deny_mode<<4) | open_mode;
1993
1994     if (Access)
1995       (*Access) = open_mode;
1996
1997     if (action) 
1998     {
1999       if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
2000       if (!file_existed) *action = FILE_WAS_CREATED;
2001       if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
2002     }
2003     /* We must create the share mode entry before truncate as
2004        truncate can fail due to locking and have to close the
2005        file (which expects the share_mode_entry to be there).
2006      */
2007     if (lp_share_modes(SNUM(cnum)))
2008     {
2009       uint16 port = 0;
2010       /* JRA. Currently this only services Exlcusive and batch
2011          oplocks (no other opens on this file). This needs to
2012          be extended to level II oplocks (multiple reader
2013          oplocks). */
2014
2015       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)) && 
2016               !IS_VETO_OPLOCK_PATH(cnum,fname))
2017       {
2018         fs_p->granted_oplock = True;
2019         fs_p->sent_oplock_break = False;
2020         global_oplocks_open++;
2021         port = oplock_port;
2022
2023         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
2024 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
2025
2026       }
2027       else
2028       {
2029         port = 0;
2030         oplock_request = 0;
2031       }
2032       set_share_mode(token, fnum, port, oplock_request);
2033     }
2034
2035     if ((flags2&O_TRUNC) && file_existed)
2036       truncate_unless_locked(fnum,cnum,token,&share_locked);
2037   }
2038
2039   if (share_locked && lp_share_modes(SNUM(cnum)))
2040     unlock_share_entry( cnum, dev, inode, token);
2041 }
2042
2043 /****************************************************************************
2044 seek a file. Try to avoid the seek if possible
2045 ****************************************************************************/
2046 int seek_file(int fnum,uint32 pos)
2047 {
2048   uint32 offset = 0;
2049   if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
2050     offset = 3;
2051
2052   Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET) 
2053                                   - offset);
2054   return(Files[fnum].pos);
2055 }
2056
2057 /****************************************************************************
2058 read from a file
2059 ****************************************************************************/
2060 int read_file(int fnum,char *data,uint32 pos,int n)
2061 {
2062   int ret=0,readret;
2063
2064 #if USE_READ_PREDICTION
2065   if (!Files[fnum].can_write)
2066     {
2067       ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
2068
2069       data += ret;
2070       n -= ret;
2071       pos += ret;
2072     }
2073 #endif
2074
2075 #if WITH_MMAP
2076   if (Files[fnum].mmap_ptr)
2077     {
2078       int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
2079       num = MIN(n,num);
2080       if (num > 0)
2081         {
2082           memcpy(data,Files[fnum].mmap_ptr+pos,num);
2083           data += num;
2084           pos += num;
2085           n -= num;
2086           ret += num;
2087         }
2088     }
2089 #endif
2090
2091   if (n <= 0)
2092     return(ret);
2093
2094   if (seek_file(fnum,pos) != pos)
2095     {
2096       DEBUG(3,("Failed to seek to %d\n",pos));
2097       return(ret);
2098     }
2099   
2100   if (n > 0) {
2101     readret = read(Files[fnum].fd_ptr->fd,data,n);
2102     if (readret > 0) ret += readret;
2103   }
2104
2105   return(ret);
2106 }
2107
2108
2109 /****************************************************************************
2110 write to a file
2111 ****************************************************************************/
2112 int write_file(int fnum,char *data,int n)
2113 {
2114   if (!Files[fnum].can_write) {
2115     errno = EPERM;
2116     return(0);
2117   }
2118
2119   if (!Files[fnum].modified) {
2120     struct stat st;
2121     Files[fnum].modified = True;
2122     if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2123       int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2124       if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {  
2125         dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2126       }
2127     }  
2128   }
2129
2130   return(write_data(Files[fnum].fd_ptr->fd,data,n));
2131 }
2132
2133
2134 /****************************************************************************
2135 load parameters specific to a connection/service
2136 ****************************************************************************/
2137 BOOL become_service(int cnum,BOOL do_chdir)
2138 {
2139   extern char magic_char;
2140   static int last_cnum = -1;
2141   int snum;
2142
2143   if (!OPEN_CNUM(cnum))
2144     {
2145       last_cnum = -1;
2146       return(False);
2147     }
2148
2149   Connections[cnum].lastused = smb_last_time;
2150
2151   snum = SNUM(cnum);
2152   
2153   if (do_chdir &&
2154       ChDir(Connections[cnum].connectpath) != 0 &&
2155       ChDir(Connections[cnum].origpath) != 0)
2156     {
2157       DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2158             Connections[cnum].connectpath,cnum));     
2159       return(False);
2160     }
2161
2162   if (cnum == last_cnum)
2163     return(True);
2164
2165   last_cnum = cnum;
2166
2167   case_default = lp_defaultcase(snum);
2168   case_preserve = lp_preservecase(snum);
2169   short_case_preserve = lp_shortpreservecase(snum);
2170   case_mangle = lp_casemangle(snum);
2171   case_sensitive = lp_casesensitive(snum);
2172   magic_char = lp_magicchar(snum);
2173   use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2174   return(True);
2175 }
2176
2177
2178 /****************************************************************************
2179   find a service entry
2180 ****************************************************************************/
2181 int find_service(char *service)
2182 {
2183    int iService;
2184
2185    string_sub(service,"\\","/");
2186
2187    iService = lp_servicenumber(service);
2188
2189    /* now handle the special case of a home directory */
2190    if (iService < 0)
2191    {
2192       char *phome_dir = get_home_dir(service);
2193
2194       if(!phome_dir)
2195       {
2196         /*
2197          * Try mapping the servicename, it may
2198          * be a Windows to unix mapped user name.
2199          */
2200         if(map_username(service))
2201           phome_dir = get_home_dir(service);
2202       }
2203
2204       DEBUG(3,("checking for home directory %s gave %s\n",service,
2205             phome_dir?phome_dir:"(NULL)"));
2206
2207       if (phome_dir)
2208       {   
2209         int iHomeService;
2210         if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2211         {
2212           lp_add_home(service,iHomeService,phome_dir);
2213           iService = lp_servicenumber(service);
2214         }
2215       }
2216    }
2217
2218    /* If we still don't have a service, attempt to add it as a printer. */
2219    if (iService < 0)
2220    {
2221       int iPrinterService;
2222
2223       if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2224       {
2225          char *pszTemp;
2226
2227          DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2228          pszTemp = PRINTCAP;
2229          if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2230          {
2231             DEBUG(3,("%s is a valid printer name\n", service));
2232             DEBUG(3,("adding %s as a printer service\n", service));
2233             lp_add_printer(service,iPrinterService);
2234             iService = lp_servicenumber(service);
2235             if (iService < 0)
2236                DEBUG(0,("failed to add %s as a printer service!\n", service));
2237          }
2238          else
2239             DEBUG(3,("%s is not a valid printer name\n", service));
2240       }
2241    }
2242
2243    /* just possibly it's a default service? */
2244    if (iService < 0) 
2245    {
2246      char *pdefservice = lp_defaultservice();
2247      if (pdefservice && *pdefservice && !strequal(pdefservice,service))
2248      {
2249        /*
2250         * We need to do a local copy here as lp_defaultservice() 
2251         * returns one of the rotating lp_string buffers that
2252         * could get overwritten by the recursive find_service() call
2253         * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
2254         */
2255        pstring defservice;
2256        pstrcpy(defservice, pdefservice);
2257        iService = find_service(defservice);
2258        if (iService >= 0)
2259        {
2260          string_sub(service,"_","/");
2261          iService = lp_add_service(service,iService);
2262        }
2263      }
2264    }
2265
2266    if (iService >= 0)
2267      if (!VALID_SNUM(iService))
2268      {
2269        DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2270        iService = -1;
2271      }
2272
2273    if (iService < 0)
2274      DEBUG(3,("find_service() failed to find service %s\n", service));
2275
2276    return (iService);
2277 }
2278
2279
2280 /****************************************************************************
2281   create an error packet from a cached error.
2282 ****************************************************************************/
2283 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2284 {
2285   write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2286
2287   int32 eclass = wbmpx->wr_errclass;
2288   int32 err = wbmpx->wr_error;
2289
2290   /* We can now delete the auxiliary struct */
2291   free((char *)wbmpx);
2292   Files[fnum].wbmpx_ptr = NULL;
2293   return error_packet(inbuf,outbuf,eclass,err,line);
2294 }
2295
2296
2297 struct
2298 {
2299   int unixerror;
2300   int smbclass;
2301   int smbcode;
2302 } unix_smb_errmap[] =
2303 {
2304   {EPERM,ERRDOS,ERRnoaccess},
2305   {EACCES,ERRDOS,ERRnoaccess},
2306   {ENOENT,ERRDOS,ERRbadfile},
2307   {ENOTDIR,ERRDOS,ERRbadpath},
2308   {EIO,ERRHRD,ERRgeneral},
2309   {EBADF,ERRSRV,ERRsrverror},
2310   {EINVAL,ERRSRV,ERRsrverror},
2311   {EEXIST,ERRDOS,ERRfilexists},
2312   {ENFILE,ERRDOS,ERRnofids},
2313   {EMFILE,ERRDOS,ERRnofids},
2314   {ENOSPC,ERRHRD,ERRdiskfull},
2315 #ifdef EDQUOT
2316   {EDQUOT,ERRHRD,ERRdiskfull},
2317 #endif
2318 #ifdef ENOTEMPTY
2319   {ENOTEMPTY,ERRDOS,ERRnoaccess},
2320 #endif
2321 #ifdef EXDEV
2322   {EXDEV,ERRDOS,ERRdiffdevice},
2323 #endif
2324   {EROFS,ERRHRD,ERRnowrite},
2325   {0,0,0}
2326 };
2327
2328 /****************************************************************************
2329   create an error packet from errno
2330 ****************************************************************************/
2331 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2332 {
2333   int eclass=def_class;
2334   int ecode=def_code;
2335   int i=0;
2336
2337   if (unix_ERR_class != SMB_SUCCESS)
2338     {
2339       eclass = unix_ERR_class;
2340       ecode = unix_ERR_code;
2341       unix_ERR_class = SMB_SUCCESS;
2342       unix_ERR_code = 0;
2343     }
2344   else
2345     {
2346       while (unix_smb_errmap[i].smbclass != 0)
2347       {
2348             if (unix_smb_errmap[i].unixerror == errno)
2349             {
2350               eclass = unix_smb_errmap[i].smbclass;
2351               ecode = unix_smb_errmap[i].smbcode;
2352               break;
2353             }
2354           i++;
2355       }
2356     }
2357
2358   return(error_packet(inbuf,outbuf,eclass,ecode,line));
2359 }
2360
2361
2362 /****************************************************************************
2363   create an error packet. Normally called using the ERROR() macro
2364 ****************************************************************************/
2365 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2366 {
2367   int outsize = set_message(outbuf,0,0,True);
2368   int cmd = CVAL(inbuf,smb_com);
2369   int flgs2 = SVAL(outbuf,smb_flg2); 
2370
2371   if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
2372   {
2373     SIVAL(outbuf,smb_rcls,error_code);
2374     
2375     DEBUG(3,("%s 32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
2376            timestring(), line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf)));
2377   }
2378   else
2379   {
2380     CVAL(outbuf,smb_rcls) = error_class;
2381     SSVAL(outbuf,smb_err,error_code);  
2382     DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2383            timestring(),
2384            line,
2385            (int)CVAL(inbuf,smb_com),
2386            smb_fn_name(CVAL(inbuf,smb_com)),
2387            error_class,
2388            error_code));
2389
2390   }
2391   
2392   if (errno != 0)
2393     DEBUG(3,("error string = %s\n",strerror(errno)));
2394   
2395   return(outsize);
2396 }
2397
2398
2399 /****************************************************************************
2400   this is called when the client exits abruptly
2401   **************************************************************************/
2402 static int sig_pipe(void)
2403 {
2404         struct cli_state *cli;
2405         BlockSignals(True,SIGPIPE);
2406
2407         if ((cli = server_client()) && cli->initialised) {
2408                 DEBUG(3,("lost connection to password server\n"));
2409                 cli_shutdown(cli);
2410                 BlockSignals(False,SIGPIPE);
2411                 return 0;
2412         }
2413
2414         exit_server("Got sigpipe\n");
2415         return(0);
2416 }
2417
2418 /****************************************************************************
2419   open the socket communication
2420 ****************************************************************************/
2421 static BOOL open_sockets(BOOL is_daemon,int port)
2422 {
2423   extern int Client;
2424
2425   if (is_daemon)
2426   {
2427     int num_interfaces = iface_count();
2428     int fd_listenset[FD_SETSIZE];
2429     fd_set listen_set;
2430     int s;
2431     int i;
2432
2433 #ifdef HAVE_ATEXIT
2434     static int atexit_set;
2435     if(atexit_set == 0) {
2436             atexit_set=1;
2437             atexit(killkids);
2438     }
2439 #endif
2440
2441     /* Stop zombies */
2442     CatchChild();
2443
2444
2445     FD_ZERO(&listen_set);
2446
2447     if(lp_interfaces() && lp_bind_interfaces_only())
2448     {
2449        /* We have been given an interfaces line, and been 
2450           told to only bind to those interfaces. Create a
2451           socket per interface and bind to only these.
2452         */
2453
2454       if(num_interfaces > FD_SETSIZE)
2455       {
2456         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2457 max can be %d\n", num_interfaces, FD_SETSIZE));
2458         return False;
2459       }
2460
2461       /* Now open a listen socket for each of the interfaces. */
2462       for(i = 0; i < num_interfaces; i++)
2463       {
2464         struct in_addr *ifip = iface_n_ip(i);
2465
2466         if(ifip == NULL)
2467         {
2468           DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2469           continue;
2470         }
2471         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2472         if(s == -1)
2473           return False;
2474         /* ready to listen */
2475         if (listen(s, 5) == -1) 
2476         {
2477           DEBUG(0,("listen: %s\n",strerror(errno)));
2478           close(s);
2479           return False;
2480         }
2481         FD_SET(s,&listen_set);
2482       }
2483     }
2484     else
2485     {
2486       /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2487       num_interfaces = 1;
2488
2489       /* open an incoming socket */
2490       s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2491       if (s == -1)
2492         return(False);
2493
2494       /* ready to listen */
2495       if (listen(s, 5) == -1) 
2496       {
2497         DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2498         close(s);
2499         return False;
2500       }
2501
2502       fd_listenset[0] = s;
2503       FD_SET(s,&listen_set);
2504     }      
2505
2506     /* now accept incoming connections - forking a new process
2507        for each incoming connection */
2508     DEBUG(2,("waiting for a connection\n"));
2509     while (1)
2510     {
2511       fd_set lfds;
2512       int num;
2513
2514       memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2515
2516       num = sys_select(&lfds,NULL);
2517
2518       if (num == -1 && errno == EINTR)
2519         continue;
2520
2521       /* Find the sockets that are read-ready - accept on these. */
2522       for( ; num > 0; num--)
2523       {
2524         struct sockaddr addr;
2525         int in_addrlen = sizeof(addr);
2526
2527         s = -1;
2528         for(i = 0; i < num_interfaces; i++)
2529         {
2530           if(FD_ISSET(fd_listenset[i],&lfds))
2531           {
2532             s = fd_listenset[i];
2533             /* Clear this so we don't look at it again. */
2534             FD_CLR(fd_listenset[i],&lfds);
2535             break;
2536           }
2537         }
2538
2539         Client = accept(s,&addr,&in_addrlen);
2540
2541         if (Client == -1 && errno == EINTR)
2542           continue;
2543
2544         if (Client == -1)
2545         {
2546           DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2547           continue;
2548         }
2549
2550         if (Client != -1 && fork()==0)
2551         {
2552           /* Child code ... */
2553
2554           CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2555
2556           /* close the listening socket(s) */
2557           for(i = 0; i < num_interfaces; i++)
2558             close(fd_listenset[i]);
2559
2560           /* close our standard file descriptors */
2561           close_low_fds();
2562           am_parent = 0;
2563   
2564           set_socket_options(Client,"SO_KEEPALIVE");
2565           set_socket_options(Client,user_socket_options);
2566
2567           /* Reset global variables in util.c so that
2568              client substitutions will be done correctly
2569              in the process.
2570            */
2571           reset_globals_after_fork();
2572           return True; 
2573         }
2574         close(Client); /* The parent doesn't need this socket */
2575
2576         /*
2577          * Force parent to check log size after spawning child.
2578          * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
2579          * The parent smbd will log to logserver.smb. 
2580          * It writes only two messages for each child
2581          * started/finished. But each child writes, say, 50 messages also in
2582          * logserver.smb, begining with the debug_count of the parent, before the
2583          * child opens its own log file logserver.client. In a worst case
2584          * scenario the size of logserver.smb would be checked after about
2585          * 50*50=2500 messages (ca. 100kb).
2586          */
2587         force_check_log_size();
2588  
2589       } /* end for num */
2590     } /* end while 1 */
2591   } /* end if is_daemon */
2592   else
2593   {
2594     /* Started from inetd. fd 0 is the socket. */
2595     /* We will abort gracefully when the client or remote system 
2596        goes away */
2597     CatchSignal(SIGPIPE, SIGNAL_CAST sig_pipe);
2598     Client = dup(0);
2599
2600     /* close our standard file descriptors */
2601     close_low_fds();
2602
2603     set_socket_options(Client,"SO_KEEPALIVE");
2604     set_socket_options(Client,user_socket_options);
2605   }
2606
2607   return True;
2608 }
2609
2610 /****************************************************************************
2611   process an smb from the client - split out from the process() code so
2612   it can be used by the oplock break code.
2613 ****************************************************************************/
2614
2615 static void process_smb(char *inbuf, char *outbuf)
2616 {
2617   extern int Client;
2618 #ifdef WITH_SSL
2619   extern BOOL sslEnabled;     /* don't use function for performance reasons */
2620   static int sslConnected = 0;
2621 #endif /* WITH_SSL */
2622   static int trans_num;
2623   int msg_type = CVAL(inbuf,0);
2624   int32 len = smb_len(inbuf);
2625   int nread = len + 4;
2626
2627   if (trans_num == 0) {
2628           /* on the first packet, check the global hosts allow/ hosts
2629              deny parameters before doing any parsing of the packet
2630              passed to us by the client.  This prevents attacks on our
2631              parsing code from hosts not in the hosts allow list */
2632           if (!check_access(-1)) {
2633                   /* send a negative session response "not listining on calling
2634                    name" */
2635                   static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2636                   DEBUG(1,("%s Connection denied from %s\n",
2637                            timestring(),client_addr(Client)));
2638                   send_smb(Client,(char *)buf);
2639                   exit_server("connection denied");
2640           }
2641   }
2642
2643   DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2644   DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2645
2646 #ifdef WITH_SSL
2647     if(sslEnabled && !sslConnected){
2648         sslConnected = sslutil_negotiate_ssl(Client, msg_type);
2649         if(sslConnected < 0){   /* an error occured */
2650             exit_server("SSL negotiation failed");
2651         }else if(sslConnected){
2652             trans_num++;
2653             return;
2654         }
2655     }
2656 #endif  /* WITH_SSL */
2657
2658 #ifdef WITH_VTP
2659   if(trans_num == 1 && VT_Check(inbuf)) 
2660   {
2661     VT_Process();
2662     return;
2663   }
2664 #endif
2665
2666   if (msg_type == 0)
2667     show_msg(inbuf);
2668   else if(msg_type == 0x85)
2669     return; /* Keepalive packet. */
2670
2671   nread = construct_reply(inbuf,outbuf,nread,max_send);
2672       
2673   if(nread > 0) 
2674   {
2675     if (CVAL(outbuf,0) == 0)
2676       show_msg(outbuf);
2677         
2678     if (nread != smb_len(outbuf) + 4) 
2679     {
2680       DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2681                  nread, smb_len(outbuf)));
2682     }
2683     else
2684       send_smb(Client,outbuf);
2685   }
2686   trans_num++;
2687 }
2688
2689 /****************************************************************************
2690   open the oplock IPC socket communication
2691 ****************************************************************************/
2692 static BOOL open_oplock_ipc(void)
2693 {
2694   struct sockaddr_in sock_name;
2695   int len = sizeof(sock_name);
2696
2697   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2698
2699   /* Open a lookback UDP socket on a random port. */
2700   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2701   if (oplock_sock == -1)
2702   {
2703     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2704 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2705     oplock_port = 0;
2706     return(False);
2707   }
2708
2709   /* Find out the transient UDP port we have been allocated. */
2710   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2711   {
2712     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2713             strerror(errno)));
2714     close(oplock_sock);
2715     oplock_sock = -1;
2716     oplock_port = 0;
2717     return False;
2718   }
2719   oplock_port = ntohs(sock_name.sin_port);
2720
2721   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
2722             getpid(), oplock_port));
2723
2724   return True;
2725 }
2726
2727 /****************************************************************************
2728   process an oplock break message.
2729 ****************************************************************************/
2730 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2731 {
2732   int32 msg_len;
2733   uint16 from_port;
2734   char *msg_start;
2735
2736   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2737   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2738
2739   msg_start = &buffer[UDP_CMD_HEADER_LEN];
2740
2741   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
2742             msg_len, from_port));
2743
2744   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2745      only valid request. */
2746
2747   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2748   {
2749     case OPLOCK_BREAK_CMD:
2750       /* Ensure that the msg length is correct. */
2751       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2752       {
2753         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2754 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2755         return False;
2756       }
2757       {
2758         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2759         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2760         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2761         struct timeval tval;
2762         struct sockaddr_in toaddr;
2763
2764         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2765         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2766
2767         DEBUG(5,("process_local_message: oplock break request from \
2768 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2769
2770         /*
2771          * If we have no record of any currently open oplocks,
2772          * it's not an error, as a close command may have
2773          * just been issued on the file that was oplocked.
2774          * Just return success in this case.
2775          */
2776
2777         if(global_oplocks_open != 0)
2778         {
2779           if(oplock_break(dev, inode, &tval) == False)
2780           {
2781             DEBUG(0,("process_local_message: oplock break failed - \
2782 not returning udp message.\n"));
2783             return False;
2784           }
2785         }
2786         else
2787         {
2788           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2789 oplocks. Returning success.\n"));
2790         }
2791
2792         /* Send the message back after OR'ing in the 'REPLY' bit. */
2793         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2794   
2795         bzero((char *)&toaddr,sizeof(toaddr));
2796         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2797         toaddr.sin_port = htons(from_port);
2798         toaddr.sin_family = AF_INET;
2799
2800         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2801                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
2802         {
2803           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2804                     remotepid, strerror(errno)));
2805           return False;
2806         }
2807
2808         DEBUG(5,("process_local_message: oplock break reply sent to \
2809 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, 
2810                 from_port, dev, inode));
2811
2812       }
2813       break;
2814     /* 
2815      * Keep this as a debug case - eventually we can remove it.
2816      */
2817     case 0x8001:
2818       DEBUG(0,("process_local_message: Received unsolicited break \
2819 reply - dumping info.\n"));
2820
2821       if(msg_len != OPLOCK_BREAK_MSG_LEN)
2822       {
2823         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2824 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2825         return False;
2826       }
2827
2828       {
2829         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2830         uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2831         uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2832
2833         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2834 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2835
2836        }
2837        return False;
2838
2839     default:
2840       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2841                 (unsigned int)SVAL(msg_start,0)));
2842       return False;
2843   }
2844   return True;
2845 }
2846
2847 /****************************************************************************
2848  Process an oplock break directly.
2849 ****************************************************************************/
2850 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2851 {
2852   extern struct current_user current_user;
2853   extern int Client;
2854   char *inbuf = NULL;
2855   char *outbuf = NULL;
2856   files_struct *fsp = NULL;
2857   int fnum;
2858   time_t start_time;
2859   BOOL shutdown_server = False;
2860   int saved_cnum;
2861   int saved_vuid;
2862   pstring saved_dir; 
2863
2864   DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2865 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2866
2867   /* We need to search the file open table for the
2868      entry containing this dev and inode, and ensure
2869      we have an oplock on it. */
2870   for( fnum = 0; fnum < MAX_FNUMS; fnum++)
2871   {
2872     if(OPEN_FNUM(fnum))
2873     {
2874       if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
2875          (Files[fnum].open_time.tv_sec == tval->tv_sec) && 
2876          (Files[fnum].open_time.tv_usec == tval->tv_usec)) {
2877               fsp = &Files[fnum];
2878               break;
2879       }
2880     }
2881   }
2882
2883   if(fsp == NULL)
2884   {
2885     /* The file could have been closed in the meantime - return success. */
2886     DEBUG(0,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2887 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2888     return True;
2889   }
2890
2891   /* Ensure we have an oplock on the file */
2892
2893   /* There is a potential race condition in that an oplock could
2894      have been broken due to another udp request, and yet there are
2895      still oplock break messages being sent in the udp message
2896      queue for this file. So return true if we don't have an oplock,
2897      as we may have just freed it.
2898    */
2899
2900   if(!fsp->granted_oplock)
2901   {
2902     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));
2903     return True;
2904   }
2905
2906   /* mark the oplock break as sent - we don't want to send twice! */
2907   if (fsp->sent_oplock_break)
2908   {
2909     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));
2910
2911     /* We have to fail the open here as we cannot send another oplock break on this
2912        file whilst we are awaiting a response from the client - neither can we
2913        allow another open to succeed while we are waiting for the client. */
2914     return False;
2915   }
2916
2917   /* Now comes the horrid part. We must send an oplock break to the client,
2918      and then process incoming messages until we get a close or oplock release.
2919      At this point we know we need a new inbuf/outbuf buffer pair.
2920      We cannot use these staticaly as we may recurse into here due to
2921      messages crossing on the wire.
2922    */
2923
2924   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2925   {
2926     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2927     return False;
2928   }
2929
2930   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
2931   {
2932     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2933     free(inbuf);
2934     inbuf = NULL;
2935     return False;
2936   }
2937
2938   /* Prepare the SMBlockingX message. */
2939   bzero(outbuf,smb_size);
2940   set_message(outbuf,8,0,True);
2941
2942   SCVAL(outbuf,smb_com,SMBlockingX);
2943   SSVAL(outbuf,smb_tid,fsp->cnum);
2944   SSVAL(outbuf,smb_pid,0xFFFF);
2945   SSVAL(outbuf,smb_uid,0);
2946   SSVAL(outbuf,smb_mid,0xFFFF);
2947   SCVAL(outbuf,smb_vwv0,0xFF);
2948   SSVAL(outbuf,smb_vwv2,fnum);
2949   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2950   /* Change this when we have level II oplocks. */
2951   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2952  
2953   send_smb(Client, outbuf);
2954
2955   /* Remember we just sent an oplock break on this file. */
2956   fsp->sent_oplock_break = True;
2957
2958   /* We need this in case a readraw crosses on the wire. */
2959   global_oplock_break = True;
2960  
2961   /* Process incoming messages. */
2962
2963   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2964      seconds we should just die.... */
2965
2966   start_time = time(NULL);
2967
2968   /*
2969    * Save the information we need to re-become the
2970    * user, then unbecome the user whilst we're doing this.
2971    */
2972   saved_cnum = fsp->cnum;
2973   saved_vuid = current_user.vuid;
2974   GetWd(saved_dir);
2975   unbecome_user();
2976
2977   while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2978   {
2979     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2980     {
2981       /*
2982        * Die if we got an error.
2983        */
2984
2985       if (smb_read_error == READ_EOF)
2986         DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2987  
2988       if (smb_read_error == READ_ERROR)
2989         DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2990                   timestring(), strerror(errno)));
2991
2992       if (smb_read_error == READ_TIMEOUT)
2993         DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2994                   timestring(), OPLOCK_BREAK_TIMEOUT));
2995
2996       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2997 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2998       shutdown_server = True;
2999       break;
3000     }
3001
3002     /*
3003      * There are certain SMB requests that we shouldn't allow
3004      * to recurse. opens, renames and deletes are the obvious
3005      * ones. This is handled in the switch_message() function.
3006      * If global_oplock_break is set they will push the packet onto
3007      * the pending smb queue and return -1 (no reply).
3008      * JRA.
3009      */
3010
3011     process_smb(inbuf, outbuf);
3012
3013     /*
3014      * Die if we go over the time limit.
3015      */
3016
3017     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
3018     {
3019       DEBUG(0,("%s oplock_break: no break received from client within \
3020 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
3021       DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
3022 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
3023       shutdown_server = True;
3024       break;
3025     }
3026   }
3027
3028   /*
3029    * Go back to being the user who requested the oplock
3030    * break.
3031    */
3032   if(!become_user(&Connections[saved_cnum], saved_cnum, saved_vuid))
3033   {
3034     DEBUG(0,("%s oplock_break: unable to re-become user ! Shutting down server\n",
3035           timestring()));
3036     close_sockets();
3037     close(oplock_sock);
3038     exit_server("unable to re-become user");
3039   }
3040   /* Including the directory. */
3041   ChDir(saved_dir);
3042
3043   /* Free the buffers we've been using to recurse. */
3044   free(inbuf);
3045   free(outbuf);
3046
3047   /* We need this in case a readraw crossed on the wire. */
3048   if(global_oplock_break)
3049     global_oplock_break = False;
3050
3051   /*
3052    * If the client did not respond we must die.
3053    */
3054
3055   if(shutdown_server)
3056   {
3057     DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
3058           timestring()));
3059     close_sockets();
3060     close(oplock_sock);
3061     exit_server("oplock break failure");
3062   }
3063
3064   if(OPEN_FNUM(fnum))
3065   {
3066     /* The lockingX reply will have removed the oplock flag 
3067        from the sharemode. */
3068     /* Paranoia.... */
3069     fsp->granted_oplock = False;
3070     fsp->sent_oplock_break = False;
3071     global_oplocks_open--;
3072   }
3073
3074   /* Santity check - remove this later. JRA */
3075   if(global_oplocks_open < 0)
3076   {
3077     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
3078               global_oplocks_open));
3079     exit_server("oplock_break: global_oplocks_open < 0");
3080   }
3081
3082   DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
3083 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
3084
3085   return True;
3086 }
3087
3088 /****************************************************************************
3089 Send an oplock break message to another smbd process. If the oplock is held 
3090 by the local smbd then call the oplock break function directly.
3091 ****************************************************************************/
3092
3093 BOOL request_oplock_break(share_mode_entry *share_entry, 
3094                           uint32 dev, uint32 inode)
3095 {
3096   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
3097   struct sockaddr_in addr_out;
3098   int pid = getpid();
3099   time_t start_time;
3100   int time_left;
3101
3102   if(pid == share_entry->pid)
3103   {
3104     /* We are breaking our own oplock, make sure it's us. */
3105     if(share_entry->op_port != oplock_port)
3106     {
3107       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
3108 should be %d\n", pid, share_entry->op_port, oplock_port));
3109       return False;
3110     }
3111
3112     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
3113
3114     /* Call oplock break direct. */
3115     return oplock_break(dev, inode, &share_entry->time);
3116   }
3117
3118   /* We need to send a OPLOCK_BREAK_CMD message to the
3119      port in the share mode entry. */
3120
3121   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
3122   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
3123   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
3124   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
3125   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
3126   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
3127
3128   /* set the address and port */
3129   bzero((char *)&addr_out,sizeof(addr_out));
3130   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3131   addr_out.sin_port = htons( share_entry->op_port );
3132   addr_out.sin_family = AF_INET;
3133    
3134   DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
3135 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3136
3137   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
3138          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
3139   {
3140     DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
3141 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
3142          timestring(), share_entry->pid, share_entry->op_port, dev, inode,
3143          strerror(errno)));
3144     return False;
3145   }
3146
3147   /*
3148    * Now we must await the oplock broken message coming back
3149    * from the target smbd process. Timeout if it fails to
3150    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
3151    * While we get messages that aren't ours, loop.
3152    */
3153
3154   start_time = time(NULL);
3155   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
3156
3157   while(time_left >= 0)
3158   {
3159     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3160     int32 reply_msg_len;
3161     uint16 reply_from_port;
3162     char *reply_msg_start;
3163
3164     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3165                time_left ? time_left * 1000 : 1) == False)
3166     {
3167       if(smb_read_error == READ_TIMEOUT)
3168       {
3169         DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3170 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid, 
3171                            share_entry->op_port, dev, inode));
3172         /*
3173          * This is a hack to make handling of failing clients more robust.
3174          * If a oplock break response message is not received in the timeout
3175          * period we may assume that the smbd servicing that client holding
3176          * the oplock has died and the client changes were lost anyway, so
3177          * we should continue to try and open the file.
3178          */
3179         break;
3180       }
3181       else
3182         DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3183 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid, 
3184                          share_entry->op_port, dev, inode, strerror(errno)));
3185       return False;
3186     }
3187
3188     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3189     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3190
3191     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3192
3193     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3194     {
3195       /* Ignore it. */
3196       DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3197              timestring()));
3198       continue;
3199     }
3200
3201     /*
3202      * Test to see if this is the reply we are awaiting.
3203      */
3204
3205     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
3206        (reply_from_port == share_entry->op_port) && 
3207        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
3208                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3209                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
3210     {
3211       /*
3212        * This is the reply we've been waiting for.
3213        */
3214       break;
3215     }
3216     else
3217     {
3218       /*
3219        * This is another message - probably a break request.
3220        * Process it to prevent potential deadlock.
3221        * Note that the code in switch_message() prevents
3222        * us from recursing into here as any SMB requests
3223        * we might process that would cause another oplock
3224        * break request to be made will be queued.
3225        * JRA.
3226        */
3227
3228       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
3229     }
3230
3231     time_left -= (time(NULL) - start_time);
3232   }
3233
3234   DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3235
3236   return True;
3237 }
3238
3239 /****************************************************************************
3240 Get the next SMB packet, doing the local message processing automatically.
3241 ****************************************************************************/
3242
3243 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
3244 {
3245   BOOL got_smb = False;
3246   BOOL ret;
3247
3248   do
3249   {
3250     ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
3251                                  timeout,&got_smb);
3252
3253     if(ret && !got_smb)
3254     {
3255       /* Deal with oplock break requests from other smbd's. */
3256       process_local_message(oplock_sock, inbuf, bufsize);
3257       continue;
3258     }
3259
3260     if(ret && (CVAL(inbuf,0) == 0x85))
3261     {
3262       /* Keepalive packet. */
3263       got_smb = False;
3264     }
3265
3266   }
3267   while(ret && !got_smb);
3268
3269   return ret;
3270 }
3271
3272 /****************************************************************************
3273 check if a snum is in use
3274 ****************************************************************************/
3275 BOOL snum_used(int snum)
3276 {
3277   int i;
3278   for (i=0;i<MAX_CONNECTIONS;i++)
3279     if (OPEN_CNUM(i) && (SNUM(i) == snum))
3280       return(True);
3281   return(False);
3282 }
3283
3284 /****************************************************************************
3285   reload the services file
3286   **************************************************************************/
3287 BOOL reload_services(BOOL test)
3288 {
3289   BOOL ret;
3290
3291   if (lp_loaded())
3292   {
3293     pstring fname;
3294     pstrcpy(fname,lp_configfile());
3295     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3296     {
3297       pstrcpy(servicesf,fname);
3298       test = False;
3299     }
3300   }
3301
3302   reopen_logs();
3303
3304   if (test && !lp_file_list_changed())
3305     return(True);
3306
3307   lp_killunused(snum_used);
3308
3309   ret = lp_load(servicesf,False,False,True);
3310
3311   /* perhaps the config filename is now set */
3312   if (!test)
3313     reload_services(True);
3314
3315   reopen_logs();
3316
3317   load_interfaces();
3318
3319   {
3320     extern int Client;
3321     if (Client != -1) {      
3322       set_socket_options(Client,"SO_KEEPALIVE");
3323       set_socket_options(Client,user_socket_options);
3324     }
3325   }
3326
3327   reset_mangled_cache();
3328
3329   /* this forces service parameters to be flushed */
3330   become_service(-1,True);
3331
3332   return(ret);
3333 }
3334
3335
3336
3337 /****************************************************************************
3338 this prevents zombie child processes
3339 ****************************************************************************/
3340 static BOOL reload_after_sighup = False;
3341
3342 static int sig_hup(void)
3343 {
3344   BlockSignals(True,SIGHUP);
3345   DEBUG(0,("Got SIGHUP\n"));
3346
3347   /*
3348    * Fix from <branko.cibej@hermes.si> here.
3349    * We used to reload in the signal handler - this
3350    * is a *BIG* no-no.
3351    */
3352
3353   reload_after_sighup = True;
3354   BlockSignals(False,SIGHUP);
3355   return(0);
3356 }
3357
3358
3359 /****************************************************************************
3360   make a connection to a service
3361 ****************************************************************************/
3362 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3363 {
3364   int cnum;
3365   int snum;
3366   struct passwd *pass = NULL;
3367   connection_struct *pcon;
3368   BOOL guest = False;
3369   BOOL force = False;
3370
3371   strlower(service);
3372
3373   snum = find_service(service);
3374   if (snum < 0)
3375     {
3376       extern int Client;
3377       if (strequal(service,"IPC$"))
3378         {         
3379           DEBUG(3,("%s refusing IPC connection\n",timestring()));
3380           return(-3);
3381         }
3382
3383       DEBUG(0,("%s %s (%s) couldn't find service %s\n",timestring(),remote_machine,client_addr(Client),service));      
3384       return(-2);
3385     }
3386
3387   if (strequal(service,HOMES_NAME))
3388     {
3389       if (*user && Get_Pwnam(user,True))
3390         return(make_connection(user,user,password,pwlen,dev,vuid));
3391
3392       if(lp_security() != SEC_SHARE)
3393       {
3394         if (validated_username(vuid))
3395         {
3396           pstrcpy(user,validated_username(vuid));
3397           return(make_connection(user,user,password,pwlen,dev,vuid));
3398         }
3399       }
3400       else
3401       {
3402         /*
3403          * Security = share. Try with sesssetup_user as the username.
3404          */
3405         if(*sesssetup_user)
3406         {
3407           pstrcpy(user,sesssetup_user);
3408           return(make_connection(user,user,password,pwlen,dev,vuid));
3409         }
3410       }
3411     }
3412
3413   if (!lp_snum_ok(snum) || !check_access(snum)) {    
3414     return(-4);
3415   }
3416
3417   /* you can only connect to the IPC$ service as an ipc device */
3418   if (strequal(service,"IPC$"))
3419     pstrcpy(dev,"IPC");
3420
3421   if (*dev == '?' || !*dev)
3422     {
3423       if (lp_print_ok(snum))
3424         pstrcpy(dev,"LPT1:");
3425       else
3426         pstrcpy(dev,"A:");
3427     }
3428
3429   /* if the request is as a printer and you can't print then refuse */
3430   strupper(dev);
3431   if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3432     DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3433     return(-6);
3434   }
3435
3436   /* lowercase the user name */
3437   strlower(user);
3438
3439   /* add it as a possible user name */
3440   add_session_user(service);
3441
3442   /* shall we let them in? */
3443   if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3444     {
3445       DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3446       return(-1);
3447     }
3448   
3449   cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3450   if (cnum < 0)
3451     {
3452       DEBUG(0,("%s couldn't find free connection\n",timestring()));      
3453       return(-1);
3454     }
3455
3456   pcon = &Connections[cnum];
3457   bzero((char *)pcon,sizeof(*pcon));
3458
3459   /* find out some info about the user */
3460   pass = Get_Pwnam(user,True);
3461
3462   if (pass == NULL)
3463     {
3464       DEBUG(0,("%s couldn't find account %s\n",timestring(),user)); 
3465       return(-7);
3466     }
3467
3468   pcon->read_only = lp_readonly(snum);
3469
3470   {
3471     pstring list;
3472     StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3473     string_sub(list,"%S",service);
3474
3475     if (user_in_list(user,list))
3476       pcon->read_only = True;
3477
3478     StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3479     string_sub(list,"%S",service);
3480
3481     if (user_in_list(user,list))
3482       pcon->read_only = False;    
3483   }
3484
3485   /* admin user check */
3486
3487   /* JRA - original code denied admin user if the share was
3488      marked read_only. Changed as I don't think this is needed,
3489      but old code left in case there is a problem here.
3490    */
3491   if (user_in_list(user,lp_admin_users(snum)) 
3492 #if 0
3493       && !pcon->read_only)
3494 #else
3495       )
3496 #endif
3497     {
3498       pcon->admin_user = True;
3499       DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3500     }
3501   else
3502     pcon->admin_user = False;
3503     
3504   pcon->force_user = force;
3505   pcon->vuid = vuid;
3506   pcon->uid = pass->pw_uid;
3507   pcon->gid = pass->pw_gid;
3508   pcon->num_files_open = 0;
3509   pcon->lastused = time(NULL);
3510   pcon->service = snum;
3511   pcon->used = True;
3512   pcon->printer = (strncmp(dev,"LPT",3) == 0);
3513   pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3514   pcon->dirptr = NULL;
3515   pcon->veto_list = NULL;
3516   pcon->hide_list = NULL;
3517   pcon->veto_oplock_list = NULL;
3518   string_set(&pcon->dirpath,"");
3519   string_set(&pcon->user,user);
3520
3521 #ifdef HAVE_GETGRNAM 
3522   if (*lp_force_group(snum))
3523     {
3524       struct group *gptr;
3525       pstring gname;
3526
3527       StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3528       /* default service may be a group name            */
3529       string_sub(gname,"%S",service);
3530       gptr = (struct group *)getgrnam(gname);
3531
3532       if (gptr)
3533         {
3534           pcon->gid = gptr->gr_gid;
3535           DEBUG(3,("Forced group %s\n",gname));
3536         }
3537       else
3538         DEBUG(1,("Couldn't find group %s\n",gname));
3539     }
3540 #endif
3541
3542   if (*lp_force_user(snum))
3543     {
3544       struct passwd *pass2;
3545       fstring fuser;
3546       fstrcpy(fuser,lp_force_user(snum));
3547       pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3548       if (pass2)
3549         {
3550           pcon->uid = pass2->pw_uid;
3551           string_set(&pcon->user,fuser);
3552           fstrcpy(user,fuser);
3553           pcon->force_user = True;
3554           DEBUG(3,("Forced user %s\n",fuser));    
3555         }
3556       else
3557         DEBUG(1,("Couldn't find user %s\n",fuser));
3558     }
3559
3560   {
3561     pstring s;
3562     pstrcpy(s,lp_pathname(snum));
3563     standard_sub(cnum,s);
3564     string_set(&pcon->connectpath,s);
3565     DEBUG(3,("Connect path is %s\n",s));
3566   }
3567
3568   /* groups stuff added by ih */
3569   pcon->ngroups = 0;
3570   pcon->igroups = NULL;
3571   pcon->groups = NULL;
3572
3573   if (!IS_IPC(cnum))
3574     {
3575       /* Find all the groups this uid is in and store them. Used by become_user() */
3576       setup_groups(pcon->user,pcon->uid,pcon->gid,
3577                   &pcon->ngroups,&pcon->igroups,&pcon->groups);
3578       
3579       /* check number of connections */
3580       if (!claim_connection(cnum,
3581                             lp_servicename(SNUM(cnum)),
3582                             lp_max_connections(SNUM(cnum)),False))
3583         {
3584           DEBUG(1,("too many connections - rejected\n"));
3585           return(-8);
3586         }  
3587
3588       if (lp_status(SNUM(cnum)))
3589         claim_connection(cnum,"STATUS.",MAXSTATUS,False);
3590     } /* IS_IPC */
3591
3592   pcon->open = True;
3593
3594   /* execute any "root preexec = " line */
3595   if (*lp_rootpreexec(SNUM(cnum)))
3596     {
3597       pstring cmd;
3598       pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3599       standard_sub(cnum,cmd);
3600       DEBUG(5,("cmd=%s\n",cmd));
3601       smbrun(cmd,NULL,False);
3602     }
3603
3604   if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3605     {
3606       DEBUG(0,("Can't become connected user!\n"));
3607       pcon->open = False;
3608       if (!IS_IPC(cnum)) {
3609         yield_connection(cnum,
3610                          lp_servicename(SNUM(cnum)),
3611                          lp_max_connections(SNUM(cnum)));
3612         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3613       }
3614       return(-1);
3615     }
3616
3617   if (ChDir(pcon->connectpath) != 0)
3618     {
3619       DEBUG(0,("Can't change directory to %s (%s)\n",
3620                pcon->connectpath,strerror(errno)));
3621       pcon->open = False;
3622       unbecome_user();
3623       if (!IS_IPC(cnum)) {
3624         yield_connection(cnum,
3625                          lp_servicename(SNUM(cnum)),
3626                          lp_max_connections(SNUM(cnum)));
3627         if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3628       }
3629       return(-5);      
3630     }
3631
3632   string_set(&pcon->origpath,pcon->connectpath);
3633
3634 #if SOFTLINK_OPTIMISATION
3635   /* resolve any soft links early */
3636   {
3637     pstring s;
3638     pstrcpy(s,pcon->connectpath);
3639     GetWd(s);
3640     string_set(&pcon->connectpath,s);
3641     ChDir(pcon->connectpath);
3642   }
3643 #endif
3644
3645   num_connections_open++;
3646   add_session_user(user);
3647   
3648   /* execute any "preexec = " line */
3649   if (*lp_preexec(SNUM(cnum)))
3650     {
3651       pstring cmd;
3652       pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3653       standard_sub(cnum,cmd);
3654       smbrun(cmd,NULL,False);
3655     }
3656   
3657   /* we've finished with the sensitive stuff */
3658   unbecome_user();
3659
3660   /* Add veto/hide lists */
3661   if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3662   {
3663     set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3664     set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3665     set_namearray( &pcon->veto_oplock_list, lp_veto_oplocks(SNUM(cnum)));
3666   }
3667
3668   {
3669     extern int Client;
3670     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3671                             timestring(),
3672                             remote_machine,
3673                             client_addr(Client),
3674                             lp_servicename(SNUM(cnum)),user,
3675                             pcon->uid,
3676                             pcon->gid,
3677                             (int)getpid()));
3678   }
3679
3680   return(cnum);
3681 }
3682
3683 /****************************************************************************
3684   Attempt to break an oplock on a file (if oplocked).
3685   Returns True if the file was closed as a result of
3686   the oplock break, False otherwise.
3687   Used as a last ditch attempt to free a space in the 
3688   file table when we have run out.
3689 ****************************************************************************/
3690
3691 static BOOL attempt_close_oplocked_file(files_struct *fp)
3692 {
3693
3694   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
3695
3696   if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
3697
3698     /* Try and break the oplock. */
3699     file_fd_struct *fsp = fp->fd_ptr;
3700     if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
3701       if(!fp->open) /* Did the oplock break close the file ? */
3702         return True;
3703     }
3704   }
3705
3706   return False;
3707 }
3708
3709 /****************************************************************************
3710   find first available file slot
3711 ****************************************************************************/
3712 int find_free_file(void )
3713 {
3714         int i;
3715         static int first_file;
3716
3717         /* we want to give out file handles differently on each new
3718            connection because of a common bug in MS clients where they try to
3719            reuse a file descriptor from an earlier smb connection. This code
3720            increases the chance that the errant client will get an error rather
3721            than causing corruption */
3722         if (first_file == 0) {
3723                 first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
3724                 if (first_file == 0) first_file = 1;
3725         }
3726
3727         if (first_file >= MAX_FNUMS)
3728                 first_file = 1;
3729
3730         for (i=first_file;i<MAX_FNUMS;i++)
3731                 if (!Files[i].open && !Files[i].reserved) {
3732                         memset(&Files[i], 0, sizeof(Files[i]));
3733                         first_file = i+1;
3734                         Files[i].reserved = True;
3735                         return(i);
3736                 }
3737
3738         /* returning a file handle of 0 is a bad idea - so we start at 1 */
3739         for (i=1;i<first_file;i++)
3740                 if (!Files[i].open && !Files[i].reserved) {
3741                         memset(&Files[i], 0, sizeof(Files[i]));
3742                         first_file = i+1;
3743                         Files[i].reserved = True;
3744                         return(i);
3745                 }
3746
3747         /* 
3748          * Before we give up, go through the open files 
3749          * and see if there are any files opened with a
3750          * batch oplock. If so break the oplock and then
3751          * re-use that entry (if it becomes closed).
3752          * This may help as NT/95 clients tend to keep
3753          * files batch oplocked for quite a long time
3754          * after they have finished with them.
3755          */
3756         for (i=first_file;i<MAX_FNUMS;i++) {
3757           if(attempt_close_oplocked_file( &Files[i])) {
3758             memset(&Files[i], 0, sizeof(Files[i]));
3759             first_file = i+1;
3760             Files[i].reserved = True;
3761             return(i);
3762           }
3763         }
3764
3765         for (i=1;i<MAX_FNUMS;i++) {
3766           if(attempt_close_oplocked_file( &Files[i])) {
3767             memset(&Files[i], 0, sizeof(Files[i]));
3768             first_file = i+1;
3769             Files[i].reserved = True;
3770             return(i);
3771           }
3772         }
3773
3774         DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3775         return(-1);
3776 }
3777
3778 /****************************************************************************
3779   find first available connection slot, starting from a random position.
3780 The randomisation stops problems with the server dieing and clients
3781 thinking the server is still available.
3782 ****************************************************************************/
3783 static int find_free_connection(int hash )
3784 {
3785   int i;
3786   BOOL used=False;
3787   hash = (hash % (MAX_CONNECTIONS-2))+1;
3788
3789  again:
3790
3791   for (i=hash+1;i!=hash;)
3792     {
3793       if (!Connections[i].open && Connections[i].used == used) 
3794         {
3795           DEBUG(3,("found free connection number %d\n",i));
3796           return(i);
3797         }
3798       i++;
3799       if (i == MAX_CONNECTIONS)
3800         i = 1;
3801     }
3802
3803   if (!used)
3804     {
3805       used = !used;
3806       goto again;
3807     }
3808
3809   DEBUG(1,("ERROR! Out of connection structures\n"));
3810   return(-1);
3811 }
3812
3813
3814 /****************************************************************************
3815 reply for the core protocol
3816 ****************************************************************************/
3817 int reply_corep(char *outbuf)
3818 {
3819   int outsize = set_message(outbuf,1,0,True);
3820
3821   Protocol = PROTOCOL_CORE;
3822
3823   return outsize;
3824 }
3825
3826
3827 /****************************************************************************
3828 reply for the coreplus protocol
3829 ****************************************************************************/
3830 int reply_coreplus(char *outbuf)
3831 {
3832   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3833   int outsize = set_message(outbuf,13,0,True);
3834   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3835                                  readbraw and writebraw (possibly) */
3836   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3837   SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */  
3838
3839   Protocol = PROTOCOL_COREPLUS;
3840
3841   return outsize;
3842 }
3843
3844
3845 /****************************************************************************
3846 reply for the lanman 1.0 protocol
3847 ****************************************************************************/
3848 int reply_lanman1(char *outbuf)
3849 {
3850   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3851   int secword=0;
3852   BOOL doencrypt = SMBENCRYPT();
3853   time_t t = time(NULL);
3854
3855   if (lp_security()>=SEC_USER) secword |= 1;
3856   if (doencrypt) secword |= 2;
3857
3858   set_message(outbuf,13,doencrypt?8:0,True);
3859   SSVAL(outbuf,smb_vwv1,secword); 
3860   /* Create a token value and add it to the outgoing packet. */
3861   if (doencrypt) 
3862     generate_next_challenge(smb_buf(outbuf));
3863
3864   Protocol = PROTOCOL_LANMAN1;
3865
3866   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3867   SSVAL(outbuf,smb_vwv2,max_recv);
3868   SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3869   SSVAL(outbuf,smb_vwv4,1);
3870   SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3871                                  readbraw writebraw (possibly) */
3872   SIVAL(outbuf,smb_vwv6,getpid());
3873   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3874
3875   put_dos_date(outbuf,smb_vwv8,t);
3876
3877   return (smb_len(outbuf)+4);
3878 }
3879
3880
3881 /****************************************************************************
3882 reply for the lanman 2.0 protocol
3883 ****************************************************************************/
3884 int reply_lanman2(char *outbuf)
3885 {
3886   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3887   int secword=0;
3888   BOOL doencrypt = SMBENCRYPT();
3889   time_t t = time(NULL);
3890   struct cli_state *cli = NULL;
3891   char cryptkey[8];
3892   char crypt_len = 0;
3893
3894   if (lp_security() == SEC_SERVER) {
3895           cli = server_cryptkey();
3896   }
3897
3898   if (cli) {
3899           DEBUG(3,("using password server validation\n"));
3900           doencrypt = ((cli->sec_mode & 2) != 0);
3901   }
3902
3903   if (lp_security()>=SEC_USER) secword |= 1;
3904   if (doencrypt) secword |= 2;
3905
3906   if (doencrypt) {
3907           crypt_len = 8;
3908           if (!cli) {
3909                   generate_next_challenge(cryptkey);
3910           } else {
3911                   memcpy(cryptkey, cli->cryptkey, 8);
3912                   set_challenge(cli->cryptkey);
3913           }
3914   }
3915
3916   set_message(outbuf,13,crypt_len,True);
3917   SSVAL(outbuf,smb_vwv1,secword); 
3918   SIVAL(outbuf,smb_vwv6,getpid());
3919   if (doencrypt) 
3920           memcpy(smb_buf(outbuf), cryptkey, 8);
3921
3922   Protocol = PROTOCOL_LANMAN2;
3923
3924   CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3925   SSVAL(outbuf,smb_vwv2,max_recv);
3926   SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
3927   SSVAL(outbuf,smb_vwv4,1);
3928   SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3929   SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3930   put_dos_date(outbuf,smb_vwv8,t);
3931
3932   return (smb_len(outbuf)+4);
3933 }
3934
3935
3936 /****************************************************************************
3937 reply for the nt protocol
3938 ****************************************************************************/
3939 int reply_nt1(char *outbuf)
3940 {
3941   /* dual names + lock_and_read + nt SMBs + remote API calls */
3942   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS |CAP_NT_SMBS;
3943
3944 /*
3945   other valid capabilities which we may support at some time...
3946                      CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3947                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3948  */
3949
3950   int secword=0;
3951   BOOL doencrypt = SMBENCRYPT();
3952   time_t t = time(NULL);
3953   int data_len;
3954   struct cli_state *cli = NULL;
3955   char cryptkey[8];
3956   char crypt_len = 0;
3957
3958   if (lp_security() == SEC_SERVER) {
3959           cli = server_cryptkey();
3960   }
3961
3962   if (cli) {
3963           DEBUG(3,("using password server validation\n"));
3964           doencrypt = ((cli->sec_mode & 2) != 0);
3965   }
3966
3967   if (doencrypt) {
3968           crypt_len = 8;
3969           if (!cli) {
3970                   generate_next_challenge(cryptkey);
3971           } else {
3972                   memcpy(cryptkey, cli->cryptkey, 8);
3973                   set_challenge(cli->cryptkey);
3974           }
3975   }
3976
3977   if (lp_readraw() && lp_writeraw()) {
3978           capabilities |= CAP_RAW_MODE;
3979   }
3980
3981   if (lp_security() >= SEC_USER) secword |= 1;
3982   if (doencrypt) secword |= 2;
3983
3984   /* decide where (if) to put the encryption challenge, and
3985      follow it with the OEM'd domain name
3986    */
3987   data_len = crypt_len + strlen(global_myworkgroup) + 1;
3988
3989   set_message(outbuf,17,data_len,True);
3990   pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
3991
3992   CVAL(outbuf,smb_vwv1) = secword;
3993   SSVALS(outbuf,smb_vwv16+1,crypt_len);
3994   if (doencrypt) 
3995           memcpy(smb_buf(outbuf), cryptkey, 8);
3996
3997   Protocol = PROTOCOL_NT1;
3998
3999   SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
4000   SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
4001   SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
4002   SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
4003   SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
4004   SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
4005   put_long_date(outbuf+smb_vwv11+1,t);
4006   SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
4007   SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
4008
4009   return (smb_len(outbuf)+4);
4010 }
4011
4012 /* these are the protocol lists used for auto architecture detection:
4013
4014 WinNT 3.51:
4015 protocol [PC NETWORK PROGRAM 1.0]
4016 protocol [XENIX CORE]
4017 protocol [MICROSOFT NETWORKS 1.03]
4018 protocol [LANMAN1.0]
4019 protocol [Windows for Workgroups 3.1a]
4020 protocol [LM1.2X002]
4021 protocol [LANMAN2.1]
4022 protocol [NT LM 0.12]
4023
4024 Win95:
4025 protocol [PC NETWORK PROGRAM 1.0]
4026 protocol [XENIX CORE]
4027 protocol [MICROSOFT NETWORKS 1.03]
4028 protocol [LANMAN1.0]
4029 protocol [Windows for Workgroups 3.1a]
4030 protocol [LM1.2X002]
4031 protocol [LANMAN2.1]
4032 protocol [NT LM 0.12]
4033
4034 OS/2:
4035 protocol [PC NETWORK PROGRAM 1.0]
4036 protocol [XENIX CORE]
4037 protocol [LANMAN1.0]
4038 protocol [LM1.2X002]
4039 protocol [LANMAN2.1]
4040 */
4041
4042 /*
4043   * Modified to recognize the architecture of the remote machine better.
4044   *
4045   * This appears to be the matrix of which protocol is used by which
4046   * MS product.
4047        Protocol                       WfWg    Win95   WinNT  OS/2
4048        PC NETWORK PROGRAM 1.0          1       1       1      1
4049        XENIX CORE                                      2      2
4050        MICROSOFT NETWORKS 3.0          2       2       
4051        DOS LM1.2X002                   3       3       
4052        MICROSOFT NETWORKS 1.03                         3
4053        DOS LANMAN2.1                   4       4       
4054        LANMAN1.0                                       4      3
4055        Windows for Workgroups 3.1a     5       5       5
4056        LM1.2X002                                       6      4
4057        LANMAN2.1                                       7      5
4058        NT LM 0.12                              6       8
4059   *
4060   *  tim@fsg.com 09/29/95
4061   */
4062   
4063 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
4064 #define ARCH_WIN95    0x2
4065 #define ARCH_OS2      0xC      /* Again OS/2 is like NT */
4066 #define ARCH_WINNT    0x8
4067 #define ARCH_SAMBA    0x10
4068  
4069 #define ARCH_ALL      0x1F
4070  
4071 /* List of supported protocols, most desired first */
4072 struct {
4073   char *proto_name;
4074   char *short_name;
4075   int (*proto_reply_fn)(char *);
4076   int protocol_level;
4077 } supported_protocols[] = {
4078   {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
4079   {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
4080   {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4081   {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4082   {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
4083   {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4084   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
4085   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
4086   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
4087   {NULL,NULL},
4088 };
4089
4090
4091 /****************************************************************************
4092   reply to a negprot
4093 ****************************************************************************/
4094 static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4095 {
4096   int outsize = set_message(outbuf,1,0,True);
4097   int Index=0;
4098   int choice= -1;
4099   int protocol;
4100   char *p;
4101   int bcc = SVAL(smb_buf(inbuf),-2);
4102   int arch = ARCH_ALL;
4103
4104   p = smb_buf(inbuf)+1;
4105   while (p < (smb_buf(inbuf) + bcc))
4106     { 
4107       Index++;
4108       DEBUG(3,("Requested protocol [%s]\n",p));
4109       if (strcsequal(p,"Windows for Workgroups 3.1a"))
4110         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
4111       else if (strcsequal(p,"DOS LM1.2X002"))
4112         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4113       else if (strcsequal(p,"DOS LANMAN2.1"))
4114         arch &= ( ARCH_WFWG | ARCH_WIN95 );
4115       else if (strcsequal(p,"NT LM 0.12"))
4116         arch &= ( ARCH_WIN95 | ARCH_WINNT );
4117       else if (strcsequal(p,"LANMAN2.1"))
4118         arch &= ( ARCH_WINNT | ARCH_OS2 );
4119       else if (strcsequal(p,"LM1.2X002"))
4120         arch &= ( ARCH_WINNT | ARCH_OS2 );
4121       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
4122         arch &= ARCH_WINNT;
4123       else if (strcsequal(p,"XENIX CORE"))
4124         arch &= ( ARCH_WINNT | ARCH_OS2 );
4125       else if (strcsequal(p,"Samba")) {
4126         arch = ARCH_SAMBA;
4127         break;
4128       }
4129  
4130       p += strlen(p) + 2;
4131     }
4132     
4133   switch ( arch ) {
4134   case ARCH_SAMBA:
4135     set_remote_arch(RA_SAMBA);
4136     break;
4137   case ARCH_WFWG:
4138     set_remote_arch(RA_WFWG);
4139     break;
4140   case ARCH_WIN95:
4141     set_remote_arch(RA_WIN95);
4142     break;
4143   case ARCH_WINNT:
4144     set_remote_arch(RA_WINNT);
4145     break;
4146   case ARCH_OS2:
4147     set_remote_arch(RA_OS2);
4148     break;
4149   default:
4150     set_remote_arch(RA_UNKNOWN);
4151     break;
4152   }
4153  
4154   /* possibly reload - change of architecture */
4155   reload_services(True);      
4156     
4157   /* a special case to stop password server loops */
4158   if (Index == 1 && strequal(remote_machine,myhostname) && 
4159       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
4160     exit_server("Password server loop!");
4161   
4162   /* Check for protocols, most desirable first */
4163   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
4164     {
4165       p = smb_buf(inbuf)+1;
4166       Index = 0;
4167       if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
4168         while (p < (smb_buf(inbuf) + bcc))
4169           { 
4170             if (strequal(p,supported_protocols[protocol].proto_name))
4171               choice = Index;
4172             Index++;
4173             p += strlen(p) + 2;
4174           }
4175       if(choice != -1)
4176         break;
4177     }
4178   
4179   SSVAL(outbuf,smb_vwv0,choice);
4180   if(choice != -1) {
4181     extern fstring remote_proto;
4182     fstrcpy(remote_proto,supported_protocols[protocol].short_name);
4183     reload_services(True);          
4184     outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
4185     DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
4186   }
4187   else {
4188     DEBUG(0,("No protocol supported !\n"));
4189   }
4190   SSVAL(outbuf,smb_vwv0,choice);
4191   
4192   DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
4193
4194   return(outsize);
4195 }
4196
4197
4198 /****************************************************************************
4199 close all open files for a connection
4200 ****************************************************************************/
4201 static void close_open_files(int cnum)
4202 {
4203   int i;
4204   for (i=0;i<MAX_FNUMS;i++)
4205     if( Files[i].cnum == cnum && Files[i].open) {
4206       if(Files[i].is_directory)
4207         close_directory(i); 
4208       else                  
4209         close_file(i,False); 
4210     }
4211 }
4212
4213
4214
4215 /****************************************************************************
4216 close a cnum
4217 ****************************************************************************/
4218 void close_cnum(int cnum, uint16 vuid)
4219 {
4220   extern int Client;
4221   DirCacheFlush(SNUM(cnum));
4222
4223   unbecome_user();
4224
4225   if (!OPEN_CNUM(cnum))
4226     {
4227       DEBUG(0,("Can't close cnum %d\n",cnum));
4228       return;
4229     }
4230
4231   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4232                           timestring(),
4233                           remote_machine,client_addr(Client),
4234                           lp_servicename(SNUM(cnum))));
4235
4236   yield_connection(cnum,
4237                    lp_servicename(SNUM(cnum)),
4238                    lp_max_connections(SNUM(cnum)));
4239
4240   if (lp_status(SNUM(cnum)))
4241     yield_connection(cnum,"STATUS.",MAXSTATUS);
4242
4243   close_open_files(cnum);
4244   dptr_closecnum(cnum);
4245
4246   /* execute any "postexec = " line */
4247   if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4248     {
4249       pstring cmd;
4250       pstrcpy(cmd,lp_postexec(SNUM(cnum)));
4251       standard_sub(cnum,cmd);
4252       smbrun(cmd,NULL,False);
4253       unbecome_user();
4254     }
4255
4256   unbecome_user();
4257   /* execute any "root postexec = " line */
4258   if (*lp_rootpostexec(SNUM(cnum)))
4259     {
4260       pstring cmd;
4261       pstrcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4262       standard_sub(cnum,cmd);
4263       smbrun(cmd,NULL,False);
4264     }
4265
4266   Connections[cnum].open = False;
4267   num_connections_open--;
4268   if (Connections[cnum].ngroups && Connections[cnum].groups)
4269     {
4270       if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4271         free(Connections[cnum].groups);
4272       free(Connections[cnum].igroups);
4273       Connections[cnum].groups = NULL;
4274       Connections[cnum].igroups = NULL;
4275       Connections[cnum].ngroups = 0;
4276     }
4277
4278   free_namearray(Connections[cnum].veto_list);
4279   free_namearray(Connections[cnum].hide_list);
4280   free_namearray(Connections[cnum].veto_oplock_list);
4281
4282   string_set(&Connections[cnum].user,"");
4283   string_set(&Connections[cnum].dirpath,"");
4284   string_set(&Connections[cnum].connectpath,"");
4285 }
4286
4287
4288
4289 #if DUMP_CORE
4290 /*******************************************************************
4291 prepare to dump a core file - carefully!
4292 ********************************************************************/
4293 static BOOL dump_core(void)
4294 {
4295   char *p;
4296   pstring dname;
4297   pstrcpy(dname,debugf);
4298   if ((p=strrchr(dname,'/'))) *p=0;
4299   pstrcat(dname,"/corefiles");
4300   mkdir(dname,0700);
4301   sys_chown(dname,getuid(),getgid());
4302   chmod(dname,0700);
4303   if (chdir(dname)) return(False);
4304   umask(~(0700));
4305
4306 #ifdef HAVE_GETRLIMIT
4307 #ifdef RLIMIT_CORE
4308   {
4309     struct rlimit rlp;
4310     getrlimit(RLIMIT_CORE, &rlp);
4311     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4312     setrlimit(RLIMIT_CORE, &rlp);
4313     getrlimit(RLIMIT_CORE, &rlp);
4314     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4315   }
4316 #endif
4317 #endif
4318
4319
4320   DEBUG(0,("Dumping core in %s\n",dname));
4321   return(True);
4322 }
4323 #endif
4324
4325 /****************************************************************************
4326 exit the server
4327 ****************************************************************************/
4328 void exit_server(char *reason)
4329 {
4330   static int firsttime=1;
4331   int i;
4332
4333   if (!firsttime) exit(0);
4334   firsttime = 0;
4335
4336   unbecome_user();
4337   DEBUG(2,("Closing connections\n"));
4338   for (i=0;i<MAX_CONNECTIONS;i++)
4339     if (Connections[i].open)
4340       close_cnum(i,(uint16)-1);
4341 #ifdef WITH_DFS
4342   if (dcelogin_atmost_once)
4343     dfs_unlogin();
4344 #endif
4345   if (!reason) {   
4346     int oldlevel = DEBUGLEVEL;
4347     DEBUGLEVEL = 10;
4348     DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4349     if (last_inbuf)
4350       show_msg(last_inbuf);
4351     DEBUGLEVEL = oldlevel;
4352     DEBUG(0,("===============================================================\n"));
4353 #if DUMP_CORE
4354     if (dump_core()) return;
4355 #endif
4356   }    
4357
4358   locking_end();
4359
4360   DEBUG(3,("%s Server exit  (%s)\n",timestring(),reason?reason:""));
4361   exit(0);
4362 }
4363
4364 /****************************************************************************
4365 do some standard substitutions in a string
4366 ****************************************************************************/
4367 void standard_sub(int cnum,char *str)
4368 {
4369   if (VALID_CNUM(cnum)) {
4370     char *p, *s, *home;
4371
4372     for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4373       switch (*(p+1)) {
4374         case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4375                      string_sub(p,"%H",home);
4376                    else
4377                      p += 2;
4378                    break;
4379         case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4380         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4381         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4382         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4383         /* 
4384          * Patch from jkf@soton.ac.uk
4385          * Left the %N (NIS server name) in standard_sub_basic as it
4386          * is a feature for logon servers, hence uses the username.
4387          * The %p (NIS server path) code is here as it is used
4388          * instead of the default "path =" string in [homes] and so
4389          * needs the service name, not the username. 
4390          */
4391         case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
4392         case '\0' : p++; break; /* don't run off the end of the string */
4393         default  : p+=2; break;
4394       }
4395     }
4396   }
4397   standard_sub_basic(str);
4398 }
4399
4400 /*
4401 These flags determine some of the permissions required to do an operation 
4402
4403 Note that I don't set NEED_WRITE on some write operations because they
4404 are used by some brain-dead clients when printing, and I don't want to
4405 force write permissions on print services.
4406 */
4407 #define AS_USER (1<<0)
4408 #define NEED_WRITE (1<<1)
4409 #define TIME_INIT (1<<2)
4410 #define CAN_IPC (1<<3)
4411 #define AS_GUEST (1<<5)
4412 #define QUEUE_IN_OPLOCK (1<<6)
4413
4414 /* 
4415    define a list of possible SMB messages and their corresponding
4416    functions. Any message that has a NULL function is unimplemented -
4417    please feel free to contribute implementations!
4418 */
4419 struct smb_message_struct
4420 {
4421   int code;
4422   char *name;
4423   int (*fn)(char *, char *, int, int);
4424   int flags;
4425 #if PROFILING
4426   unsigned long time;
4427 #endif
4428 }
4429  smb_messages[] = {
4430
4431     /* CORE PROTOCOL */
4432
4433    {SMBnegprot,"SMBnegprot",reply_negprot,0},
4434    {SMBtcon,"SMBtcon",reply_tcon,0},
4435    {SMBtdis,"SMBtdis",reply_tdis,0},
4436    {SMBexit,"SMBexit",reply_exit,0},
4437    {SMBioctl,"SMBioctl",reply_ioctl,0},
4438    {SMBecho,"SMBecho",reply_echo,0},
4439    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4440    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4441    {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4442    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4443    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4444    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4445    {SMBsearch,"SMBsearch",reply_search,AS_USER},
4446    {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
4447
4448    /* note that SMBmknew and SMBcreate are deliberately overloaded */   
4449    {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4450    {SMBmknew,"SMBmknew",reply_mknew,AS_USER}, 
4451
4452    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4453    {SMBread,"SMBread",reply_read,AS_USER},
4454    {SMBwrite,"SMBwrite",reply_write,AS_USER},
4455    {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4456    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4457    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4458    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4459    {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
4460
4461    /* this is a Pathworks specific call, allowing the 
4462       changing of the root path */
4463    {pSETDIR,"pSETDIR",reply_setdir,AS_USER}, 
4464
4465    {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4466    {SMBflush,"SMBflush",reply_flush,AS_USER},
4467    {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
4468    {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
4469    {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4470    {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4471    {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4472    {SMBlock,"SMBlock",reply_lock,AS_USER},
4473    {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4474    
4475    /* CORE+ PROTOCOL FOLLOWS */
4476    
4477    {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4478    {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4479    {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4480    {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4481    {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4482    
4483    /* LANMAN1.0 PROTOCOL FOLLOWS */
4484    
4485    {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4486    {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4487    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4488    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4489    {SMBwritec,"SMBwritec",NULL,AS_USER},
4490    {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4491    {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4492    {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4493    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4494    {SMBioctls,"SMBioctls",NULL,AS_USER},
4495    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4496    {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
4497    
4498    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4499    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
4500    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4501    {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4502    
4503    {SMBffirst,"SMBffirst",reply_search,AS_USER},
4504    {SMBfunique,"SMBfunique",reply_search,AS_USER},
4505    {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4506
4507    /* LANMAN2.0 PROTOCOL FOLLOWS */
4508    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4509    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4510    {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER },
4511    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4512
4513    /* NT PROTOCOL FOLLOWS */
4514    {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
4515    {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
4516    {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
4517    {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
4518
4519    /* messaging routines */
4520    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4521    {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4522    {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4523    {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4524
4525    /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4526    
4527    {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4528    {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4529    {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4530    {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4531  };
4532
4533 /****************************************************************************
4534 return a string containing the function name of a SMB command
4535 ****************************************************************************/
4536 char *smb_fn_name(int type)
4537 {
4538   static char *unknown_name = "SMBunknown";
4539   static int num_smb_messages = 
4540     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4541   int match;
4542
4543   for (match=0;match<num_smb_messages;match++)
4544     if (smb_messages[match].code == type)
4545       break;
4546
4547   if (match == num_smb_messages)
4548     return(unknown_name);
4549
4550   return(smb_messages[match].name);
4551 }
4552
4553
4554 /****************************************************************************
4555 do a switch on the message type, and return the response size
4556 ****************************************************************************/
4557 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4558 {
4559   static int pid= -1;
4560   int outsize = 0;
4561   static int num_smb_messages = 
4562     sizeof(smb_messages) / sizeof(struct smb_message_struct);
4563   int match;
4564
4565 #if PROFILING
4566   struct timeval msg_start_time;
4567   struct timeval msg_end_time;
4568   static unsigned long total_time = 0;
4569
4570   GetTimeOfDay(&msg_start_time);
4571 #endif
4572
4573   if (pid == -1)
4574     pid = getpid();
4575
4576   errno = 0;
4577   last_message = type;
4578
4579   /* make sure this is an SMB packet */
4580   if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4581   {
4582     DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4583     return(-1);
4584   }
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   {
4592     DEBUG(0,("Unknown message type %d!\n",type));
4593     outsize = reply_unknown(inbuf,outbuf);
4594   }
4595   else
4596   {
4597     DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4598
4599     if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
4600     {
4601       /* 
4602        * Queue this message as we are the process of an oplock break.
4603        */
4604
4605       DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
4606              timestring() ));
4607
4608       push_smb_message( inbuf, size);
4609       return -1;
4610     }          
4611
4612     if (smb_messages[match].fn)
4613     {
4614       int cnum = SVAL(inbuf,smb_tid);
4615       int flags = smb_messages[match].flags;
4616       static uint16 last_session_tag = UID_FIELD_INVALID;
4617       /* In share mode security we must ignore the vuid. */
4618       uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
4619       /* Ensure this value is replaced in the incoming packet. */
4620       SSVAL(inbuf,smb_uid,session_tag);
4621
4622       /*
4623        * Ensure the correct username is in sesssetup_user.
4624        * This is a really ugly bugfix for problems with
4625        * multiple session_setup_and_X's being done and
4626        * allowing %U and %G substitutions to work correctly.
4627        * There is a reason this code is done here, don't
4628        * move it unless you know what you're doing... :-).
4629        * JRA.
4630        */
4631       if(session_tag != last_session_tag ) {
4632         user_struct *vuser = NULL;
4633
4634         last_session_tag = session_tag;
4635         if(session_tag != UID_FIELD_INVALID)
4636           vuser = get_valid_user_struct(session_tag);           
4637         if(vuser != NULL)
4638           pstrcpy( sesssetup_user, vuser->requested_name);
4639       }
4640
4641       /* does this protocol need to be run as root? */
4642       if (!(flags & AS_USER))
4643         unbecome_user();
4644
4645       /* does this protocol need to be run as the connected user? */
4646       if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4647         if (flags & AS_GUEST) 
4648           flags &= ~AS_USER;
4649         else
4650           return(ERROR(ERRSRV,ERRinvnid));
4651       }
4652       /* this code is to work around a bug is MS client 3 without
4653          introducing a security hole - it needs to be able to do
4654          print queue checks as guest if it isn't logged in properly */
4655       if (flags & AS_USER)
4656         flags &= ~AS_GUEST;
4657
4658       /* does it need write permission? */
4659       if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4660         return(ERROR(ERRSRV,ERRaccess));
4661
4662       /* ipc services are limited */
4663       if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4664         return(ERROR(ERRSRV,ERRaccess));            
4665
4666       /* load service specific parameters */
4667       if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4668         return(ERROR(ERRSRV,ERRaccess));
4669
4670       /* does this protocol need to be run as guest? */
4671       if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4672         return(ERROR(ERRSRV,ERRaccess));
4673
4674       last_inbuf = inbuf;
4675
4676       outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4677     }
4678     else
4679     {
4680       outsize = reply_unknown(inbuf,outbuf);
4681     }
4682   }
4683
4684 #if PROFILING
4685   GetTimeOfDay(&msg_end_time);
4686   if (!(smb_messages[match].flags & TIME_INIT))
4687   {
4688     smb_messages[match].time = 0;
4689     smb_messages[match].flags |= TIME_INIT;
4690   }
4691   {
4692     unsigned long this_time =     
4693       (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4694       (msg_end_time.tv_usec - msg_start_time.tv_usec);
4695     smb_messages[match].time += this_time;
4696     total_time += this_time;
4697   }
4698   DEBUG(2,("TIME %s  %d usecs   %g pct\n",
4699         smb_fn_name(type),smb_messages[match].time,
4700         (100.0*smb_messages[match].time) / total_time));
4701 #endif
4702
4703   return(outsize);
4704 }
4705
4706
4707 /****************************************************************************
4708   construct a chained reply and add it to the already made reply
4709   **************************************************************************/
4710 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4711 {
4712   static char *orig_inbuf;
4713   static char *orig_outbuf;
4714   int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4715   unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4716   char *inbuf2, *outbuf2;
4717   int outsize2;
4718   char inbuf_saved[smb_wct];
4719   char outbuf_saved[smb_wct];
4720   extern int chain_size;
4721   int wct = CVAL(outbuf,smb_wct);
4722   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4723
4724   /* maybe its not chained */
4725   if (smb_com2 == 0xFF) {
4726     CVAL(outbuf,smb_vwv0) = 0xFF;
4727     return outsize;
4728   }
4729
4730   if (chain_size == 0) {
4731     /* this is the first part of the chain */
4732     orig_inbuf = inbuf;
4733     orig_outbuf = outbuf;
4734   }
4735
4736   /* we need to tell the client where the next part of the reply will be */
4737   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4738   CVAL(outbuf,smb_vwv0) = smb_com2;
4739
4740   /* remember how much the caller added to the chain, only counting stuff
4741      after the parameter words */
4742   chain_size += outsize - smb_wct;
4743
4744   /* work out pointers into the original packets. The
4745      headers on these need to be filled in */
4746   inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4747   outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4748
4749   /* remember the original command type */
4750   smb_com1 = CVAL(orig_inbuf,smb_com);
4751
4752   /* save the data which will be overwritten by the new headers */
4753   memcpy(inbuf_saved,inbuf2,smb_wct);
4754   memcpy(outbuf_saved,outbuf2,smb_wct);
4755
4756   /* give the new packet the same header as the last part of the SMB */
4757   memmove(inbuf2,inbuf,smb_wct);
4758
4759   /* create the in buffer */
4760   CVAL(inbuf2,smb_com) = smb_com2;
4761
4762   /* create the out buffer */
4763   bzero(outbuf2,smb_size);
4764   set_message(outbuf2,0,0,True);
4765   CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4766   
4767   memcpy(outbuf2+4,inbuf2+4,4);
4768   CVAL(outbuf2,smb_rcls) = SMB_SUCCESS;
4769   CVAL(outbuf2,smb_reh) = 0;
4770   CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
4771                                                                   means a reply */
4772   SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4773   SSVAL(outbuf2,smb_err,SMB_SUCCESS);
4774   SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4775   SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4776   SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4777   SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4778
4779   DEBUG(3,("Chained message\n"));
4780   show_msg(inbuf2);
4781
4782   /* process the request */
4783   outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4784                             bufsize-chain_size);
4785
4786   /* copy the new reply and request headers over the old ones, but
4787      preserve the smb_com field */
4788   memmove(orig_outbuf,outbuf2,smb_wct);
4789   CVAL(orig_outbuf,smb_com) = smb_com1;
4790
4791   /* restore the saved data, being careful not to overwrite any
4792    data from the reply header */
4793   memcpy(inbuf2,inbuf_saved,smb_wct);
4794   {
4795     int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4796     if (ofs < 0) ofs = 0;
4797     memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4798   }
4799
4800   return outsize2;
4801 }
4802
4803
4804
4805 /****************************************************************************
4806   construct a reply to the incoming packet
4807 ****************************************************************************/
4808 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4809 {
4810   int type = CVAL(inbuf,smb_com);
4811   int outsize = 0;
4812   int msg_type = CVAL(inbuf,0);
4813   extern int chain_size;
4814
4815   smb_last_time = time(NULL);
4816
4817   chain_size = 0;
4818   chain_fnum = -1;
4819   reset_chain_pnum();
4820
4821   bzero(outbuf,smb_size);
4822
4823   if (msg_type != 0)
4824     return(reply_special(inbuf,outbuf));  
4825
4826   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4827   set_message(outbuf,0,0,True);
4828   
4829   memcpy(outbuf+4,inbuf+4,4);
4830   CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
4831   CVAL(outbuf,smb_reh) = 0;
4832   CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set 
4833                                                              means a reply */
4834   SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4835   SSVAL(outbuf,smb_err,SMB_SUCCESS);
4836   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4837   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4838   SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4839   SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4840
4841   outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4842
4843   outsize += chain_size;
4844
4845   if(outsize > 4)
4846     smb_setlen(outbuf,outsize - 4);
4847   return(outsize);
4848 }
4849
4850 /****************************************************************************
4851   process commands from the client
4852 ****************************************************************************/
4853 static void process(void)
4854 {
4855   extern int Client;
4856
4857   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4858   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4859   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
4860     return;
4861
4862   InBuffer += SMB_ALIGNMENT;
4863   OutBuffer += SMB_ALIGNMENT;
4864
4865 #if PRIME_NMBD
4866   DEBUG(3,("priming nmbd\n"));
4867   {
4868     struct in_addr ip;
4869     ip = *interpret_addr2("localhost");
4870     if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4871     *OutBuffer = 0;
4872     send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4873   }
4874 #endif    
4875
4876   /* re-initialise the timezone */
4877   TimeInit();
4878
4879   while (True)
4880   {
4881     int deadtime = lp_deadtime()*60;
4882     int counter;
4883     int last_keepalive=0;
4884     int service_load_counter = 0;
4885     BOOL got_smb = False;
4886
4887     if (deadtime <= 0)
4888       deadtime = DEFAULT_SMBD_TIMEOUT;
4889
4890 #if USE_READ_PREDICTION
4891     if (lp_readprediction())
4892       do_read_prediction();
4893 #endif
4894
4895     errno = 0;      
4896
4897     for (counter=SMBD_SELECT_LOOP; 
4898           !receive_message_or_smb(Client,oplock_sock,
4899                       InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); 
4900           counter += SMBD_SELECT_LOOP)
4901     {
4902       int i;
4903       time_t t;
4904       BOOL allidle = True;
4905       extern int keepalive;
4906
4907       if (counter > 365 * 3600) /* big number of seconds. */
4908       {
4909         counter = 0;
4910         service_load_counter = 0;
4911       }
4912
4913       if (smb_read_error == READ_EOF) 
4914       {
4915         DEBUG(3,("end of file from client\n"));
4916         return;
4917       }
4918
4919       if (smb_read_error == READ_ERROR) 
4920       {
4921         DEBUG(3,("receive_smb error (%s) exiting\n",
4922                   strerror(errno)));
4923         return;
4924       }
4925
4926       t = time(NULL);
4927
4928       /* become root again if waiting */
4929       unbecome_user();
4930
4931       /* check for smb.conf reload */
4932       if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4933       {
4934         service_load_counter = counter;
4935
4936         /* reload services, if files have changed. */
4937         reload_services(True);
4938       }
4939
4940       /*
4941        * If reload_after_sighup == True then we got a SIGHUP
4942        * and are being asked to reload. Fix from <branko.cibej@hermes.si>
4943        */
4944
4945       if (reload_after_sighup)
4946       {
4947         DEBUG(0,("Reloading services after SIGHUP\n"));
4948         reload_services(False);
4949         reload_after_sighup = False;
4950       }
4951
4952       /* automatic timeout if all connections are closed */      
4953       if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) 
4954       {
4955         DEBUG(2,("%s Closing idle connection\n",timestring()));
4956         return;
4957       }
4958
4959       if (keepalive && (counter-last_keepalive)>keepalive) 
4960       {
4961               struct cli_state *cli = server_client();
4962               if (!send_keepalive(Client)) { 
4963                       DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4964                       return;
4965               }     
4966               /* also send a keepalive to the password server if its still
4967                  connected */
4968               if (cli && cli->initialised)
4969                       send_keepalive(cli->fd);
4970               last_keepalive = counter;
4971       }
4972
4973       /* check for connection timeouts */
4974       for (i=0;i<MAX_CONNECTIONS;i++)
4975         if (Connections[i].open)
4976         {
4977           /* close dirptrs on connections that are idle */
4978           if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4979             dptr_idlecnum(i);
4980
4981           if (Connections[i].num_files_open > 0 ||
4982                      (t-Connections[i].lastused)<deadtime)
4983             allidle = False;
4984         }
4985
4986       if (allidle && num_connections_open>0) 
4987       {
4988         DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4989         return;
4990       }
4991
4992       if(global_machine_pasword_needs_changing)
4993       {
4994         unsigned char trust_passwd_hash[16];
4995         time_t lct;
4996         pstring remote_machine_list;
4997
4998         /*
4999          * We're in domain level security, and the code that
5000          * read the machine password flagged that the machine
5001          * password needs changing.
5002          */
5003
5004         /*
5005          * First, open the machine password file with an exclusive lock.
5006          */
5007
5008         if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
5009           DEBUG(0,("process: unable to open the machine account password file for \
5010 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5011           continue;
5012         }
5013
5014         if(!get_trust_account_password( trust_passwd_hash, &lct)) {
5015           DEBUG(0,("process: unable to read the machine account password for \
5016 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
5017           trust_password_unlock();
5018           continue;
5019         }
5020
5021         /*
5022          * Make sure someone else hasn't already done this.
5023          */
5024
5025         if(t < lct + lp_machine_password_timeout()) {
5026           trust_password_unlock();
5027           global_machine_pasword_needs_changing = False;
5028           continue;
5029         }
5030
5031         pstrcpy(remote_machine_list, lp_passwordserver());
5032
5033         change_trust_account_password( global_myworkgroup, remote_machine_list);
5034         trust_password_unlock();
5035         global_machine_pasword_needs_changing = False;
5036       }
5037     }
5038
5039     if(got_smb)
5040       process_smb(InBuffer, OutBuffer);
5041     else
5042       process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
5043   }
5044 }
5045
5046
5047 /****************************************************************************
5048   initialise connect, service and file structs
5049 ****************************************************************************/
5050 static void init_structs(void )
5051 {
5052   int i;
5053   get_myname(myhostname,NULL);
5054
5055   /*
5056    * Set the machine NETBIOS name if not already
5057    * set from the config file.
5058    */
5059
5060   if (!*global_myname)
5061   {
5062     char *p;
5063     fstrcpy( global_myname, myhostname );
5064     p = strchr( global_myname, '.' );
5065     if (p) 
5066       *p = 0;
5067   }
5068   strupper( global_myname );
5069
5070   for (i=0;i<MAX_CONNECTIONS;i++)
5071     {
5072       Connections[i].open = False;
5073       Connections[i].num_files_open=0;
5074       Connections[i].lastused=0;
5075       Connections[i].used=False;
5076       string_init(&Connections[i].user,"");
5077       string_init(&Connections[i].dirpath,"");
5078       string_init(&Connections[i].connectpath,"");
5079       string_init(&Connections[i].origpath,"");
5080     }
5081
5082   for (i=0;i<MAX_FNUMS;i++)
5083     {
5084       Files[i].open = False;
5085       string_init(&Files[i].name,"");
5086     }
5087
5088   for (i=0;i<MAX_OPEN_FILES;i++)
5089     {
5090       file_fd_struct *fd_ptr = &FileFd[i];
5091       fd_ptr->ref_count = 0;
5092       fd_ptr->dev = (int32)-1;
5093       fd_ptr->inode = (int32)-1;
5094       fd_ptr->fd = -1;
5095       fd_ptr->fd_readonly = -1;
5096       fd_ptr->fd_writeonly = -1;
5097       fd_ptr->real_open_flags = -1;
5098     }
5099
5100   /* for RPC pipes */
5101   init_rpc_pipe_hnd();
5102
5103   /* for LSA handles */
5104   init_lsa_policy_hnd();
5105
5106   init_dptrs();
5107 }
5108
5109 /****************************************************************************
5110 usage on the program
5111 ****************************************************************************/
5112 static void usage(char *pname)
5113 {
5114   DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
5115
5116   printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
5117   printf("Version %s\n",VERSION);
5118   printf("\t-D                    become a daemon\n");
5119   printf("\t-p port               listen on the specified port\n");
5120   printf("\t-d debuglevel         set the debuglevel\n");
5121   printf("\t-l log basename.      Basename for log/debug files\n");
5122   printf("\t-s services file.     Filename of services file\n");
5123   printf("\t-P                    passive only\n");
5124   printf("\t-a                    overwrite log file, don't append\n");
5125   printf("\n");
5126 }
5127
5128
5129 /****************************************************************************
5130   main program
5131 ****************************************************************************/
5132  int main(int argc,char *argv[])
5133 {
5134   extern BOOL append_log;
5135   /* shall I run as a daemon */
5136   BOOL is_daemon = False;
5137   int port = SMB_PORT;
5138   int opt;
5139   extern char *optarg;
5140
5141 #ifdef HAVE_SET_AUTH_PARAMETERS
5142   set_auth_parameters(argc,argv);
5143 #endif
5144
5145 #ifdef HAVE_SETLUID
5146   /* needed for SecureWare on SCO */
5147   setluid(0);
5148 #endif
5149
5150   append_log = True;
5151
5152   TimeInit();
5153
5154   pstrcpy(debugf,SMBLOGFILE);  
5155
5156   pstrcpy(remote_machine, "smb");
5157
5158   setup_logging(argv[0],False);
5159
5160   charset_initialise();
5161
5162   /* make absolutely sure we run as root - to handle cases where people
5163      are crazy enough to have it setuid */
5164 #ifdef HAVE_SETRESUID
5165   setresuid(0,0,0);
5166 #else
5167   setuid(0);
5168   seteuid(0);
5169   setuid(0);
5170   seteuid(0);
5171 #endif
5172
5173   fault_setup((void (*)(void *))exit_server);
5174   CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
5175
5176   /* we want total control over the permissions on created files,
5177      so set our umask to 0 */
5178   umask(0);
5179
5180   GetWd(OriginalDir);
5181
5182   init_uid();
5183
5184   /* this is for people who can't start the program correctly */
5185   while (argc > 1 && (*argv[1] != '-'))
5186     {
5187       argv++;
5188       argc--;
5189     }
5190
5191   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5192     switch (opt)
5193       {
5194       case 'O':
5195         pstrcpy(user_socket_options,optarg);
5196         break;
5197       case 'i':
5198         pstrcpy(scope,optarg);
5199         break;
5200       case 'P':
5201         {
5202           extern BOOL passive;
5203           passive = True;
5204         }
5205         break;  
5206       case 's':
5207         pstrcpy(servicesf,optarg);
5208         break;
5209       case 'l':
5210         pstrcpy(debugf,optarg);
5211         break;
5212       case 'a':
5213         {
5214           extern BOOL append_log;
5215           append_log = !append_log;
5216         }
5217         break;
5218       case 'D':
5219         is_daemon = True;
5220         break;
5221       case 'd':
5222         if (*optarg == 'A')
5223           DEBUGLEVEL = 10000;
5224         else
5225           DEBUGLEVEL = atoi(optarg);
5226         break;
5227       case 'p':
5228         port = atoi(optarg);
5229         break;
5230       case 'h':
5231         usage(argv[0]);
5232         exit(0);
5233         break;
5234       default:
5235         usage(argv[0]);
5236         exit(1);
5237       }
5238
5239   reopen_logs();
5240
5241   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5242   DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5243
5244 #ifdef HAVE_GETRLIMIT
5245 #ifdef RLIMIT_NOFILE
5246   {
5247     struct rlimit rlp;
5248     getrlimit(RLIMIT_NOFILE, &rlp);
5249     /*
5250      * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the
5251      * extra fd we need to read directories, as well as the log files
5252      * and standard handles etc.
5253      */
5254     rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10;
5255     setrlimit(RLIMIT_NOFILE, &rlp);
5256     getrlimit(RLIMIT_NOFILE, &rlp);
5257     DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5258   }
5259 #endif
5260 #endif
5261
5262   
5263   DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5264         getuid(),getgid(),geteuid(),getegid()));
5265
5266   if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5267     {
5268       DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5269       exit(1);
5270     }
5271
5272   init_structs();
5273
5274   if (!reload_services(False))
5275     return(-1); 
5276
5277 #ifdef WITH_SSL
5278   {
5279     extern BOOL sslEnabled;
5280     sslEnabled = lp_ssl_enabled();
5281     if(sslEnabled)
5282       sslutil_init(True);
5283   }
5284 #endif        /* WITH_SSL */
5285
5286   codepage_initialise(lp_client_code_page());
5287
5288   pstrcpy(global_myworkgroup, lp_workgroup());
5289
5290   if(!pdb_generate_machine_sid()) {
5291           DEBUG(0,("ERROR: Samba cannot get a machine SID.\n"));
5292           exit(1);
5293   }
5294
5295   CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
5296
5297   /* Setup the signals that allow the debug log level
5298      to by dynamically changed. */
5299  
5300   /* If we are using the malloc debug code we can't use
5301      SIGUSR1 and SIGUSR2 to do debug level changes. */
5302
5303 #ifndef MEM_MAN
5304 #if defined(SIGUSR1)
5305   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
5306 #endif /* SIGUSR1 */
5307    
5308 #if defined(SIGUSR2)
5309   CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
5310 #endif /* SIGUSR2 */
5311 #endif /* MEM_MAN */
5312
5313   DEBUG(3,("%s loaded services\n",timestring()));
5314
5315   if (!is_daemon && !is_a_socket(0))
5316     {
5317       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5318       is_daemon = True;
5319     }
5320
5321   if (is_daemon)
5322     {
5323       DEBUG(3,("%s becoming a daemon\n",timestring()));
5324       become_daemon();
5325     }
5326
5327   if (!directory_exist(lp_lockdir(), NULL)) {
5328           mkdir(lp_lockdir(), 0755);
5329   }
5330
5331   if (is_daemon) {
5332           pidfile_create("smbd");
5333   }
5334
5335   if (!open_sockets(is_daemon,port))
5336     exit(1);
5337
5338   if (!locking_init(0))
5339     exit(1);
5340
5341   if(!initialize_password_db())
5342     exit(1);
5343
5344   /* possibly reload the services file. */
5345   reload_services(True);
5346
5347   max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5348
5349   if (*lp_rootdir())
5350     {
5351       if (sys_chroot(lp_rootdir()) == 0)
5352         DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5353     }
5354
5355   /* Setup the oplock IPC socket. */
5356   if(!open_oplock_ipc())
5357     exit(1);
5358
5359   process();
5360   close_sockets();
5361
5362   exit_server("normal exit");
5363   return(0);
5364 }