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