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