auto-create the locks directory on startup
[Samba.git] / source / smbd / server.c
blob278087b60aacf5a53d59bd5e2906b8e85733ab24
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
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.
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.
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.
22 #include "includes.h"
23 #include "trans2.h"
25 pstring servicesf = CONFIGFILE;
26 extern pstring debugf;
27 extern pstring sesssetup_user;
28 extern fstring myworkgroup;
30 char *InBuffer = NULL;
31 char *OutBuffer = NULL;
32 char *last_inbuf = NULL;
34 int am_parent = 1;
35 int atexit_set = 0;
37 /* the last message the was processed */
38 int last_message = -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
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;
53 extern int smb_read_error;
55 extern pstring user_socket_options;
57 connection_struct Connections[MAX_CONNECTIONS];
58 files_struct Files[MAX_OPEN_FILES];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd[MAX_OPEN_FILES];
65 int max_file_fd_used = 0;
67 extern int Protocol;
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.
74 int max_send = BUFFER_SIZE;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv = BUFFER_SIZE;
81 /* a fnum to use when chaining */
82 int chain_fnum = -1;
84 /* number of open connections */
85 static int num_connections_open = 0;
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;
93 BOOL global_oplock_break = False;
95 extern fstring remote_machine;
97 extern pstring OriginalDir;
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;
104 extern int extra_time_offset;
106 extern pstring myhostname;
108 static int find_free_connection(int hash);
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)
117 /****************************************************************************
118 when exiting, take the whole family
119 ****************************************************************************/
120 void *dflt_sig(void)
122 exit_server("caught signal");
123 return 0; /* Keep -Wall happy :-) */
125 /****************************************************************************
126 Send a SIGTERM to our process group.
127 *****************************************************************************/
128 void killkids(void)
130 if(am_parent) kill(0,SIGTERM);
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)
150 mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
152 if ( !IS_DOS_READONLY(dosmode) )
153 result |= (S_IWUSR | S_IWGRP | S_IWOTH);
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;
167 if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
168 result |= S_IXGRP;
170 if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
171 result |= S_IXOTH;
173 /* Apply mode mask */
174 result &= lp_create_mode(SNUM(cnum));
175 /* Add in force bits */
176 result |= lp_force_create_mode(SNUM(cnum));
178 return(result);
182 /****************************************************************************
183 change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum,char *path,struct stat *sbuf)
187 int result = 0;
188 extern struct current_user current_user;
190 DEBUG(8,("dos_mode: %d %s\n", cnum, path));
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;
205 if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
206 result |= aARCH;
208 if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
209 result |= aSYSTEM;
211 if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
212 result |= aHIDDEN;
214 if (S_ISDIR(sbuf->st_mode))
215 result = aDIR | (result & aRONLY);
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
224 /* hide files with a name starting with a . */
225 if (lp_hide_dot_files(SNUM(cnum)))
227 char *p = strrchr(path,'/');
228 if (p)
229 p++;
230 else
231 p = path;
233 if (p[0] == '.' && p[1] != '.' && p[1] != 0)
234 result |= aHIDDEN;
237 /* Optimization : Only call is_hidden_path if it's not already
238 hidden. */
239 if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
241 result |= aHIDDEN;
244 DEBUG(8,("dos_mode returning "));
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"));
252 DEBUG(8,("\n"));
254 return(result);
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
262 struct stat st1;
263 int mask=0;
264 int tmp;
265 int unixmode;
267 if (!st) {
268 st = &st1;
269 if (sys_stat(fname,st)) return(-1);
272 if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
274 if (dos_mode(cnum,fname,st) == dosmode) return(0);
276 unixmode = unix_mode(cnum,dosmode);
278 /* preserve the s bits */
279 mask |= (S_ISUID | S_ISGID);
281 /* preserve the t bit */
282 #ifdef S_ISVTX
283 mask |= S_ISVTX;
284 #endif
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;
291 unixmode |= (st->st_mode & mask);
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;
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;
307 return(sys_chmod(fname,unixmode));
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
312 than POSIX.
313 *******************************************************************/
315 int file_utime(int cnum, char *fname, struct utimbuf *times)
317 extern struct current_user current_user;
318 struct stat sb;
319 int ret = -1;
321 errno = 0;
323 if(sys_utime(fname, times) == 0)
324 return 0;
326 if((errno != EPERM) && (errno != EACCES))
327 return -1;
329 if(!lp_dos_filetimes(SNUM(cnum)))
330 return -1;
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).
338 if(sys_stat(fname,&sb) != 0)
339 return -1;
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);
356 return ret;
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
363 BOOL set_filetime(int cnum, char *fname, time_t mtime)
365 struct utimbuf times;
367 if (null_mtime(mtime)) return(True);
369 times.modtime = times.actime = mtime;
371 if (file_utime(cnum, fname, &times)) {
372 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
375 return(True);
378 /****************************************************************************
379 check if two filenames are equal
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL fname_equal(char *name1, char *name2)
385 int l1 = strlen(name1);
386 int l2 = strlen(name2);
388 /* handle filenames ending in a single dot */
389 if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
391 BOOL ret;
392 name1[l1-1] = 0;
393 ret = fname_equal(name1,name2);
394 name1[l1-1] = '.';
395 return(ret);
398 if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
400 BOOL ret;
401 name2[l2-1] = 0;
402 ret = fname_equal(name1,name2);
403 name2[l2-1] = '.';
404 return(ret);
407 /* now normal filename handling */
408 if (case_sensitive)
409 return(strcmp(name1,name2) == 0);
411 return(strequal(name1,name2));
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)
420 pstring tmpname;
422 if (is_8_3(name2, True))
423 return(False);
425 strcpy(tmpname,name2);
426 mangle_name_83(tmpname);
428 return(strequal(name1,tmpname));
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
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)
439 void *cur_dir;
440 char *dname;
441 BOOL mangled;
442 pstring name2;
444 mangled = is_mangled(name);
446 /* handle null paths */
447 if (*path == 0)
448 path = ".";
450 if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
451 strcpy(name, dname);
452 return(True);
455 if (mangled)
456 check_mangled_stack(name);
458 /* open the directory */
459 if (!(cur_dir = OpenDir(cnum, path, True)))
461 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
462 return(False);
465 /* now scan for matching names */
466 while ((dname = ReadDirName(cur_dir)))
468 if (*dname == '.' &&
469 (strequal(dname,".") || strequal(dname,"..")))
470 continue;
472 pstrcpy(name2,dname);
473 if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
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) */
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);
486 CloseDir(cur_dir);
487 return(False);
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.
495 We assume that we have already done a chdir() to the right "root" directory
496 for this service.
498 The function will return False if some part of the name except for the last
499 part cannot be resolved
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.
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)
513 struct stat st;
514 char *start, *end;
515 pstring dirpath;
516 int saved_errno;
518 *dirpath = 0;
519 *bad_path = False;
521 if(saved_last_component)
522 *saved_last_component = 0;
524 /* convert to basic unix format - removing \ chars and cleaning it up */
525 unix_format(name);
526 unix_clean_name(name);
528 /* names must be relative to the root of the service - trim any leading /.
529 also trim trailing /'s */
530 trim_string(name,"/","/");
533 * Ensure saved_last_component is valid even if file exists.
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);
543 if (!case_sensitive &&
544 (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
545 strnorm(name);
547 /* check if it's a printer file */
548 if (Connections[cnum].printer)
550 if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
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));
560 return(True);
563 /* stat the name - if it exists then we are all done! */
564 if (sys_stat(name,&st) == 0)
565 return(True);
567 saved_errno = errno;
569 DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
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);
577 /* now we need to recursively match the name against the real
578 directory structure */
580 start = name;
581 while (strncmp(start,"./",2) == 0)
582 start += 2;
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))
588 /* pinpoint the end of this section of the filename */
589 end = strchr(start, '/');
591 /* chop the name at this point */
592 if (end) *end = 0;
594 if(saved_last_component != 0)
595 strcpy(saved_last_component, end ? end + 1 : start);
597 /* check if the name exists up to this point */
598 if (sys_stat(name, &st) == 0)
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))
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);
610 else
612 pstring rest;
614 *rest = 0;
616 /* remember the rest of the pathname so it can be restored
617 later */
618 if (end) pstrcpy(rest,end+1);
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))
624 if (end)
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.
635 *bad_path = True;
636 return(False);
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);
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);
653 DEBUG(5,("New file %s\n",start));
654 return(True);
657 /* restore the rest of the string */
658 if (end)
660 strcpy(start+strlen(start)+1,rest);
661 end = start + strlen(start);
665 /* add to the dirpath that we have resolved so far */
666 if (*dirpath) strcat(dirpath,"/");
667 strcat(dirpath,start);
669 /* restore the / that we wiped out earlier */
670 if (end) *end = '/';
673 /* the name has been resolved */
674 DEBUG(5,("conversion finished %s\n",name));
675 return(True);
679 /****************************************************************************
680 normalise for DOS usage
681 ****************************************************************************/
682 static void disk_norm(int *bsize,int *dfree,int *dsize)
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 */
695 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
697 *dfree /= 2;
698 *dsize /= 2;
699 *bsize *= 2;
700 if (*bsize > WORDMAX )
702 *bsize = WORDMAX;
703 if (*dsize > WORDMAX)
704 *dsize = WORDMAX;
705 if (*dfree > WORDMAX)
706 *dfree = WORDMAX;
707 break;
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)
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
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
738 /* possibly use system() to get the result */
739 if (df_command && *df_command)
741 int ret;
742 pstring syscmd;
743 pstring outfile;
745 sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
746 sprintf(syscmd,"%s %s",df_command,path);
747 standard_sub_basic(syscmd);
749 ret = smbrun(syscmd,outfile,False);
750 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
753 FILE *f = fopen(outfile,"r");
754 *dsize = 0;
755 *dfree = 0;
756 *bsize = 1024;
757 if (f)
759 fscanf(f,"%d %d %d",dsize,dfree,bsize);
760 fclose(f);
762 else
763 DEBUG(0,("Can't open %s\n",outfile));
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.
774 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
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;
795 #endif
796 return(dfree_retval);
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 */
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));
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 */
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 */
849 #if defined(SCO) || defined(ISC) || defined(MIPS)
850 *bsize = 512;
851 #endif
853 /* handle rediculous bsize values - some OSes are broken */
854 if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
856 disk_norm(bsize,dfree,dsize);
858 if (*bsize < 256)
859 *bsize = 512;
860 if ((*dsize)<1)
862 DEBUG(0,("dfree seems to be broken on your system\n"));
863 *dsize = 20*1024*1024/(*bsize);
864 *dfree = MAX(1,*dfree);
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.
872 if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
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;
893 #endif
894 return(dfree_retval);
895 #endif
899 /****************************************************************************
900 wrap it to get filenames right
901 ****************************************************************************/
902 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
904 return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
909 /****************************************************************************
910 check a filename - possibly caling reducename
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)
918 BOOL ret;
920 errno = 0;
922 if( IS_VETO_PATH(cnum, name))
924 DEBUG(5,("file path name %s vetoed\n",name));
925 return(0);
928 ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
930 /* Check if we are allowing users to follow symlinks */
931 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
932 University of Geneva */
934 #ifdef S_ISLNK
935 if (!lp_symlinks(SNUM(cnum)))
937 struct stat statbuf;
938 if ( (sys_lstat(name,&statbuf) != -1) &&
939 (S_ISLNK(statbuf.st_mode)) )
941 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
942 ret=0;
945 #endif
947 if (!ret)
948 DEBUG(5,("check_name on %s failed\n",name));
950 return(ret);
953 /****************************************************************************
954 check a filename - possibly caling reducename
955 ****************************************************************************/
956 static void check_for_pipe(char *fname)
958 /* special case of pipe opens */
959 char s[10];
960 StrnCpy(s,fname,9);
961 strlower(s);
962 if (strstr(s,"pipe/"))
964 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
965 unix_ERR_class = ERRSRV;
966 unix_ERR_code = ERRaccess;
970 /****************************************************************************
971 fd support routines - attempt to do a sys_open
972 ****************************************************************************/
973 static int fd_attempt_open(char *fname, int flags, int mode)
975 int fd = sys_open(fname,flags,mode);
977 /* Fix for files ending in '.' */
978 if((fd == -1) && (errno == ENOENT) &&
979 (strchr(fname,'.')==NULL))
981 strcat(fname,".");
982 fd = sys_open(fname,flags,mode);
985 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
986 if ((fd == -1) && (errno == ENAMETOOLONG))
988 int max_len;
989 char *p = strrchr(fname, '/');
991 if (p == fname) /* name is "/xxx" */
993 max_len = pathconf("/", _PC_NAME_MAX);
994 p++;
996 else if ((p == NULL) || (p == fname))
998 p = fname;
999 max_len = pathconf(".", _PC_NAME_MAX);
1001 else
1003 *p = '\0';
1004 max_len = pathconf(fname, _PC_NAME_MAX);
1005 *p = '/';
1006 p++;
1008 if (strlen(p) > max_len)
1010 char tmp = p[max_len];
1012 p[max_len] = '\0';
1013 if ((fd = sys_open(fname,flags,mode)) == -1)
1014 p[max_len] = tmp;
1017 #endif
1018 return fd;
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)
1027 int i;
1028 file_fd_struct *fd_ptr;
1030 if(sbuf == 0)
1031 return 0;
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;
1045 return 0;
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()
1054 int i;
1055 file_fd_struct *fd_ptr;
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;
1076 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1077 n"));
1078 return 0;
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)
1087 int fd = sys_open( fname, O_RDWR, mode);
1089 if(fd == -1)
1090 return;
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;
1097 fd_ptr->fd = fd;
1098 fd_ptr->real_open_flags = O_RDWR;
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)
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;
1129 return fd_ptr->ref_count;
1132 /****************************************************************************
1133 open a file
1134 ****************************************************************************/
1135 static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
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];
1143 fsp->open = False;
1144 fsp->fd_ptr = 0;
1145 fsp->granted_oplock = False;
1146 errno = EPERM;
1148 pstrcpy(fname,fname1);
1150 /* check permissions */
1151 if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
1153 DEBUG(3,("Permission denied opening %s\n",fname));
1154 check_for_pipe(fname);
1155 return;
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;
1164 if (flags == O_WRONLY)
1165 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1169 * Ensure we have a valid struct stat so we can search the
1170 * open fd table.
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)));
1178 check_for_pipe(fname);
1179 return;
1181 sbuf = 0;
1182 } else {
1183 sbuf = &statbuf;
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).
1192 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
1194 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
1196 /* File was already open. */
1197 if((flags & O_CREAT) && (flags & O_EXCL)) {
1198 fd_ptr->ref_count--;
1199 errno = EEXIST;
1200 return;
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.
1208 if(fd_ptr->real_open_flags != O_RDWR)
1209 fd_attempt_reopen(fname, mode, fd_ptr);
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.
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;
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;
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.
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);
1247 * On some systems opening a file for R/W access on a read only
1248 * filesystems sets errno to EROFS.
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;
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;
1284 if (fd_ptr->fd < 0)
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;
1294 if (fd_ptr->fd >= 0)
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;
1306 sbuf = &statbuf;
1308 /* Set the correct entries in fd_ptr. */
1309 fd_ptr->dev = (uint32)sbuf->st_dev;
1310 fd_ptr->inode = (uint32)sbuf->st_ino;
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;
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
1340 if (fsp->print_file && POSTSCRIPT(cnum) &&
1341 fsp->can_write)
1343 DEBUG(3,("Writing postscript line\n"));
1344 write_file(fnum,"%!\n",3);
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));
1354 #if USE_MMAP
1355 /* mmap it if read-only */
1356 if (!fsp->can_write)
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);
1362 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
1364 DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
1365 fsp->mmap_ptr = NULL;
1368 #endif
1371 /*******************************************************************
1372 sync a file
1373 ********************************************************************/
1374 void sync_file(int fnum)
1376 #ifndef NO_FSYNC
1377 fsync(Files[fnum].fd_ptr->fd);
1378 #endif
1381 /****************************************************************************
1382 run a file if it is a magic script
1383 ****************************************************************************/
1384 static void check_magic(int fnum,int cnum)
1386 if (!*lp_magicscript(SNUM(cnum)))
1387 return;
1389 DEBUG(5,("checking magic for %s\n",Files[fnum].name));
1392 char *p;
1393 if (!(p = strrchr(Files[fnum].name,'/')))
1394 p = Files[fnum].name;
1395 else
1396 p++;
1398 if (!strequal(lp_magicscript(SNUM(cnum)),p))
1399 return;
1403 int ret;
1404 pstring magic_output;
1405 pstring fname;
1406 pstrcpy(fname,Files[fnum].name);
1408 if (*lp_magicoutput(SNUM(cnum)))
1409 pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
1410 else
1411 sprintf(magic_output,"%s.out",fname);
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);
1421 /****************************************************************************
1422 close a file - possibly invalidating the read prediction
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)
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;
1437 #if USE_READ_PREDICTION
1438 invalidate_read_prediction(fs_p->fd_ptr->fd);
1439 #endif
1441 fs_p->open = False;
1442 Connections[cnum].num_files_open--;
1443 if(fs_p->wbmpx_ptr)
1445 free((char *)fs_p->wbmpx_ptr);
1446 fs_p->wbmpx_ptr = NULL;
1449 #if USE_MMAP
1450 if(fs_p->mmap_ptr)
1452 munmap(fs_p->mmap_ptr,fs_p->mmap_size);
1453 fs_p->mmap_ptr = NULL;
1455 #endif
1457 if (lp_share_modes(SNUM(cnum)))
1459 lock_share_entry( cnum, dev, inode, &token);
1460 del_share_mode(token, fnum);
1463 fd_attempt_close(fs_p->fd_ptr);
1465 if (lp_share_modes(SNUM(cnum)))
1466 unlock_share_entry( cnum, dev, inode, token);
1468 /* NT uses smbclose to start a print - weird */
1469 if (normal_close && fs_p->print_file)
1470 print_file(fnum);
1472 /* check for magic scripts */
1473 if (normal_close)
1474 check_magic(fnum,cnum);
1476 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1477 timestring(),Connections[cnum].user,fs_p->name,
1478 Connections[cnum].num_files_open));
1481 enum {AFAIL,AREAD,AWRITE,AALL};
1483 /*******************************************************************
1484 reproduce the share mode access table
1485 ********************************************************************/
1486 static int access_table(int new_deny,int old_deny,int old_mode,
1487 int share_pid,char *fname)
1489 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
1491 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
1492 int pid = getpid();
1493 if (old_deny == new_deny && share_pid == pid)
1494 return(AALL);
1496 if (old_mode == 0) return(AREAD);
1498 /* the new smbpub.zip spec says that if the file extension is
1499 .com, .dll, .exe or .sym then allow the open. I will force
1500 it to read-only as this seems sensible although the spec is
1501 a little unclear on this. */
1502 if ((fname = strrchr(fname,'.'))) {
1503 if (strequal(fname,".com") ||
1504 strequal(fname,".dll") ||
1505 strequal(fname,".exe") ||
1506 strequal(fname,".sym"))
1507 return(AREAD);
1510 return(AFAIL);
1513 switch (new_deny)
1515 case DENY_WRITE:
1516 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
1517 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
1518 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
1519 return(AFAIL);
1520 case DENY_READ:
1521 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
1522 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
1523 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
1524 return(AFAIL);
1525 case DENY_NONE:
1526 if (old_deny==DENY_WRITE) return(AREAD);
1527 if (old_deny==DENY_READ) return(AWRITE);
1528 if (old_deny==DENY_NONE) return(AALL);
1529 return(AFAIL);
1531 return(AFAIL);
1534 /*******************************************************************
1535 check if the share mode on a file allows it to be deleted or unlinked
1536 return True if sharing doesn't prevent the operation
1537 ********************************************************************/
1538 BOOL check_file_sharing(int cnum,char *fname)
1540 int i;
1541 int ret = False;
1542 share_mode_entry *old_shares = 0;
1543 int num_share_modes;
1544 struct stat sbuf;
1545 int token;
1546 int pid = getpid();
1547 uint32 dev, inode;
1549 if(!lp_share_modes(SNUM(cnum)))
1550 return True;
1552 if (stat(fname,&sbuf) == -1) return(True);
1554 dev = (uint32)sbuf.st_dev;
1555 inode = (uint32)sbuf.st_ino;
1557 lock_share_entry(cnum, dev, inode, &token);
1558 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1561 * Check if the share modes will give us access.
1564 if(num_share_modes != 0)
1566 BOOL broke_oplock;
1571 broke_oplock = False;
1572 for(i = 0; i < num_share_modes; i++)
1574 share_mode_entry *share_entry = &old_shares[i];
1577 * Break oplocks before checking share modes. See comment in
1578 * open_file_shared for details.
1579 * Check if someone has an oplock on this file. If so we must
1580 * break it before continuing.
1582 if(share_entry->op_type & BATCH_OPLOCK)
1585 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1586 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1588 /* Oplock break.... */
1589 unlock_share_entry(cnum, dev, inode, token);
1590 if(request_oplock_break(share_entry, dev, inode) == False)
1592 free((char *)old_shares);
1593 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1594 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1595 return False;
1597 lock_share_entry(cnum, dev, inode, &token);
1598 broke_oplock = True;
1599 break;
1602 /* someone else has a share lock on it, check to see
1603 if we can too */
1604 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1605 goto free_and_exit;
1607 } /* end for */
1609 if(broke_oplock)
1611 free((char *)old_shares);
1612 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1614 } while(broke_oplock);
1617 /* XXXX exactly what share mode combinations should be allowed for
1618 deleting/renaming? */
1619 /* If we got here then either there were no share modes or
1620 all share modes were DENY_DOS and the pid == getpid() */
1621 ret = True;
1623 free_and_exit:
1625 unlock_share_entry(cnum, dev, inode, token);
1626 if(old_shares != NULL)
1627 free((char *)old_shares);
1628 return(ret);
1631 /****************************************************************************
1632 C. Hoch 11/22/95
1633 Helper for open_file_shared.
1634 Truncate a file after checking locking; close file if locked.
1635 **************************************************************************/
1636 static void truncate_unless_locked(int fnum, int cnum, int token,
1637 BOOL *share_locked)
1639 if (Files[fnum].can_write){
1640 if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
1641 /* If share modes are in force for this connection we
1642 have the share entry locked. Unlock it before closing. */
1643 if (*share_locked && lp_share_modes(SNUM(cnum)))
1644 unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
1645 Files[fnum].fd_ptr->inode, token);
1646 close_file(fnum,False);
1647 /* Share mode no longer locked. */
1648 *share_locked = False;
1649 errno = EACCES;
1650 unix_ERR_class = ERRDOS;
1651 unix_ERR_code = ERRlock;
1653 else
1654 ftruncate(Files[fnum].fd_ptr->fd,0);
1658 /****************************************************************************
1659 check if we can open a file with a share mode
1660 ****************************************************************************/
1661 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1662 BOOL fcbopen, int *flags)
1664 int old_open_mode = share->share_mode &0xF;
1665 int old_deny_mode = (share->share_mode >>4)&7;
1667 if (old_deny_mode > 4 || old_open_mode > 2)
1669 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1670 deny_mode,old_deny_mode,old_open_mode,fname));
1671 return False;
1675 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1676 share->pid,fname);
1678 if ((access_allowed == AFAIL) ||
1679 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1680 (access_allowed == AREAD && *flags == O_WRONLY) ||
1681 (access_allowed == AWRITE && *flags == O_RDONLY))
1683 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1684 deny_mode,old_deny_mode,old_open_mode,
1685 share->pid,fname, access_allowed));
1686 return False;
1689 if (access_allowed == AREAD)
1690 *flags = O_RDONLY;
1692 if (access_allowed == AWRITE)
1693 *flags = O_WRONLY;
1696 return True;
1699 /****************************************************************************
1700 open a file with a share mode
1701 ****************************************************************************/
1702 void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
1703 int mode,int oplock_request, int *Access,int *action)
1705 files_struct *fs_p = &Files[fnum];
1706 int flags=0;
1707 int flags2=0;
1708 int deny_mode = (share_mode>>4)&7;
1709 struct stat sbuf;
1710 BOOL file_existed = file_exist(fname,&sbuf);
1711 BOOL share_locked = False;
1712 BOOL fcbopen = False;
1713 int token;
1714 uint32 dev = 0;
1715 uint32 inode = 0;
1716 int num_share_modes = 0;
1718 fs_p->open = False;
1719 fs_p->fd_ptr = 0;
1721 /* this is for OS/2 EAs - try and say we don't support them */
1722 if (strstr(fname,".+,;=[]."))
1724 unix_ERR_class = ERRDOS;
1725 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1726 #ifdef OS2_WPS_FIX
1727 unix_ERR_code = ERRcannotopen;
1728 #else /* OS2_WPS_FIX */
1729 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
1730 #endif /* OS2_WPS_FIX */
1732 return;
1735 if ((ofun & 0x3) == 0 && file_existed)
1737 errno = EEXIST;
1738 return;
1741 if (ofun & 0x10)
1742 flags2 |= O_CREAT;
1743 if ((ofun & 0x3) == 2)
1744 flags2 |= O_TRUNC;
1746 /* note that we ignore the append flag as
1747 append does not mean the same thing under dos and unix */
1749 switch (share_mode&0xF)
1751 case 1:
1752 flags = O_WRONLY;
1753 break;
1754 case 0xF:
1755 fcbopen = True;
1756 flags = O_RDWR;
1757 break;
1758 case 2:
1759 flags = O_RDWR;
1760 break;
1761 default:
1762 flags = O_RDONLY;
1763 break;
1766 if (flags != O_RDONLY && file_existed &&
1767 (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
1769 if (!fcbopen)
1771 errno = EACCES;
1772 return;
1774 flags = O_RDONLY;
1777 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
1779 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1780 errno = EINVAL;
1781 return;
1784 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
1786 if (lp_share_modes(SNUM(cnum)))
1788 int i;
1789 share_mode_entry *old_shares = 0;
1791 if (file_existed)
1793 dev = (uint32)sbuf.st_dev;
1794 inode = (uint32)sbuf.st_ino;
1795 lock_share_entry(cnum, dev, inode, &token);
1796 share_locked = True;
1797 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1801 * Check if the share modes will give us access.
1804 if(share_locked && (num_share_modes != 0))
1806 BOOL broke_oplock;
1811 broke_oplock = False;
1812 for(i = 0; i < num_share_modes; i++)
1814 share_mode_entry *share_entry = &old_shares[i];
1817 * By observation of NetBench, oplocks are broken *before* share
1818 * modes are checked. This allows a file to be closed by the client
1819 * if the share mode would deny access and the client has an oplock.
1820 * Check if someone has an oplock on this file. If so we must break
1821 * it before continuing.
1823 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
1826 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1827 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1829 /* Oplock break.... */
1830 unlock_share_entry(cnum, dev, inode, token);
1831 if(request_oplock_break(share_entry, dev, inode) == False)
1833 free((char *)old_shares);
1834 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1835 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1836 errno = EACCES;
1837 unix_ERR_class = ERRDOS;
1838 unix_ERR_code = ERRbadshare;
1839 return;
1841 lock_share_entry(cnum, dev, inode, &token);
1842 broke_oplock = True;
1843 break;
1846 /* someone else has a share lock on it, check to see
1847 if we can too */
1848 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
1850 free((char *)old_shares);
1851 unlock_share_entry(cnum, dev, inode, token);
1852 errno = EACCES;
1853 unix_ERR_class = ERRDOS;
1854 unix_ERR_code = ERRbadshare;
1855 return;
1858 } /* end for */
1860 if(broke_oplock)
1862 free((char *)old_shares);
1863 num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
1865 } while(broke_oplock);
1868 if(old_shares != 0)
1869 free((char *)old_shares);
1872 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1873 flags,flags2,mode));
1875 open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
1876 if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
1878 flags = O_RDONLY;
1879 open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
1882 if (fs_p->open)
1884 int open_mode=0;
1886 if((share_locked == False) && lp_share_modes(SNUM(cnum)))
1888 /* We created the file - thus we must now lock the share entry before creating it. */
1889 dev = fs_p->fd_ptr->dev;
1890 inode = fs_p->fd_ptr->inode;
1891 lock_share_entry(cnum, dev, inode, &token);
1892 share_locked = True;
1895 switch (flags)
1897 case O_RDONLY:
1898 open_mode = 0;
1899 break;
1900 case O_RDWR:
1901 open_mode = 2;
1902 break;
1903 case O_WRONLY:
1904 open_mode = 1;
1905 break;
1908 fs_p->share_mode = (deny_mode<<4) | open_mode;
1910 if (Access)
1911 (*Access) = open_mode;
1913 if (action)
1915 if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
1916 if (!file_existed) *action = 2;
1917 if (file_existed && (flags2 & O_TRUNC)) *action = 3;
1919 /* We must create the share mode entry before truncate as
1920 truncate can fail due to locking and have to close the
1921 file (which expects the share_mode_entry to be there).
1923 if (lp_share_modes(SNUM(cnum)))
1925 uint16 port = 0;
1926 /* JRA. Currently this only services Exlcusive and batch
1927 oplocks (no other opens on this file). This needs to
1928 be extended to level II oplocks (multiple reader
1929 oplocks). */
1931 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
1933 fs_p->granted_oplock = True;
1934 global_oplocks_open++;
1935 port = oplock_port;
1937 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1938 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
1941 else
1943 port = 0;
1944 oplock_request = 0;
1946 set_share_mode(token, fnum, port, oplock_request);
1949 if ((flags2&O_TRUNC) && file_existed)
1950 truncate_unless_locked(fnum,cnum,token,&share_locked);
1953 if (share_locked && lp_share_modes(SNUM(cnum)))
1954 unlock_share_entry( cnum, dev, inode, token);
1957 /****************************************************************************
1958 seek a file. Try to avoid the seek if possible
1959 ****************************************************************************/
1960 int seek_file(int fnum,uint32 pos)
1962 uint32 offset = 0;
1963 if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
1964 offset = 3;
1966 Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
1967 - offset);
1968 return(Files[fnum].pos);
1971 /****************************************************************************
1972 read from a file
1973 ****************************************************************************/
1974 int read_file(int fnum,char *data,uint32 pos,int n)
1976 int ret=0,readret;
1978 #if USE_READ_PREDICTION
1979 if (!Files[fnum].can_write)
1981 ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
1983 data += ret;
1984 n -= ret;
1985 pos += ret;
1987 #endif
1989 #if USE_MMAP
1990 if (Files[fnum].mmap_ptr)
1992 int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
1993 if (num > 0)
1995 memcpy(data,Files[fnum].mmap_ptr+pos,num);
1996 data += num;
1997 pos += num;
1998 n -= num;
1999 ret += num;
2002 #endif
2004 if (n <= 0)
2005 return(ret);
2007 if (seek_file(fnum,pos) != pos)
2009 DEBUG(3,("Failed to seek to %d\n",pos));
2010 return(ret);
2013 if (n > 0) {
2014 readret = read(Files[fnum].fd_ptr->fd,data,n);
2015 if (readret > 0) ret += readret;
2018 return(ret);
2022 /****************************************************************************
2023 write to a file
2024 ****************************************************************************/
2025 int write_file(int fnum,char *data,int n)
2027 if (!Files[fnum].can_write) {
2028 errno = EPERM;
2029 return(0);
2032 if (!Files[fnum].modified) {
2033 struct stat st;
2034 Files[fnum].modified = True;
2035 if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
2036 int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
2037 if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
2038 dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
2043 return(write_data(Files[fnum].fd_ptr->fd,data,n));
2047 /****************************************************************************
2048 load parameters specific to a connection/service
2049 ****************************************************************************/
2050 BOOL become_service(int cnum,BOOL do_chdir)
2052 extern char magic_char;
2053 static int last_cnum = -1;
2054 int snum;
2056 if (!OPEN_CNUM(cnum))
2058 last_cnum = -1;
2059 return(False);
2062 Connections[cnum].lastused = smb_last_time;
2064 snum = SNUM(cnum);
2066 if (do_chdir &&
2067 ChDir(Connections[cnum].connectpath) != 0 &&
2068 ChDir(Connections[cnum].origpath) != 0)
2070 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2071 Connections[cnum].connectpath,cnum));
2072 return(False);
2075 if (cnum == last_cnum)
2076 return(True);
2078 last_cnum = cnum;
2080 case_default = lp_defaultcase(snum);
2081 case_preserve = lp_preservecase(snum);
2082 short_case_preserve = lp_shortpreservecase(snum);
2083 case_mangle = lp_casemangle(snum);
2084 case_sensitive = lp_casesensitive(snum);
2085 magic_char = lp_magicchar(snum);
2086 use_mangled_map = (*lp_mangled_map(snum) ? True:False);
2087 return(True);
2091 /****************************************************************************
2092 find a service entry
2093 ****************************************************************************/
2094 int find_service(char *service)
2096 int iService;
2098 string_sub(service,"\\","/");
2100 iService = lp_servicenumber(service);
2102 /* now handle the special case of a home directory */
2103 if (iService < 0)
2105 char *phome_dir = get_home_dir(service);
2106 DEBUG(3,("checking for home directory %s gave %s\n",service,
2107 phome_dir?phome_dir:"(NULL)"));
2108 if (phome_dir)
2110 int iHomeService;
2111 if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
2113 lp_add_home(service,iHomeService,phome_dir);
2114 iService = lp_servicenumber(service);
2119 /* If we still don't have a service, attempt to add it as a printer. */
2120 if (iService < 0)
2122 int iPrinterService;
2124 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
2126 char *pszTemp;
2128 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
2129 pszTemp = PRINTCAP;
2130 if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
2132 DEBUG(3,("%s is a valid printer name\n", service));
2133 DEBUG(3,("adding %s as a printer service\n", service));
2134 lp_add_printer(service,iPrinterService);
2135 iService = lp_servicenumber(service);
2136 if (iService < 0)
2137 DEBUG(0,("failed to add %s as a printer service!\n", service));
2139 else
2140 DEBUG(3,("%s is not a valid printer name\n", service));
2144 /* just possibly it's a default service? */
2145 if (iService < 0)
2147 char *defservice = lp_defaultservice();
2148 if (defservice && *defservice && !strequal(defservice,service)) {
2149 iService = find_service(defservice);
2150 if (iService >= 0) {
2151 string_sub(service,"_","/");
2152 iService = lp_add_service(service,iService);
2157 if (iService >= 0)
2158 if (!VALID_SNUM(iService))
2160 DEBUG(0,("Invalid snum %d for %s\n",iService,service));
2161 iService = -1;
2164 if (iService < 0)
2165 DEBUG(3,("find_service() failed to find service %s\n", service));
2167 return (iService);
2171 /****************************************************************************
2172 create an error packet from a cached error.
2173 ****************************************************************************/
2174 int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
2176 write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
2178 int32 eclass = wbmpx->wr_errclass;
2179 int32 err = wbmpx->wr_error;
2181 /* We can now delete the auxiliary struct */
2182 free((char *)wbmpx);
2183 Files[fnum].wbmpx_ptr = NULL;
2184 return error_packet(inbuf,outbuf,eclass,err,line);
2188 struct
2190 int unixerror;
2191 int smbclass;
2192 int smbcode;
2193 } unix_smb_errmap[] =
2195 {EPERM,ERRDOS,ERRnoaccess},
2196 {EACCES,ERRDOS,ERRnoaccess},
2197 {ENOENT,ERRDOS,ERRbadfile},
2198 {ENOTDIR,ERRDOS,ERRbadpath},
2199 {EIO,ERRHRD,ERRgeneral},
2200 {EBADF,ERRSRV,ERRsrverror},
2201 {EINVAL,ERRSRV,ERRsrverror},
2202 {EEXIST,ERRDOS,ERRfilexists},
2203 {ENFILE,ERRDOS,ERRnofids},
2204 {EMFILE,ERRDOS,ERRnofids},
2205 {ENOSPC,ERRHRD,ERRdiskfull},
2206 #ifdef EDQUOT
2207 {EDQUOT,ERRHRD,ERRdiskfull},
2208 #endif
2209 #ifdef ENOTEMPTY
2210 {ENOTEMPTY,ERRDOS,ERRnoaccess},
2211 #endif
2212 #ifdef EXDEV
2213 {EXDEV,ERRDOS,ERRdiffdevice},
2214 #endif
2215 {EROFS,ERRHRD,ERRnowrite},
2216 {0,0,0}
2219 /****************************************************************************
2220 create an error packet from errno
2221 ****************************************************************************/
2222 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
2224 int eclass=def_class;
2225 int ecode=def_code;
2226 int i=0;
2228 if (unix_ERR_class != SUCCESS)
2230 eclass = unix_ERR_class;
2231 ecode = unix_ERR_code;
2232 unix_ERR_class = SUCCESS;
2233 unix_ERR_code = 0;
2235 else
2237 while (unix_smb_errmap[i].smbclass != 0)
2239 if (unix_smb_errmap[i].unixerror == errno)
2241 eclass = unix_smb_errmap[i].smbclass;
2242 ecode = unix_smb_errmap[i].smbcode;
2243 break;
2245 i++;
2249 return(error_packet(inbuf,outbuf,eclass,ecode,line));
2253 /****************************************************************************
2254 create an error packet. Normally called using the ERROR() macro
2255 ****************************************************************************/
2256 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
2258 int outsize = set_message(outbuf,0,0,True);
2259 int cmd;
2260 cmd = CVAL(inbuf,smb_com);
2262 CVAL(outbuf,smb_rcls) = error_class;
2263 SSVAL(outbuf,smb_err,error_code);
2265 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2266 timestring(),
2267 line,
2268 (int)CVAL(inbuf,smb_com),
2269 smb_fn_name(CVAL(inbuf,smb_com)),
2270 error_class,
2271 error_code));
2273 if (errno != 0)
2274 DEBUG(3,("error string = %s\n",strerror(errno)));
2276 return(outsize);
2280 #ifndef SIGCLD_IGNORE
2281 /****************************************************************************
2282 this prevents zombie child processes
2283 ****************************************************************************/
2284 static int sig_cld()
2286 static int depth = 0;
2287 if (depth != 0)
2289 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2290 depth=0;
2291 return(0);
2293 depth++;
2295 BlockSignals(True,SIGCLD);
2296 DEBUG(5,("got SIGCLD\n"));
2298 #ifdef USE_WAITPID
2299 while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
2300 #endif
2302 /* Stop zombies */
2303 /* Stevens, Adv. Unix Prog. says that on system V you must call
2304 wait before reinstalling the signal handler, because the kernel
2305 calls the handler from within the signal-call when there is a
2306 child that has exited. This would lead to an infinite recursion
2307 if done vice versa. */
2309 #ifndef DONT_REINSTALL_SIG
2310 #ifdef SIGCLD_IGNORE
2311 signal(SIGCLD, SIG_IGN);
2312 #else
2313 signal(SIGCLD, SIGNAL_CAST sig_cld);
2314 #endif
2315 #endif
2317 #ifndef USE_WAITPID
2318 while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
2319 #endif
2320 depth--;
2321 BlockSignals(False,SIGCLD);
2322 return 0;
2324 #endif
2326 /****************************************************************************
2327 this is called when the client exits abruptly
2328 **************************************************************************/
2329 static int sig_pipe()
2331 struct cli_state *cli;
2332 BlockSignals(True,SIGPIPE);
2334 if ((cli = server_client()) && cli->initialised) {
2335 DEBUG(3,("lost connection to password server\n"));
2336 cli_shutdown(cli);
2337 #ifndef DONT_REINSTALL_SIG
2338 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2339 #endif
2340 BlockSignals(False,SIGPIPE);
2341 return 0;
2344 exit_server("Got sigpipe\n");
2345 return(0);
2348 /****************************************************************************
2349 open the socket communication
2350 ****************************************************************************/
2351 static BOOL open_sockets(BOOL is_daemon,int port)
2353 extern int Client;
2355 if (is_daemon)
2357 int num_interfaces = iface_count();
2358 int fd_listenset[FD_SETSIZE];
2359 fd_set listen_set;
2360 int s;
2361 int i;
2363 /* Stop zombies */
2364 #ifdef SIGCLD_IGNORE
2365 signal(SIGCLD, SIG_IGN);
2366 #else
2367 signal(SIGCLD, SIGNAL_CAST sig_cld);
2368 #endif
2370 if(atexit_set == 0)
2371 atexit(killkids);
2373 FD_ZERO(&listen_set);
2375 if(lp_interfaces() && lp_bind_interfaces_only())
2377 /* We have been given an interfaces line, and been
2378 told to only bind to those interfaces. Create a
2379 socket per interface and bind to only these.
2382 if(num_interfaces > FD_SETSIZE)
2384 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2385 max can be %d\n", num_interfaces, FD_SETSIZE));
2386 return False;
2389 /* Now open a listen socket for each of the interfaces. */
2390 for(i = 0; i < num_interfaces; i++)
2392 struct in_addr *ifip = iface_n_ip(i);
2394 if(ifip == NULL)
2396 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
2397 continue;
2399 s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr);
2400 if(s == -1)
2401 return False;
2402 /* ready to listen */
2403 if (listen(s, 5) == -1)
2405 DEBUG(0,("listen: %s\n",strerror(errno)));
2406 close(s);
2407 return False;
2409 FD_SET(s,&listen_set);
2412 else
2414 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2415 num_interfaces = 1;
2417 /* open an incoming socket */
2418 s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
2419 if (s == -1)
2420 return(False);
2422 /* ready to listen */
2423 if (listen(s, 5) == -1)
2425 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno)));
2426 close(s);
2427 return False;
2430 fd_listenset[0] = s;
2431 FD_SET(s,&listen_set);
2434 /* now accept incoming connections - forking a new process
2435 for each incoming connection */
2436 DEBUG(2,("waiting for a connection\n"));
2437 while (1)
2439 fd_set lfds;
2440 int num;
2442 memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set));
2444 num = sys_select(&lfds,NULL);
2446 if (num == -1 && errno == EINTR)
2447 continue;
2449 /* Find the sockets that are read-ready - accept on these. */
2450 for( ; num > 0; num--)
2452 struct sockaddr addr;
2453 int in_addrlen = sizeof(addr);
2455 s = -1;
2456 for(i = 0; i < num_interfaces; i++)
2458 if(FD_ISSET(fd_listenset[i],&lfds))
2460 s = fd_listenset[i];
2461 /* Clear this so we don't look at it again. */
2462 FD_CLR(fd_listenset[i],&lfds);
2463 break;
2467 Client = accept(s,&addr,&in_addrlen);
2469 if (Client == -1 && errno == EINTR)
2470 continue;
2472 if (Client == -1)
2474 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno)));
2475 continue;
2478 #ifdef NO_FORK_DEBUG
2479 #ifndef NO_SIGNAL_TEST
2480 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2481 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2482 #endif /* NO_SIGNAL_TEST */
2483 return True;
2484 #else /* NO_FORK_DEBUG */
2485 if (Client != -1 && fork()==0)
2487 /* Child code ... */
2489 #ifndef NO_SIGNAL_TEST
2490 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2491 signal(SIGCLD, SIGNAL_CAST SIG_DFL);
2492 #endif /* NO_SIGNAL_TEST */
2493 /* close the listening socket(s) */
2494 for(i = 0; i < num_interfaces; i++)
2495 close(fd_listenset[i]);
2497 /* close our standard file descriptors */
2498 close_low_fds();
2499 am_parent = 0;
2501 set_socket_options(Client,"SO_KEEPALIVE");
2502 set_socket_options(Client,user_socket_options);
2504 /* Reset global variables in util.c so that
2505 client substitutions will be done correctly
2506 in the process.
2508 reset_globals_after_fork();
2509 return True;
2511 close(Client); /* The parent doesn't need this socket */
2512 #endif /NO_FORK_DEBUG */
2513 } /* end for num */
2514 } /* end while 1 */
2515 } /* end if is_daemon */
2516 else
2518 /* Started from inetd. fd 0 is the socket. */
2519 /* We will abort gracefully when the client or remote system
2520 goes away */
2521 #ifndef NO_SIGNAL_TEST
2522 signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2523 #endif
2524 Client = dup(0);
2526 /* close our standard file descriptors */
2527 close_low_fds();
2529 set_socket_options(Client,"SO_KEEPALIVE");
2530 set_socket_options(Client,user_socket_options);
2533 return True;
2536 /****************************************************************************
2537 process an smb from the client - split out from the process() code so
2538 it can be used by the oplock break code.
2539 ****************************************************************************/
2541 static void process_smb(char *inbuf, char *outbuf)
2543 extern int Client;
2544 static int trans_num;
2545 int msg_type = CVAL(inbuf,0);
2546 int32 len = smb_len(inbuf);
2547 int nread = len + 4;
2549 if (trans_num == 0) {
2550 /* on the first packet, check the global hosts allow/ hosts
2551 deny parameters before doing any parsing of the packet
2552 passed to us by the client. This prevents attacks on our
2553 parsing code from hosts not in the hosts allow list */
2554 if (!check_access(-1)) {
2555 /* send a negative session response "not listining on calling
2556 name" */
2557 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2558 DEBUG(1,("%s Connection denied from %s\n",
2559 timestring(),client_addr()));
2560 send_smb(Client,(char *)buf);
2561 exit_server("connection denied");
2565 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
2566 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
2568 #ifdef WITH_VTP
2569 if(trans_num == 1 && VT_Check(inbuf))
2571 VT_Process();
2572 return;
2574 #endif
2576 if (msg_type == 0)
2577 show_msg(inbuf);
2579 nread = construct_reply(inbuf,outbuf,nread,max_send);
2581 if(nread > 0)
2583 if (CVAL(outbuf,0) == 0)
2584 show_msg(outbuf);
2586 if (nread != smb_len(outbuf) + 4)
2588 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2589 nread, smb_len(outbuf)));
2591 else
2592 send_smb(Client,outbuf);
2594 trans_num++;
2597 /****************************************************************************
2598 open the oplock IPC socket communication
2599 ****************************************************************************/
2600 static BOOL open_oplock_ipc()
2602 struct sockaddr_in sock_name;
2603 int len = sizeof(sock_name);
2605 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2607 /* Open a lookback UDP socket on a random port. */
2608 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
2609 if (oplock_sock == -1)
2611 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2612 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
2613 oplock_port = 0;
2614 return(False);
2617 /* Find out the transient UDP port we have been allocated. */
2618 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
2620 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2621 strerror(errno)));
2622 close(oplock_sock);
2623 oplock_sock = -1;
2624 oplock_port = 0;
2625 return False;
2627 oplock_port = ntohs(sock_name.sin_port);
2629 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2630 getpid(), oplock_port));
2632 return True;
2635 /****************************************************************************
2636 process an oplock break message.
2637 ****************************************************************************/
2638 static BOOL process_local_message(int sock, char *buffer, int buf_size)
2640 int32 msg_len;
2641 uint16 from_port;
2642 char *msg_start;
2644 msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
2645 from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
2647 msg_start = &buffer[UDP_CMD_HEADER_LEN];
2649 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2650 msg_len, from_port));
2652 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2653 only valid request. */
2655 switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
2657 case OPLOCK_BREAK_CMD:
2658 /* Ensure that the msg length is correct. */
2659 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2661 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2662 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2663 return False;
2666 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2667 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2668 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2669 struct timeval tval;
2670 struct sockaddr_in toaddr;
2672 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
2673 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
2675 DEBUG(5,("process_local_message: oplock break request from \
2676 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2679 * If we have no record of any currently open oplocks,
2680 * it's not an error, as a close command may have
2681 * just been issued on the file that was oplocked.
2682 * Just return success in this case.
2685 if(global_oplocks_open != 0)
2687 if(oplock_break(dev, inode, &tval) == False)
2689 DEBUG(0,("process_local_message: oplock break failed - \
2690 not returning udp message.\n"));
2691 return False;
2694 else
2696 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2697 oplocks. Returning success.\n"));
2700 /* Send the message back after OR'ing in the 'REPLY' bit. */
2701 SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
2703 bzero((char *)&toaddr,sizeof(toaddr));
2704 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2705 toaddr.sin_port = htons(from_port);
2706 toaddr.sin_family = AF_INET;
2708 if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
2709 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
2711 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2712 remotepid, strerror(errno)));
2713 return False;
2716 DEBUG(5,("process_local_message: oplock break reply sent to \
2717 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
2718 from_port, dev, inode));
2721 break;
2723 * Keep this as a debug case - eventually we can remove it.
2725 case 0x8001:
2726 DEBUG(0,("process_local_message: Received unsolicited break \
2727 reply - dumping info.\n"));
2729 if(msg_len != OPLOCK_BREAK_MSG_LEN)
2731 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2732 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
2733 return False;
2737 uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
2738 uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
2739 uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
2741 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2742 pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
2745 return False;
2747 default:
2748 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2749 (unsigned int)SVAL(msg_start,0)));
2750 return False;
2752 return True;
2755 /****************************************************************************
2756 Process an oplock break directly.
2757 ****************************************************************************/
2758 BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
2760 extern int Client;
2761 static char *inbuf = NULL;
2762 static char *outbuf = NULL;
2763 files_struct *fsp = NULL;
2764 int fnum;
2765 time_t start_time;
2766 BOOL shutdown_server = False;
2768 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2769 global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
2771 if(inbuf == NULL)
2773 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2774 if(inbuf == NULL) {
2775 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2776 return False;
2778 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2779 if(outbuf == NULL) {
2780 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2781 free(inbuf);
2782 inbuf = NULL;
2783 return False;
2787 /* We need to search the file open table for the
2788 entry containing this dev and inode, and ensure
2789 we have an oplock on it. */
2790 for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
2792 if(OPEN_FNUM(fnum))
2794 fsp = &Files[fnum];
2795 if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
2796 (fsp->open_time.tv_sec == tval->tv_sec) &&
2797 (fsp->open_time.tv_usec == tval->tv_usec))
2798 break;
2802 if(fsp == NULL)
2804 /* The file could have been closed in the meantime - return success. */
2805 DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2806 allowing break to succeed.\n", timestring(), dev, inode, fnum));
2807 return True;
2810 /* Ensure we have an oplock on the file */
2812 /* There is a potential race condition in that an oplock could
2813 have been broken due to another udp request, and yet there are
2814 still oplock break messages being sent in the udp message
2815 queue for this file. So return true if we don't have an oplock,
2816 as we may have just freed it.
2819 if(!fsp->granted_oplock)
2821 DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2822 Allowing break to succeed regardless.\n", timestring(), fsp->name, fnum, dev, inode));
2823 return True;
2826 /* Now comes the horrid part. We must send an oplock break to the client,
2827 and then process incoming messages until we get a close or oplock release.
2830 /* Prepare the SMBlockingX message. */
2831 bzero(outbuf,smb_size);
2832 set_message(outbuf,8,0,True);
2834 SCVAL(outbuf,smb_com,SMBlockingX);
2835 SSVAL(outbuf,smb_tid,fsp->cnum);
2836 SSVAL(outbuf,smb_pid,0xFFFF);
2837 SSVAL(outbuf,smb_uid,0);
2838 SSVAL(outbuf,smb_mid,0xFFFF);
2839 SCVAL(outbuf,smb_vwv0,0xFF);
2840 SSVAL(outbuf,smb_vwv2,fnum);
2841 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
2842 /* Change this when we have level II oplocks. */
2843 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
2845 send_smb(Client, outbuf);
2847 global_oplock_break = True;
2849 /* Process incoming messages. */
2851 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2852 seconds we should just die.... */
2854 start_time = time(NULL);
2856 while(OPEN_FNUM(fnum) && fsp->granted_oplock)
2858 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
2861 * Die if we got an error.
2864 if (smb_read_error == READ_EOF)
2865 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2867 if (smb_read_error == READ_ERROR)
2868 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2869 timestring(), strerror(errno)));
2871 if (smb_read_error == READ_TIMEOUT)
2872 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2873 timestring(), OPLOCK_BREAK_TIMEOUT));
2875 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2876 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2877 shutdown_server = True;
2878 break;
2880 process_smb(inbuf, outbuf);
2882 /* We only need this in case a readraw crossed on the wire. */
2883 if(global_oplock_break)
2884 global_oplock_break = False;
2887 * Die if we go over the time limit.
2890 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
2892 DEBUG(0,("%s oplock_break: no break received from client within \
2893 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT));
2894 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2895 inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
2896 shutdown_server = True;
2897 break;
2902 * If the client did not respond we must die.
2905 if(shutdown_server)
2907 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2908 timestring()));
2909 close_sockets();
2910 close(oplock_sock);
2911 exit_server("oplock break failure");
2914 if(OPEN_FNUM(fnum))
2916 /* The lockingX reply will have removed the oplock flag
2917 from the sharemode. */
2918 /* Paranoia.... */
2919 fsp->granted_oplock = False;
2922 global_oplocks_open--;
2924 /* Santity check - remove this later. JRA */
2925 if(global_oplocks_open < 0)
2927 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2928 global_oplocks_open));
2929 exit_server("oplock_break: global_oplocks_open < 0");
2932 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2933 global_oplocks_open = %d\n", timestring(), fnum, dev, inode, global_oplocks_open));
2935 return True;
2938 /****************************************************************************
2939 Send an oplock break message to another smbd process. If the oplock is held
2940 by the local smbd then call the oplock break function directly.
2941 ****************************************************************************/
2943 BOOL request_oplock_break(share_mode_entry *share_entry,
2944 uint32 dev, uint32 inode)
2946 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
2947 struct sockaddr_in addr_out;
2948 int pid = getpid();
2950 if(pid == share_entry->pid)
2952 /* We are breaking our own oplock, make sure it's us. */
2953 if(share_entry->op_port != oplock_port)
2955 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2956 should be %d\n", pid, share_entry->op_port, oplock_port));
2957 return False;
2960 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2962 /* Call oplock break direct. */
2963 return oplock_break(dev, inode, &share_entry->time);
2966 /* We need to send a OPLOCK_BREAK_CMD message to the
2967 port in the share mode entry. */
2969 SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
2970 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
2971 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
2972 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
2973 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
2974 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
2976 /* set the address and port */
2977 bzero((char *)&addr_out,sizeof(addr_out));
2978 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2979 addr_out.sin_port = htons( share_entry->op_port );
2980 addr_out.sin_family = AF_INET;
2982 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2983 for dev = %x, inode = %x\n", timestring(), share_entry->pid, share_entry->op_port, dev, inode));
2985 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
2986 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
2988 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2989 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2990 timestring(), share_entry->pid, share_entry->op_port, dev, inode,
2991 strerror(errno)));
2992 return False;
2996 * Now we must await the oplock broken message coming back
2997 * from the target smbd process. Timeout if it fails to
2998 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
2999 * While we get messages that aren't ours, loop.
3002 while(1)
3004 char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
3005 int32 reply_msg_len;
3006 uint16 reply_from_port;
3007 char *reply_msg_start;
3009 if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
3010 (OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) * 1000) == False)
3012 if(smb_read_error == READ_TIMEOUT)
3014 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3015 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry->pid,
3016 share_entry->op_port, dev, inode));
3018 * This is a hack to make handling of failing clients more robust.
3019 * If a oplock break response message is not received in the timeout
3020 * period we may assume that the smbd servicing that client holding
3021 * the oplock has died and the client changes were lost anyway, so
3022 * we should continue to try and open the file.
3024 break;
3026 else
3027 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3028 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring, share_entry->pid,
3029 share_entry->op_port, dev, inode, strerror(errno)));
3030 return False;
3034 * If the response we got was not an answer to our message, but
3035 * was a completely different request, push it onto the pending
3036 * udp message stack so that we can deal with it in the main loop.
3037 * It may be another oplock break request to us.
3041 * Local note from JRA. There exists the possibility of a denial
3042 * of service attack here by allowing non-root processes running
3043 * on a local machine sending many of these pending messages to
3044 * a smbd port. Currently I'm not sure how to restrict the messages
3045 * I will queue (although I could add a limit to the queue) to
3046 * those received by root processes only. There should be a
3047 * way to make this bulletproof....
3050 reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
3051 reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
3053 reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
3055 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
3057 /* Ignore it. */
3058 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3059 timestring()));
3060 continue;
3063 if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
3064 (reply_from_port != share_entry->op_port) ||
3065 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
3066 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
3067 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
3069 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3070 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3071 timestring(), share_entry->pid, share_entry->op_port, dev, inode));
3072 if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
3073 return False;
3074 continue;
3077 break;
3080 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3082 return True;
3085 /****************************************************************************
3086 check if a snum is in use
3087 ****************************************************************************/
3088 BOOL snum_used(int snum)
3090 int i;
3091 for (i=0;i<MAX_CONNECTIONS;i++)
3092 if (OPEN_CNUM(i) && (SNUM(i) == snum))
3093 return(True);
3094 return(False);
3097 /****************************************************************************
3098 reload the services file
3099 **************************************************************************/
3100 BOOL reload_services(BOOL test)
3102 BOOL ret;
3104 if (lp_loaded())
3106 pstring fname;
3107 pstrcpy(fname,lp_configfile());
3108 if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
3110 pstrcpy(servicesf,fname);
3111 test = False;
3115 reopen_logs();
3117 if (test && !lp_file_list_changed())
3118 return(True);
3120 lp_killunused(snum_used);
3122 ret = lp_load(servicesf,False);
3124 /* perhaps the config filename is now set */
3125 if (!test)
3126 reload_services(True);
3128 reopen_logs();
3130 load_interfaces();
3133 extern int Client;
3134 if (Client != -1) {
3135 set_socket_options(Client,"SO_KEEPALIVE");
3136 set_socket_options(Client,user_socket_options);
3140 reset_mangled_stack( lp_mangledstack() );
3142 /* this forces service parameters to be flushed */
3143 become_service(-1,True);
3145 return(ret);
3150 /****************************************************************************
3151 this prevents zombie child processes
3152 ****************************************************************************/
3153 static int sig_hup()
3155 BlockSignals(True,SIGHUP);
3156 DEBUG(0,("Got SIGHUP\n"));
3157 reload_services(False);
3158 #ifndef DONT_REINSTALL_SIG
3159 signal(SIGHUP,SIGNAL_CAST sig_hup);
3160 #endif
3161 BlockSignals(False,SIGHUP);
3162 return(0);
3165 /****************************************************************************
3166 Setup the groups a user belongs to.
3167 ****************************************************************************/
3168 int setup_groups(char *user, int uid, int gid, int *p_ngroups,
3169 int **p_igroups, gid_t **p_groups,
3170 int **p_attrs)
3172 if (-1 == initgroups(user,gid))
3174 if (getuid() == 0)
3176 DEBUG(0,("Unable to initgroups!\n"));
3177 if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
3178 DEBUG(0,("This is probably a problem with the account %s\n",user));
3181 else
3183 int i,ngroups;
3184 int *igroups;
3185 int *attrs;
3186 gid_t grp = 0;
3187 ngroups = getgroups(0,&grp);
3188 if (ngroups <= 0)
3189 ngroups = 32;
3190 igroups = (int *)malloc(sizeof(int)*ngroups);
3191 attrs = (int *)malloc(sizeof(int)*ngroups);
3192 for (i=0;i<ngroups;i++)
3194 attrs [i] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3195 igroups[i] = 0x42424242;
3197 ngroups = getgroups(ngroups,(gid_t *)igroups);
3199 if (igroups[0] == 0x42424242)
3200 ngroups = 0;
3202 *p_ngroups = ngroups;
3203 *p_attrs = attrs;
3205 /* The following bit of code is very strange. It is due to the
3206 fact that some OSes use int* and some use gid_t* for
3207 getgroups, and some (like SunOS) use both, one in prototypes,
3208 and one in man pages and the actual code. Thus we detect it
3209 dynamically using some very ugly code */
3210 if (ngroups > 0)
3212 /* does getgroups return ints or gid_t ?? */
3213 static BOOL groups_use_ints = True;
3215 if (groups_use_ints &&
3216 ngroups == 1 &&
3217 SVAL(igroups,2) == 0x4242)
3218 groups_use_ints = False;
3220 for (i=0;groups_use_ints && i<ngroups;i++)
3221 if (igroups[i] == 0x42424242)
3222 groups_use_ints = False;
3224 if (groups_use_ints)
3226 *p_igroups = igroups;
3227 *p_groups = (gid_t *)igroups;
3229 else
3231 gid_t *groups = (gid_t *)igroups;
3232 igroups = (int *)malloc(sizeof(int)*ngroups);
3233 for (i=0;i<ngroups;i++)
3235 igroups[i] = groups[i];
3237 *p_igroups = igroups;
3238 *p_groups = (gid_t *)groups;
3241 DEBUG(3,("%s is in %d groups\n",user,ngroups));
3242 for (i=0;i<ngroups;i++)
3243 DEBUG(3,("%d ",igroups[i]));
3244 DEBUG(3,("\n"));
3246 return 0;
3249 /****************************************************************************
3250 make a connection to a service
3251 ****************************************************************************/
3252 int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
3254 int cnum;
3255 int snum;
3256 struct passwd *pass = NULL;
3257 connection_struct *pcon;
3258 BOOL guest = False;
3259 BOOL force = False;
3260 static BOOL first_connection = True;
3262 strlower(service);
3264 snum = find_service(service);
3265 if (snum < 0)
3267 if (strequal(service,"IPC$"))
3269 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3270 return(-3);
3273 DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
3274 return(-2);
3277 if (strequal(service,HOMES_NAME))
3279 if (*user && Get_Pwnam(user,True))
3280 return(make_connection(user,user,password,pwlen,dev,vuid));
3282 if (validated_username(vuid))
3284 strcpy(user,validated_username(vuid));
3285 return(make_connection(user,user,password,pwlen,dev,vuid));
3289 if (!lp_snum_ok(snum) || !check_access(snum)) {
3290 return(-4);
3293 /* you can only connect to the IPC$ service as an ipc device */
3294 if (strequal(service,"IPC$"))
3295 strcpy(dev,"IPC");
3297 if (*dev == '?' || !*dev)
3299 if (lp_print_ok(snum))
3300 strcpy(dev,"LPT1:");
3301 else
3302 strcpy(dev,"A:");
3305 /* if the request is as a printer and you can't print then refuse */
3306 strupper(dev);
3307 if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
3308 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3309 return(-6);
3312 /* lowercase the user name */
3313 strlower(user);
3315 /* add it as a possible user name */
3316 add_session_user(service);
3318 /* shall we let them in? */
3319 if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
3321 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
3322 return(-1);
3325 cnum = find_free_connection(str_checksum(service) + str_checksum(user));
3326 if (cnum < 0)
3328 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3329 return(-1);
3332 pcon = &Connections[cnum];
3333 bzero((char *)pcon,sizeof(*pcon));
3335 /* find out some info about the user */
3336 pass = Get_Pwnam(user,True);
3338 if (pass == NULL)
3340 DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
3341 return(-7);
3344 pcon->read_only = lp_readonly(snum);
3347 pstring list;
3348 StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
3349 string_sub(list,"%S",service);
3351 if (user_in_list(user,list))
3352 pcon->read_only = True;
3354 StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
3355 string_sub(list,"%S",service);
3357 if (user_in_list(user,list))
3358 pcon->read_only = False;
3361 /* admin user check */
3363 /* JRA - original code denied admin user if the share was
3364 marked read_only. Changed as I don't think this is needed,
3365 but old code left in case there is a problem here.
3367 if (user_in_list(user,lp_admin_users(snum))
3368 #if 0
3369 && !pcon->read_only)
3370 #else
3372 #endif
3374 pcon->admin_user = True;
3375 DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
3377 else
3378 pcon->admin_user = False;
3380 pcon->force_user = force;
3381 pcon->vuid = vuid;
3382 pcon->uid = pass->pw_uid;
3383 pcon->gid = pass->pw_gid;
3384 pcon->num_files_open = 0;
3385 pcon->lastused = time(NULL);
3386 pcon->service = snum;
3387 pcon->used = True;
3388 pcon->printer = (strncmp(dev,"LPT",3) == 0);
3389 pcon->ipc = (strncmp(dev,"IPC",3) == 0);
3390 pcon->dirptr = NULL;
3391 pcon->veto_list = NULL;
3392 pcon->hide_list = NULL;
3393 string_set(&pcon->dirpath,"");
3394 string_set(&pcon->user,user);
3396 #if HAVE_GETGRNAM
3397 if (*lp_force_group(snum))
3399 struct group *gptr;
3400 pstring gname;
3402 StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
3403 /* default service may be a group name */
3404 string_sub(gname,"%S",service);
3405 gptr = (struct group *)getgrnam(gname);
3407 if (gptr)
3409 pcon->gid = gptr->gr_gid;
3410 DEBUG(3,("Forced group %s\n",gname));
3412 else
3413 DEBUG(1,("Couldn't find group %s\n",gname));
3415 #endif
3417 if (*lp_force_user(snum))
3419 struct passwd *pass2;
3420 fstring fuser;
3421 fstrcpy(fuser,lp_force_user(snum));
3422 pass2 = (struct passwd *)Get_Pwnam(fuser,True);
3423 if (pass2)
3425 pcon->uid = pass2->pw_uid;
3426 string_set(&pcon->user,fuser);
3427 fstrcpy(user,fuser);
3428 pcon->force_user = True;
3429 DEBUG(3,("Forced user %s\n",fuser));
3431 else
3432 DEBUG(1,("Couldn't find user %s\n",fuser));
3436 pstring s;
3437 pstrcpy(s,lp_pathname(snum));
3438 standard_sub(cnum,s);
3439 string_set(&pcon->connectpath,s);
3440 DEBUG(3,("Connect path is %s\n",s));
3443 /* groups stuff added by ih */
3444 pcon->ngroups = 0;
3445 pcon->igroups = NULL;
3446 pcon->groups = NULL;
3447 pcon->attrs = NULL;
3449 if (!IS_IPC(cnum))
3451 /* Find all the groups this uid is in and store them. Used by become_user() */
3452 setup_groups(pcon->user,pcon->uid,pcon->gid,
3453 &pcon->ngroups,&pcon->igroups,&pcon->groups,&pcon->attrs);
3455 /* check number of connections */
3456 if (!claim_connection(cnum,
3457 lp_servicename(SNUM(cnum)),
3458 lp_max_connections(SNUM(cnum)),False))
3460 DEBUG(1,("too many connections - rejected\n"));
3461 return(-8);
3464 if (lp_status(SNUM(cnum)))
3465 claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
3467 first_connection = False;
3468 } /* IS_IPC */
3470 pcon->open = True;
3472 /* execute any "root preexec = " line */
3473 if (*lp_rootpreexec(SNUM(cnum)))
3475 pstring cmd;
3476 pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
3477 standard_sub(cnum,cmd);
3478 DEBUG(5,("cmd=%s\n",cmd));
3479 smbrun(cmd,NULL,False);
3482 if (!become_user(&Connections[cnum], cnum,pcon->vuid))
3484 DEBUG(0,("Can't become connected user!\n"));
3485 pcon->open = False;
3486 if (!IS_IPC(cnum)) {
3487 yield_connection(cnum,
3488 lp_servicename(SNUM(cnum)),
3489 lp_max_connections(SNUM(cnum)));
3490 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3492 return(-1);
3495 if (ChDir(pcon->connectpath) != 0)
3497 DEBUG(0,("Can't change directory to %s (%s)\n",
3498 pcon->connectpath,strerror(errno)));
3499 pcon->open = False;
3500 unbecome_user();
3501 if (!IS_IPC(cnum)) {
3502 yield_connection(cnum,
3503 lp_servicename(SNUM(cnum)),
3504 lp_max_connections(SNUM(cnum)));
3505 if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
3507 return(-5);
3510 string_set(&pcon->origpath,pcon->connectpath);
3512 #if SOFTLINK_OPTIMISATION
3513 /* resolve any soft links early */
3515 pstring s;
3516 pstrcpy(s,pcon->connectpath);
3517 GetWd(s);
3518 string_set(&pcon->connectpath,s);
3519 ChDir(pcon->connectpath);
3521 #endif
3523 num_connections_open++;
3524 add_session_user(user);
3526 /* execute any "preexec = " line */
3527 if (*lp_preexec(SNUM(cnum)))
3529 pstring cmd;
3530 pstrcpy(cmd,lp_preexec(SNUM(cnum)));
3531 standard_sub(cnum,cmd);
3532 smbrun(cmd,NULL,False);
3535 /* we've finished with the sensitive stuff */
3536 unbecome_user();
3538 /* Add veto/hide lists */
3539 if (!IS_IPC(cnum) && !IS_PRINT(cnum))
3541 set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
3542 set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
3546 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3547 timestring(),
3548 remote_machine,
3549 client_addr(),
3550 lp_servicename(SNUM(cnum)),user,
3551 pcon->uid,
3552 pcon->gid,
3553 (int)getpid()));
3556 return(cnum);
3560 /****************************************************************************
3561 find first available file slot
3562 ****************************************************************************/
3563 int find_free_file(void )
3565 int i;
3566 /* we start at 1 here for an obscure reason I can't now remember,
3567 but I think is important :-) */
3568 for (i=1;i<MAX_OPEN_FILES;i++)
3569 if (!Files[i].open)
3570 return(i);
3571 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3572 return(-1);
3575 /****************************************************************************
3576 find first available connection slot, starting from a random position.
3577 The randomisation stops problems with the server dieing and clients
3578 thinking the server is still available.
3579 ****************************************************************************/
3580 static int find_free_connection(int hash )
3582 int i;
3583 BOOL used=False;
3584 hash = (hash % (MAX_CONNECTIONS-2))+1;
3586 again:
3588 for (i=hash+1;i!=hash;)
3590 if (!Connections[i].open && Connections[i].used == used)
3592 DEBUG(3,("found free connection number %d\n",i));
3593 return(i);
3595 i++;
3596 if (i == MAX_CONNECTIONS)
3597 i = 1;
3600 if (!used)
3602 used = !used;
3603 goto again;
3606 DEBUG(1,("ERROR! Out of connection structures\n"));
3607 return(-1);
3611 /****************************************************************************
3612 reply for the core protocol
3613 ****************************************************************************/
3614 int reply_corep(char *outbuf)
3616 int outsize = set_message(outbuf,1,0,True);
3618 Protocol = PROTOCOL_CORE;
3620 return outsize;
3624 /****************************************************************************
3625 reply for the coreplus protocol
3626 ****************************************************************************/
3627 int reply_coreplus(char *outbuf)
3629 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3630 int outsize = set_message(outbuf,13,0,True);
3631 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3632 readbraw and writebraw (possibly) */
3633 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3634 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
3636 Protocol = PROTOCOL_COREPLUS;
3638 return outsize;
3642 /****************************************************************************
3643 reply for the lanman 1.0 protocol
3644 ****************************************************************************/
3645 int reply_lanman1(char *outbuf)
3647 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3648 int secword=0;
3649 BOOL doencrypt = SMBENCRYPT();
3650 time_t t = time(NULL);
3652 if (lp_security()>=SEC_USER) secword |= 1;
3653 if (doencrypt) secword |= 2;
3655 set_message(outbuf,13,doencrypt?8:0,True);
3656 SSVAL(outbuf,smb_vwv1,secword);
3657 /* Create a token value and add it to the outgoing packet. */
3658 if (doencrypt)
3659 generate_next_challenge(smb_buf(outbuf));
3661 Protocol = PROTOCOL_LANMAN1;
3663 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3664 SSVAL(outbuf,smb_vwv2,max_recv);
3665 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
3666 SSVAL(outbuf,smb_vwv4,1);
3667 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
3668 readbraw writebraw (possibly) */
3669 SIVAL(outbuf,smb_vwv6,getpid());
3670 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3672 put_dos_date(outbuf,smb_vwv8,t);
3674 return (smb_len(outbuf)+4);
3678 /****************************************************************************
3679 reply for the lanman 2.0 protocol
3680 ****************************************************************************/
3681 int reply_lanman2(char *outbuf)
3683 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3684 int secword=0;
3685 BOOL doencrypt = SMBENCRYPT();
3686 time_t t = time(NULL);
3687 struct cli_state *cli = NULL;
3688 char cryptkey[8];
3689 char crypt_len = 0;
3691 if (lp_security() == SEC_SERVER) {
3692 cli = server_cryptkey();
3695 if (cli) {
3696 DEBUG(3,("using password server validation\n"));
3697 doencrypt = ((cli->sec_mode & 2) != 0);
3700 if (lp_security()>=SEC_USER) secword |= 1;
3701 if (doencrypt) secword |= 2;
3703 if (doencrypt) {
3704 crypt_len = 8;
3705 if (!cli) {
3706 generate_next_challenge(cryptkey);
3707 } else {
3708 memcpy(cryptkey, cli->cryptkey, 8);
3709 set_challenge(cli->cryptkey);
3713 set_message(outbuf,13,crypt_len,True);
3714 SSVAL(outbuf,smb_vwv1,secword);
3715 SIVAL(outbuf,smb_vwv6,getpid());
3716 if (doencrypt)
3717 memcpy(smb_buf(outbuf), cryptkey, 8);
3719 Protocol = PROTOCOL_LANMAN2;
3721 CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3722 SSVAL(outbuf,smb_vwv2,max_recv);
3723 SSVAL(outbuf,smb_vwv3,lp_maxmux());
3724 SSVAL(outbuf,smb_vwv4,1);
3725 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
3726 SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
3727 put_dos_date(outbuf,smb_vwv8,t);
3729 return (smb_len(outbuf)+4);
3733 /****************************************************************************
3734 reply for the nt protocol
3735 ****************************************************************************/
3736 int reply_nt1(char *outbuf)
3738 /* dual names + lock_and_read + nt SMBs + remote API calls */
3739 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
3741 other valid capabilities which we may support at some time...
3742 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3743 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3746 int secword=0;
3747 BOOL doencrypt = SMBENCRYPT();
3748 time_t t = time(NULL);
3749 int data_len;
3750 struct cli_state *cli = NULL;
3751 char cryptkey[8];
3752 char crypt_len = 0;
3754 if (lp_security() == SEC_SERVER) {
3755 cli = server_cryptkey();
3758 if (cli) {
3759 DEBUG(3,("using password server validation\n"));
3760 doencrypt = ((cli->sec_mode & 2) != 0);
3763 if (doencrypt) {
3764 crypt_len = 8;
3765 if (!cli) {
3766 generate_next_challenge(cryptkey);
3767 } else {
3768 memcpy(cryptkey, cli->cryptkey, 8);
3769 set_challenge(cli->cryptkey);
3773 if (lp_readraw() && lp_writeraw()) {
3774 capabilities |= CAP_RAW_MODE;
3777 if (lp_security() >= SEC_USER) secword |= 1;
3778 if (doencrypt) secword |= 2;
3780 /* decide where (if) to put the encryption challenge, and
3781 follow it with the OEM'd domain name
3783 data_len = crypt_len + strlen(myworkgroup) + 1;
3785 set_message(outbuf,17,data_len,True);
3786 strcpy(smb_buf(outbuf)+crypt_len, myworkgroup);
3788 CVAL(outbuf,smb_vwv1) = secword;
3789 SSVALS(outbuf,smb_vwv16+1,crypt_len);
3790 if (doencrypt)
3791 memcpy(smb_buf(outbuf), cryptkey, 8);
3793 Protocol = PROTOCOL_NT1;
3795 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
3796 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
3797 SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
3798 SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
3799 SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
3800 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
3801 put_long_date(outbuf+smb_vwv11+1,t);
3802 SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
3803 SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
3805 return (smb_len(outbuf)+4);
3808 /* these are the protocol lists used for auto architecture detection:
3810 WinNT 3.51:
3811 protocol [PC NETWORK PROGRAM 1.0]
3812 protocol [XENIX CORE]
3813 protocol [MICROSOFT NETWORKS 1.03]
3814 protocol [LANMAN1.0]
3815 protocol [Windows for Workgroups 3.1a]
3816 protocol [LM1.2X002]
3817 protocol [LANMAN2.1]
3818 protocol [NT LM 0.12]
3820 Win95:
3821 protocol [PC NETWORK PROGRAM 1.0]
3822 protocol [XENIX CORE]
3823 protocol [MICROSOFT NETWORKS 1.03]
3824 protocol [LANMAN1.0]
3825 protocol [Windows for Workgroups 3.1a]
3826 protocol [LM1.2X002]
3827 protocol [LANMAN2.1]
3828 protocol [NT LM 0.12]
3830 OS/2:
3831 protocol [PC NETWORK PROGRAM 1.0]
3832 protocol [XENIX CORE]
3833 protocol [LANMAN1.0]
3834 protocol [LM1.2X002]
3835 protocol [LANMAN2.1]
3839 * Modified to recognize the architecture of the remote machine better.
3841 * This appears to be the matrix of which protocol is used by which
3842 * MS product.
3843 Protocol WfWg Win95 WinNT OS/2
3844 PC NETWORK PROGRAM 1.0 1 1 1 1
3845 XENIX CORE 2 2
3846 MICROSOFT NETWORKS 3.0 2 2
3847 DOS LM1.2X002 3 3
3848 MICROSOFT NETWORKS 1.03 3
3849 DOS LANMAN2.1 4 4
3850 LANMAN1.0 4 3
3851 Windows for Workgroups 3.1a 5 5 5
3852 LM1.2X002 6 4
3853 LANMAN2.1 7 5
3854 NT LM 0.12 6 8
3856 * tim@fsg.com 09/29/95
3859 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3860 #define ARCH_WIN95 0x2
3861 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3862 #define ARCH_WINNT 0x8
3863 #define ARCH_SAMBA 0x10
3865 #define ARCH_ALL 0x1F
3867 /* List of supported protocols, most desired first */
3868 struct {
3869 char *proto_name;
3870 char *short_name;
3871 int (*proto_reply_fn)(char *);
3872 int protocol_level;
3873 } supported_protocols[] = {
3874 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
3875 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
3876 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3877 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3878 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
3879 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3880 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
3881 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
3882 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
3883 {NULL,NULL},
3887 /****************************************************************************
3888 reply to a negprot
3889 ****************************************************************************/
3890 static int reply_negprot(char *inbuf,char *outbuf)
3892 int outsize = set_message(outbuf,1,0,True);
3893 int Index=0;
3894 int choice= -1;
3895 int protocol;
3896 char *p;
3897 int bcc = SVAL(smb_buf(inbuf),-2);
3898 int arch = ARCH_ALL;
3900 p = smb_buf(inbuf)+1;
3901 while (p < (smb_buf(inbuf) + bcc))
3903 Index++;
3904 DEBUG(3,("Requested protocol [%s]\n",p));
3905 if (strcsequal(p,"Windows for Workgroups 3.1a"))
3906 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
3907 else if (strcsequal(p,"DOS LM1.2X002"))
3908 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3909 else if (strcsequal(p,"DOS LANMAN2.1"))
3910 arch &= ( ARCH_WFWG | ARCH_WIN95 );
3911 else if (strcsequal(p,"NT LM 0.12"))
3912 arch &= ( ARCH_WIN95 | ARCH_WINNT );
3913 else if (strcsequal(p,"LANMAN2.1"))
3914 arch &= ( ARCH_WINNT | ARCH_OS2 );
3915 else if (strcsequal(p,"LM1.2X002"))
3916 arch &= ( ARCH_WINNT | ARCH_OS2 );
3917 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
3918 arch &= ARCH_WINNT;
3919 else if (strcsequal(p,"XENIX CORE"))
3920 arch &= ( ARCH_WINNT | ARCH_OS2 );
3921 else if (strcsequal(p,"Samba")) {
3922 arch = ARCH_SAMBA;
3923 break;
3926 p += strlen(p) + 2;
3929 switch ( arch ) {
3930 case ARCH_SAMBA:
3931 set_remote_arch(RA_SAMBA);
3932 break;
3933 case ARCH_WFWG:
3934 set_remote_arch(RA_WFWG);
3935 break;
3936 case ARCH_WIN95:
3937 set_remote_arch(RA_WIN95);
3938 break;
3939 case ARCH_WINNT:
3940 set_remote_arch(RA_WINNT);
3941 break;
3942 case ARCH_OS2:
3943 set_remote_arch(RA_OS2);
3944 break;
3945 default:
3946 set_remote_arch(RA_UNKNOWN);
3947 break;
3950 /* possibly reload - change of architecture */
3951 reload_services(True);
3953 /* a special case to stop password server loops */
3954 if (Index == 1 && strequal(remote_machine,myhostname) &&
3955 lp_security()==SEC_SERVER)
3956 exit_server("Password server loop!");
3958 /* Check for protocols, most desirable first */
3959 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
3961 p = smb_buf(inbuf)+1;
3962 Index = 0;
3963 if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
3964 while (p < (smb_buf(inbuf) + bcc))
3966 if (strequal(p,supported_protocols[protocol].proto_name))
3967 choice = Index;
3968 Index++;
3969 p += strlen(p) + 2;
3971 if(choice != -1)
3972 break;
3975 SSVAL(outbuf,smb_vwv0,choice);
3976 if(choice != -1) {
3977 extern fstring remote_proto;
3978 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
3979 reload_services(True);
3980 outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
3981 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
3983 else {
3984 DEBUG(0,("No protocol supported !\n"));
3986 SSVAL(outbuf,smb_vwv0,choice);
3988 DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
3990 return(outsize);
3994 /****************************************************************************
3995 close all open files for a connection
3996 ****************************************************************************/
3997 static void close_open_files(int cnum)
3999 int i;
4000 for (i=0;i<MAX_OPEN_FILES;i++)
4001 if( Files[i].cnum == cnum && Files[i].open) {
4002 close_file(i,False);
4008 /****************************************************************************
4009 close a cnum
4010 ****************************************************************************/
4011 void close_cnum(int cnum, uint16 vuid)
4013 DirCacheFlush(SNUM(cnum));
4015 unbecome_user();
4017 if (!OPEN_CNUM(cnum))
4019 DEBUG(0,("Can't close cnum %d\n",cnum));
4020 return;
4023 DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
4024 timestring(),
4025 remote_machine,client_addr(),
4026 lp_servicename(SNUM(cnum))));
4028 yield_connection(cnum,
4029 lp_servicename(SNUM(cnum)),
4030 lp_max_connections(SNUM(cnum)));
4032 if (lp_status(SNUM(cnum)))
4033 yield_connection(cnum,"STATUS.",MAXSTATUS);
4035 close_open_files(cnum);
4036 dptr_closecnum(cnum);
4038 /* execute any "postexec = " line */
4039 if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
4041 pstring cmd;
4042 strcpy(cmd,lp_postexec(SNUM(cnum)));
4043 standard_sub(cnum,cmd);
4044 smbrun(cmd,NULL,False);
4045 unbecome_user();
4048 unbecome_user();
4049 /* execute any "root postexec = " line */
4050 if (*lp_rootpostexec(SNUM(cnum)))
4052 pstring cmd;
4053 strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
4054 standard_sub(cnum,cmd);
4055 smbrun(cmd,NULL,False);
4058 Connections[cnum].open = False;
4059 num_connections_open--;
4060 if (Connections[cnum].ngroups && Connections[cnum].groups)
4062 if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
4063 free(Connections[cnum].groups);
4064 free(Connections[cnum].igroups);
4065 Connections[cnum].groups = NULL;
4066 Connections[cnum].igroups = NULL;
4067 Connections[cnum].ngroups = 0;
4070 free_namearray(Connections[cnum].veto_list);
4071 free_namearray(Connections[cnum].hide_list);
4073 string_set(&Connections[cnum].user,"");
4074 string_set(&Connections[cnum].dirpath,"");
4075 string_set(&Connections[cnum].connectpath,"");
4079 /****************************************************************************
4080 simple routines to do connection counting
4081 ****************************************************************************/
4082 BOOL yield_connection(int cnum,char *name,int max_connections)
4084 struct connect_record crec;
4085 pstring fname;
4086 FILE *f;
4087 int mypid = getpid();
4088 int i;
4090 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
4092 if (max_connections <= 0)
4093 return(True);
4095 bzero(&crec,sizeof(crec));
4097 pstrcpy(fname,lp_lockdir());
4098 standard_sub(cnum,fname);
4099 trim_string(fname,"","/");
4101 strcat(fname,"/");
4102 strcat(fname,name);
4103 strcat(fname,".LCK");
4105 f = fopen(fname,"r+");
4106 if (!f)
4108 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
4109 return(False);
4112 fseek(f,0,SEEK_SET);
4114 /* find a free spot */
4115 for (i=0;i<max_connections;i++)
4117 if (fread(&crec,sizeof(crec),1,f) != 1)
4119 DEBUG(2,("Entry not found in lock file %s\n",fname));
4120 fclose(f);
4121 return(False);
4123 if (crec.pid == mypid && crec.cnum == cnum)
4124 break;
4127 if (crec.pid != mypid || crec.cnum != cnum)
4129 fclose(f);
4130 DEBUG(2,("Entry not found in lock file %s\n",fname));
4131 return(False);
4134 bzero((void *)&crec,sizeof(crec));
4136 /* remove our mark */
4137 if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4138 fwrite(&crec,sizeof(crec),1,f) != 1)
4140 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
4141 fclose(f);
4142 return(False);
4145 DEBUG(3,("Yield successful\n"));
4147 fclose(f);
4148 return(True);
4152 /****************************************************************************
4153 simple routines to do connection counting
4154 ****************************************************************************/
4155 BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
4157 struct connect_record crec;
4158 pstring fname;
4159 FILE *f;
4160 int snum = SNUM(cnum);
4161 int i,foundi= -1;
4162 int total_recs;
4164 if (max_connections <= 0)
4165 return(True);
4167 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
4169 pstrcpy(fname,lp_lockdir());
4170 standard_sub(cnum,fname);
4171 trim_string(fname,"","/");
4173 if (!directory_exist(fname,NULL))
4174 mkdir(fname,0755);
4176 strcat(fname,"/");
4177 strcat(fname,name);
4178 strcat(fname,".LCK");
4180 if (!file_exist(fname,NULL))
4182 int oldmask = umask(022);
4183 f = fopen(fname,"w");
4184 if (f) fclose(f);
4185 umask(oldmask);
4188 total_recs = file_size(fname) / sizeof(crec);
4190 f = fopen(fname,"r+");
4192 if (!f)
4194 DEBUG(1,("couldn't open lock file %s\n",fname));
4195 return(False);
4198 /* find a free spot */
4199 for (i=0;i<max_connections;i++)
4202 if (i>=total_recs ||
4203 fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
4204 fread(&crec,sizeof(crec),1,f) != 1)
4206 if (foundi < 0) foundi = i;
4207 break;
4210 if (Clear && crec.pid && !process_exists(crec.pid))
4212 fseek(f,i*sizeof(crec),SEEK_SET);
4213 bzero((void *)&crec,sizeof(crec));
4214 fwrite(&crec,sizeof(crec),1,f);
4215 if (foundi < 0) foundi = i;
4216 continue;
4218 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
4220 foundi=i;
4221 if (!Clear) break;
4225 if (foundi < 0)
4227 DEBUG(3,("no free locks in %s\n",fname));
4228 fclose(f);
4229 return(False);
4232 /* fill in the crec */
4233 bzero((void *)&crec,sizeof(crec));
4234 crec.magic = 0x280267;
4235 crec.pid = getpid();
4236 crec.cnum = cnum;
4237 crec.uid = Connections[cnum].uid;
4238 crec.gid = Connections[cnum].gid;
4239 StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
4240 crec.start = time(NULL);
4242 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
4243 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
4245 /* make our mark */
4246 if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
4247 fwrite(&crec,sizeof(crec),1,f) != 1)
4249 fclose(f);
4250 return(False);
4253 fclose(f);
4254 return(True);
4257 #if DUMP_CORE
4258 /*******************************************************************
4259 prepare to dump a core file - carefully!
4260 ********************************************************************/
4261 static BOOL dump_core(void)
4263 char *p;
4264 pstring dname;
4265 pstrcpy(dname,debugf);
4266 if ((p=strrchr(dname,'/'))) *p=0;
4267 strcat(dname,"/corefiles");
4268 mkdir(dname,0700);
4269 sys_chown(dname,getuid(),getgid());
4270 chmod(dname,0700);
4271 if (chdir(dname)) return(False);
4272 umask(~(0700));
4274 #ifndef NO_GETRLIMIT
4275 #ifdef RLIMIT_CORE
4277 struct rlimit rlp;
4278 getrlimit(RLIMIT_CORE, &rlp);
4279 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
4280 setrlimit(RLIMIT_CORE, &rlp);
4281 getrlimit(RLIMIT_CORE, &rlp);
4282 DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
4284 #endif
4285 #endif
4288 DEBUG(0,("Dumping core in %s\n",dname));
4289 return(True);
4291 #endif
4293 /****************************************************************************
4294 exit the server
4295 ****************************************************************************/
4296 void exit_server(char *reason)
4298 static int firsttime=1;
4299 int i;
4301 if (!firsttime) exit(0);
4302 firsttime = 0;
4304 unbecome_user();
4305 DEBUG(2,("Closing connections\n"));
4306 for (i=0;i<MAX_CONNECTIONS;i++)
4307 if (Connections[i].open)
4308 close_cnum(i,(uint16)-1);
4309 #ifdef DFS_AUTH
4310 if (dcelogin_atmost_once)
4311 dfs_unlogin();
4312 #endif
4313 if (!reason) {
4314 int oldlevel = DEBUGLEVEL;
4315 DEBUGLEVEL = 10;
4316 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
4317 if (last_inbuf)
4318 show_msg(last_inbuf);
4319 DEBUGLEVEL = oldlevel;
4320 DEBUG(0,("===============================================================\n"));
4321 #if DUMP_CORE
4322 if (dump_core()) return;
4323 #endif
4326 locking_end();
4328 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
4329 exit(0);
4332 /****************************************************************************
4333 do some standard substitutions in a string
4334 ****************************************************************************/
4335 void standard_sub(int cnum,char *str)
4337 if (VALID_CNUM(cnum)) {
4338 char *p, *s, *home;
4340 for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
4341 switch (*(p+1)) {
4342 case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
4343 string_sub(p,"%H",home);
4344 else
4345 p += 2;
4346 break;
4347 case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
4348 case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
4349 case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
4350 case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
4351 case '\0' : p++; break; /* don't run off the end of the string */
4352 default : p+=2; break;
4356 standard_sub_basic(str);
4360 These flags determine some of the permissions required to do an operation
4362 Note that I don't set NEED_WRITE on some write operations because they
4363 are used by some brain-dead clients when printing, and I don't want to
4364 force write permissions on print services.
4366 #define AS_USER (1<<0)
4367 #define NEED_WRITE (1<<1)
4368 #define TIME_INIT (1<<2)
4369 #define CAN_IPC (1<<3)
4370 #define AS_GUEST (1<<5)
4374 define a list of possible SMB messages and their corresponding
4375 functions. Any message that has a NULL function is unimplemented -
4376 please feel free to contribute implementations!
4378 struct smb_message_struct
4380 int code;
4381 char *name;
4382 int (*fn)();
4383 int flags;
4384 #if PROFILING
4385 unsigned long time;
4386 #endif
4388 smb_messages[] = {
4390 /* CORE PROTOCOL */
4392 {SMBnegprot,"SMBnegprot",reply_negprot,0},
4393 {SMBtcon,"SMBtcon",reply_tcon,0},
4394 {SMBtdis,"SMBtdis",reply_tdis,0},
4395 {SMBexit,"SMBexit",reply_exit,0},
4396 {SMBioctl,"SMBioctl",reply_ioctl,0},
4397 {SMBecho,"SMBecho",reply_echo,0},
4398 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
4399 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
4400 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
4401 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
4402 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
4403 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
4404 {SMBsearch,"SMBsearch",reply_search,AS_USER},
4405 {SMBopen,"SMBopen",reply_open,AS_USER},
4407 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4408 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
4409 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
4411 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
4412 {SMBread,"SMBread",reply_read,AS_USER},
4413 {SMBwrite,"SMBwrite",reply_write,AS_USER},
4414 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
4415 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
4416 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
4417 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
4418 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
4420 /* this is a Pathworks specific call, allowing the
4421 changing of the root path */
4422 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
4424 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
4425 {SMBflush,"SMBflush",reply_flush,AS_USER},
4426 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
4427 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
4428 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
4429 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
4430 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
4431 {SMBlock,"SMBlock",reply_lock,AS_USER},
4432 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
4434 /* CORE+ PROTOCOL FOLLOWS */
4436 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
4437 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
4438 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
4439 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
4440 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
4442 /* LANMAN1.0 PROTOCOL FOLLOWS */
4444 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
4445 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
4446 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
4447 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
4448 {SMBwritec,"SMBwritec",NULL,AS_USER},
4449 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
4450 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
4451 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
4452 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
4453 {SMBioctls,"SMBioctls",NULL,AS_USER},
4454 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
4455 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
4457 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
4458 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
4459 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
4460 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
4462 {SMBffirst,"SMBffirst",reply_search,AS_USER},
4463 {SMBfunique,"SMBfunique",reply_search,AS_USER},
4464 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
4466 /* LANMAN2.0 PROTOCOL FOLLOWS */
4467 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
4468 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
4469 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
4470 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
4472 /* messaging routines */
4473 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
4474 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
4475 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
4476 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
4478 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4480 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
4481 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
4482 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
4483 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
4486 /****************************************************************************
4487 return a string containing the function name of a SMB command
4488 ****************************************************************************/
4489 char *smb_fn_name(int type)
4491 static char *unknown_name = "SMBunknown";
4492 static int num_smb_messages =
4493 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4494 int match;
4496 for (match=0;match<num_smb_messages;match++)
4497 if (smb_messages[match].code == type)
4498 break;
4500 if (match == num_smb_messages)
4501 return(unknown_name);
4503 return(smb_messages[match].name);
4507 /****************************************************************************
4508 do a switch on the message type, and return the response size
4509 ****************************************************************************/
4510 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
4512 static int pid= -1;
4513 int outsize = 0;
4514 static int num_smb_messages =
4515 sizeof(smb_messages) / sizeof(struct smb_message_struct);
4516 int match;
4518 #if PROFILING
4519 struct timeval msg_start_time;
4520 struct timeval msg_end_time;
4521 static unsigned long total_time = 0;
4523 GetTimeOfDay(&msg_start_time);
4524 #endif
4526 if (pid == -1)
4527 pid = getpid();
4529 errno = 0;
4530 last_message = type;
4532 /* make sure this is an SMB packet */
4533 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
4535 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
4536 return(-1);
4539 for (match=0;match<num_smb_messages;match++)
4540 if (smb_messages[match].code == type)
4541 break;
4543 if (match == num_smb_messages)
4545 DEBUG(0,("Unknown message type %d!\n",type));
4546 outsize = reply_unknown(inbuf,outbuf);
4548 else
4550 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
4551 if (smb_messages[match].fn)
4553 int cnum = SVAL(inbuf,smb_tid);
4554 int flags = smb_messages[match].flags;
4555 uint16 session_tag = SVAL(inbuf,smb_uid);
4557 /* does this protocol need to be run as root? */
4558 if (!(flags & AS_USER))
4559 unbecome_user();
4561 /* does this protocol need to be run as the connected user? */
4562 if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
4563 if (flags & AS_GUEST)
4564 flags &= ~AS_USER;
4565 else
4566 return(ERROR(ERRSRV,ERRinvnid));
4568 /* this code is to work around a bug is MS client 3 without
4569 introducing a security hole - it needs to be able to do
4570 print queue checks as guest if it isn't logged in properly */
4571 if (flags & AS_USER)
4572 flags &= ~AS_GUEST;
4574 /* does it need write permission? */
4575 if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
4576 return(ERROR(ERRSRV,ERRaccess));
4578 /* ipc services are limited */
4579 if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
4580 return(ERROR(ERRSRV,ERRaccess));
4582 /* load service specific parameters */
4583 if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
4584 return(ERROR(ERRSRV,ERRaccess));
4586 /* does this protocol need to be run as guest? */
4587 if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
4588 return(ERROR(ERRSRV,ERRaccess));
4590 last_inbuf = inbuf;
4592 outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
4594 else
4596 outsize = reply_unknown(inbuf,outbuf);
4600 #if PROFILING
4601 GetTimeOfDay(&msg_end_time);
4602 if (!(smb_messages[match].flags & TIME_INIT))
4604 smb_messages[match].time = 0;
4605 smb_messages[match].flags |= TIME_INIT;
4608 unsigned long this_time =
4609 (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
4610 (msg_end_time.tv_usec - msg_start_time.tv_usec);
4611 smb_messages[match].time += this_time;
4612 total_time += this_time;
4614 DEBUG(2,("TIME %s %d usecs %g pct\n",
4615 smb_fn_name(type),smb_messages[match].time,
4616 (100.0*smb_messages[match].time) / total_time));
4617 #endif
4619 return(outsize);
4623 /****************************************************************************
4624 construct a chained reply and add it to the already made reply
4625 **************************************************************************/
4626 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
4628 static char *orig_inbuf;
4629 static char *orig_outbuf;
4630 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
4631 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
4632 char *inbuf2, *outbuf2;
4633 int outsize2;
4634 char inbuf_saved[smb_wct];
4635 char outbuf_saved[smb_wct];
4636 extern int chain_size;
4637 int wct = CVAL(outbuf,smb_wct);
4638 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
4640 /* maybe its not chained */
4641 if (smb_com2 == 0xFF) {
4642 CVAL(outbuf,smb_vwv0) = 0xFF;
4643 return outsize;
4646 if (chain_size == 0) {
4647 /* this is the first part of the chain */
4648 orig_inbuf = inbuf;
4649 orig_outbuf = outbuf;
4652 /* we need to tell the client where the next part of the reply will be */
4653 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
4654 CVAL(outbuf,smb_vwv0) = smb_com2;
4656 /* remember how much the caller added to the chain, only counting stuff
4657 after the parameter words */
4658 chain_size += outsize - smb_wct;
4660 /* work out pointers into the original packets. The
4661 headers on these need to be filled in */
4662 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
4663 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
4665 /* remember the original command type */
4666 smb_com1 = CVAL(orig_inbuf,smb_com);
4668 /* save the data which will be overwritten by the new headers */
4669 memcpy(inbuf_saved,inbuf2,smb_wct);
4670 memcpy(outbuf_saved,outbuf2,smb_wct);
4672 /* give the new packet the same header as the last part of the SMB */
4673 memmove(inbuf2,inbuf,smb_wct);
4675 /* create the in buffer */
4676 CVAL(inbuf2,smb_com) = smb_com2;
4678 /* create the out buffer */
4679 bzero(outbuf2,smb_size);
4680 set_message(outbuf2,0,0,True);
4681 CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
4683 memcpy(outbuf2+4,inbuf2+4,4);
4684 CVAL(outbuf2,smb_rcls) = SUCCESS;
4685 CVAL(outbuf2,smb_reh) = 0;
4686 CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
4687 means a reply */
4688 SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
4689 SSVAL(outbuf2,smb_err,SUCCESS);
4690 SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
4691 SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
4692 SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
4693 SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
4695 DEBUG(3,("Chained message\n"));
4696 show_msg(inbuf2);
4698 /* process the request */
4699 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
4700 bufsize-chain_size);
4702 /* copy the new reply and request headers over the old ones, but
4703 preserve the smb_com field */
4704 memmove(orig_outbuf,outbuf2,smb_wct);
4705 CVAL(orig_outbuf,smb_com) = smb_com1;
4707 /* restore the saved data, being careful not to overwrite any
4708 data from the reply header */
4709 memcpy(inbuf2,inbuf_saved,smb_wct);
4711 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
4712 if (ofs < 0) ofs = 0;
4713 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
4716 return outsize2;
4721 /****************************************************************************
4722 construct a reply to the incoming packet
4723 ****************************************************************************/
4724 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
4726 int type = CVAL(inbuf,smb_com);
4727 int outsize = 0;
4728 int msg_type = CVAL(inbuf,0);
4729 extern int chain_size;
4731 smb_last_time = time(NULL);
4733 chain_size = 0;
4734 chain_fnum = -1;
4735 reset_chain_pnum();
4737 bzero(outbuf,smb_size);
4739 if (msg_type != 0)
4740 return(reply_special(inbuf,outbuf));
4742 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
4743 set_message(outbuf,0,0,True);
4745 memcpy(outbuf+4,inbuf+4,4);
4746 CVAL(outbuf,smb_rcls) = SUCCESS;
4747 CVAL(outbuf,smb_reh) = 0;
4748 CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
4749 means a reply */
4750 SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
4751 SSVAL(outbuf,smb_err,SUCCESS);
4752 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
4753 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
4754 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
4755 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
4757 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
4759 outsize += chain_size;
4761 if(outsize > 4)
4762 smb_setlen(outbuf,outsize - 4);
4763 return(outsize);
4766 /****************************************************************************
4767 process commands from the client
4768 ****************************************************************************/
4769 static void process(void)
4771 extern int Client;
4773 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4774 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4775 if ((InBuffer == NULL) || (OutBuffer == NULL))
4776 return;
4778 InBuffer += SMB_ALIGNMENT;
4779 OutBuffer += SMB_ALIGNMENT;
4781 #if PRIME_NMBD
4782 DEBUG(3,("priming nmbd\n"));
4784 struct in_addr ip;
4785 ip = *interpret_addr2("localhost");
4786 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
4787 *OutBuffer = 0;
4788 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
4790 #endif
4792 /* re-initialise the timezone */
4793 TimeInit();
4795 while (True)
4797 int deadtime = lp_deadtime()*60;
4798 int counter;
4799 int last_keepalive=0;
4800 int service_load_counter = 0;
4801 BOOL got_smb = False;
4803 if (deadtime <= 0)
4804 deadtime = DEFAULT_SMBD_TIMEOUT;
4806 #if USE_READ_PREDICTION
4807 if (lp_readprediction())
4808 do_read_prediction();
4809 #endif
4811 errno = 0;
4813 for (counter=SMBD_SELECT_LOOP;
4814 !receive_message_or_smb(Client,oplock_sock,
4815 InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
4816 counter += SMBD_SELECT_LOOP)
4818 int i;
4819 time_t t;
4820 BOOL allidle = True;
4821 extern int keepalive;
4823 if (counter > 365 * 3600) /* big number of seconds. */
4825 counter = 0;
4826 service_load_counter = 0;
4829 if (smb_read_error == READ_EOF)
4831 DEBUG(3,("end of file from client\n"));
4832 return;
4835 if (smb_read_error == READ_ERROR)
4837 DEBUG(3,("receive_smb error (%s) exiting\n",
4838 strerror(errno)));
4839 return;
4842 t = time(NULL);
4844 /* become root again if waiting */
4845 unbecome_user();
4847 /* check for smb.conf reload */
4848 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
4850 service_load_counter = counter;
4852 /* reload services, if files have changed. */
4853 reload_services(True);
4856 /* automatic timeout if all connections are closed */
4857 if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
4859 DEBUG(2,("%s Closing idle connection\n",timestring()));
4860 return;
4863 if (keepalive && (counter-last_keepalive)>keepalive)
4865 struct cli_state *cli = server_client();
4866 if (!send_keepalive(Client)) {
4867 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4868 return;
4870 /* also send a keepalive to the password server if its still
4871 connected */
4872 if (cli && cli->initialised)
4873 send_keepalive(cli->fd);
4874 last_keepalive = counter;
4877 /* check for connection timeouts */
4878 for (i=0;i<MAX_CONNECTIONS;i++)
4879 if (Connections[i].open)
4881 /* close dirptrs on connections that are idle */
4882 if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
4883 dptr_idlecnum(i);
4885 if (Connections[i].num_files_open > 0 ||
4886 (t-Connections[i].lastused)<deadtime)
4887 allidle = False;
4890 if (allidle && num_connections_open>0)
4892 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4893 return;
4897 if(got_smb)
4898 process_smb(InBuffer, OutBuffer);
4899 else
4900 process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
4905 /****************************************************************************
4906 initialise connect, service and file structs
4907 ****************************************************************************/
4908 static void init_structs(void )
4910 int i;
4911 get_myname(myhostname,NULL);
4913 for (i=0;i<MAX_CONNECTIONS;i++)
4915 Connections[i].open = False;
4916 Connections[i].num_files_open=0;
4917 Connections[i].lastused=0;
4918 Connections[i].used=False;
4919 string_init(&Connections[i].user,"");
4920 string_init(&Connections[i].dirpath,"");
4921 string_init(&Connections[i].connectpath,"");
4922 string_init(&Connections[i].origpath,"");
4925 for (i=0;i<MAX_OPEN_FILES;i++)
4927 Files[i].open = False;
4928 string_init(&Files[i].name,"");
4932 for (i=0;i<MAX_OPEN_FILES;i++)
4934 file_fd_struct *fd_ptr = &FileFd[i];
4935 fd_ptr->ref_count = 0;
4936 fd_ptr->dev = (int32)-1;
4937 fd_ptr->inode = (int32)-1;
4938 fd_ptr->fd = -1;
4939 fd_ptr->fd_readonly = -1;
4940 fd_ptr->fd_writeonly = -1;
4941 fd_ptr->real_open_flags = -1;
4944 /* for RPC pipes */
4945 init_rpc_pipe_hnd();
4947 #ifdef NTDOMAIN
4948 /* for LSA handles */
4949 init_lsa_policy_hnd();
4950 #endif
4952 init_dptrs();
4955 /****************************************************************************
4956 usage on the program
4957 ****************************************************************************/
4958 static void usage(char *pname)
4960 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4962 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
4963 printf("Version %s\n",VERSION);
4964 printf("\t-D become a daemon\n");
4965 printf("\t-p port listen on the specified port\n");
4966 printf("\t-d debuglevel set the debuglevel\n");
4967 printf("\t-l log basename. Basename for log/debug files\n");
4968 printf("\t-s services file. Filename of services file\n");
4969 printf("\t-P passive only\n");
4970 printf("\t-a overwrite log file, don't append\n");
4971 printf("\n");
4975 /****************************************************************************
4976 main program
4977 ****************************************************************************/
4978 int main(int argc,char *argv[])
4980 extern BOOL append_log;
4981 /* shall I run as a daemon */
4982 BOOL is_daemon = False;
4983 int port = SMB_PORT;
4984 int opt;
4985 extern char *optarg;
4986 char pidFile[100] = { 0 };
4988 #ifdef NEED_AUTH_PARAMETERS
4989 set_auth_parameters(argc,argv);
4990 #endif
4992 #ifdef SecureWare
4993 setluid(0);
4994 #endif
4996 append_log = True;
4998 TimeInit();
5000 strcpy(debugf,SMBLOGFILE);
5002 setup_logging(argv[0],False);
5004 charset_initialise();
5006 /* make absolutely sure we run as root - to handle cases whre people
5007 are crazy enough to have it setuid */
5008 #ifdef USE_SETRES
5009 setresuid(0,0,0);
5010 #else
5011 setuid(0);
5012 seteuid(0);
5013 setuid(0);
5014 seteuid(0);
5015 #endif
5017 fault_setup(exit_server);
5018 signal(SIGTERM , SIGNAL_CAST dflt_sig);
5020 /* we want total control over the permissions on created files,
5021 so set our umask to 0 */
5022 umask(0);
5024 GetWd(OriginalDir);
5026 init_uid();
5028 /* this is for people who can't start the program correctly */
5029 while (argc > 1 && (*argv[1] != '-'))
5031 argv++;
5032 argc--;
5035 while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
5036 switch (opt)
5038 case 'f':
5039 strncpy(pidFile, optarg, sizeof(pidFile));
5040 break;
5041 case 'O':
5042 strcpy(user_socket_options,optarg);
5043 break;
5044 case 'i':
5045 strcpy(scope,optarg);
5046 break;
5047 case 'P':
5049 extern BOOL passive;
5050 passive = True;
5052 break;
5053 case 's':
5054 strcpy(servicesf,optarg);
5055 break;
5056 case 'l':
5057 strcpy(debugf,optarg);
5058 break;
5059 case 'a':
5061 extern BOOL append_log;
5062 append_log = !append_log;
5064 break;
5065 case 'D':
5066 is_daemon = True;
5067 break;
5068 case 'd':
5069 if (*optarg == 'A')
5070 DEBUGLEVEL = 10000;
5071 else
5072 DEBUGLEVEL = atoi(optarg);
5073 break;
5074 case 'p':
5075 port = atoi(optarg);
5076 break;
5077 case 'h':
5078 usage(argv[0]);
5079 exit(0);
5080 break;
5081 default:
5082 usage(argv[0]);
5083 exit(1);
5086 reopen_logs();
5088 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
5089 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5091 #ifndef NO_GETRLIMIT
5092 #ifdef RLIMIT_NOFILE
5094 struct rlimit rlp;
5095 getrlimit(RLIMIT_NOFILE, &rlp);
5096 rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
5097 setrlimit(RLIMIT_NOFILE, &rlp);
5098 getrlimit(RLIMIT_NOFILE, &rlp);
5099 DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
5101 #endif
5102 #endif
5105 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5106 getuid(),getgid(),geteuid(),getegid()));
5108 if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
5110 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5111 exit(1);
5114 init_structs();
5116 if (!reload_services(False))
5117 return(-1);
5119 codepage_initialise(lp_client_code_page());
5121 strcpy(myworkgroup, lp_workgroup());
5123 #ifndef NO_SIGNAL_TEST
5124 signal(SIGHUP,SIGNAL_CAST sig_hup);
5125 #endif
5127 DEBUG(3,("%s loaded services\n",timestring()));
5129 if (!is_daemon && !is_a_socket(0))
5131 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5132 is_daemon = True;
5135 if (is_daemon)
5137 DEBUG(3,("%s becoming a daemon\n",timestring()));
5138 become_daemon();
5141 if (!directory_exist(lp_lockdir(), NULL)) {
5142 mkdir(lp_lockdir(), 0755);
5145 if (*pidFile)
5147 int fd;
5148 char buf[20];
5150 if ((fd = open(pidFile,
5151 #ifdef O_NONBLOCK
5152 O_NONBLOCK |
5153 #endif
5154 O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
5156 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
5157 exit(1);
5159 if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
5161 DEBUG(0,("ERROR: smbd is already running\n"));
5162 exit(1);
5164 sprintf(buf, "%u\n", (unsigned int) getpid());
5165 if (write(fd, buf, strlen(buf)) < 0)
5167 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
5168 exit(1);
5170 /* Leave pid file open & locked for the duration... */
5173 if (!open_sockets(is_daemon,port))
5174 exit(1);
5176 if (!locking_init(0))
5177 exit(1);
5179 /* possibly reload the services file. */
5180 reload_services(True);
5182 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
5184 if (*lp_rootdir())
5186 if (sys_chroot(lp_rootdir()) == 0)
5187 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5190 /* Setup the oplock IPC socket. */
5191 if(!open_oplock_ipc())
5192 exit(1);
5194 process();
5195 close_sockets();
5197 exit_server("normal exit");
5198 return(0);