2 Unix SMB/Netbios implementation.
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.
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
;
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)
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 extern time_t smb_last_time
;
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;
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 */
84 /* number of open connections */
85 static int num_connections_open
= 0;
87 extern fstring remote_machine
;
91 /* these can be set by some functions to override the error codes */
92 int unix_ERR_class
=SUCCESS
;
96 extern int extra_time_offset
;
98 extern pstring myhostname
;
100 static int find_free_connection(int hash
);
102 /* for readability... */
103 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
104 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
105 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
106 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
107 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
109 /****************************************************************************
110 when exiting, take the whole family
111 ****************************************************************************/
114 exit_server("caught signal");
115 return 0; /* Keep -Wall happy :-) */
117 /****************************************************************************
118 Send a SIGTERM to our process group.
119 *****************************************************************************/
122 if(am_parent
) kill(0,SIGTERM
);
125 /****************************************************************************
126 change a dos mode to a unix mode
127 base permission for files:
128 everybody gets read bit set
129 dos readonly is represented in unix by removing everyone's write bit
130 dos archive is represented in unix by the user's execute bit
131 dos system is represented in unix by the group's execute bit
132 dos hidden is represented in unix by the other's execute bit
133 Then apply create mask,
135 base permission for directories:
136 dos directory is represented in unix by unix's dir bit and the exec bit
137 Then apply create mask,
139 ****************************************************************************/
140 mode_t
unix_mode(int cnum
,int dosmode
)
142 mode_t result
= (S_IRUSR
| S_IRGRP
| S_IROTH
);
144 if ( !IS_DOS_READONLY(dosmode
) )
145 result
|= (S_IWUSR
| S_IWGRP
| S_IWOTH
);
147 if (IS_DOS_DIR(dosmode
)) {
148 /* We never make directories read only for the owner as under DOS a user
149 can always create a file in a read-only directory. */
150 result
|= (S_IFDIR
| S_IXUSR
| S_IXGRP
| S_IXOTH
| S_IWUSR
);
151 /* Apply directory mask */
152 result
&= lp_dir_mode(SNUM(cnum
));
153 /* Add in force bits */
154 result
|= lp_force_dir_mode(SNUM(cnum
));
156 if (MAP_ARCHIVE(cnum
) && IS_DOS_ARCHIVE(dosmode
))
159 if (MAP_SYSTEM(cnum
) && IS_DOS_SYSTEM(dosmode
))
162 if (MAP_HIDDEN(cnum
) && IS_DOS_HIDDEN(dosmode
))
165 /* Apply mode mask */
166 result
&= lp_create_mode(SNUM(cnum
));
167 /* Add in force bits */
168 result
|= lp_force_create_mode(SNUM(cnum
));
174 /****************************************************************************
175 change a unix mode to a dos mode
176 ****************************************************************************/
177 int dos_mode(int cnum
,char *path
,struct stat
*sbuf
)
180 extern struct current_user current_user
;
182 if (CAN_WRITE(cnum
) && !lp_alternate_permissions(SNUM(cnum
))) {
183 if (!((sbuf
->st_mode
& S_IWOTH
) ||
184 Connections
[cnum
].admin_user
||
185 ((sbuf
->st_mode
& S_IWUSR
) && current_user
.uid
==sbuf
->st_uid
) ||
186 ((sbuf
->st_mode
& S_IWGRP
) &&
187 in_group(sbuf
->st_gid
,current_user
.gid
,
188 current_user
.ngroups
,current_user
.igroups
))))
191 if ((sbuf
->st_mode
& S_IWUSR
) == 0)
195 if ((sbuf
->st_mode
& S_IXUSR
) != 0)
198 if (MAP_SYSTEM(cnum
) && ((sbuf
->st_mode
& S_IXGRP
) != 0))
201 if (MAP_HIDDEN(cnum
) && ((sbuf
->st_mode
& S_IXOTH
) != 0))
204 if (S_ISDIR(sbuf
->st_mode
))
205 result
= aDIR
| (result
& aRONLY
);
208 if (S_ISLNK(sbuf
->st_mode
) && S_ISDIR(sbuf
->st_mode
))
212 /* hide files with a name starting with a . */
213 if (lp_hide_dot_files(SNUM(cnum
)))
215 char *p
= strrchr(path
,'/');
221 if (p
[0] == '.' && p
[1] != '.' && p
[1] != 0)
229 /*******************************************************************
230 chmod a file - but preserve some bits
231 ********************************************************************/
232 int dos_chmod(int cnum
,char *fname
,int dosmode
,struct stat
*st
)
241 if (sys_stat(fname
,st
)) return(-1);
244 if (S_ISDIR(st
->st_mode
)) dosmode
|= aDIR
;
246 if (dos_mode(cnum
,fname
,st
) == dosmode
) return(0);
248 unixmode
= unix_mode(cnum
,dosmode
);
250 /* preserve the s bits */
251 mask
|= (S_ISUID
| S_ISGID
);
253 /* preserve the t bit */
258 /* possibly preserve the x bits */
259 if (!MAP_ARCHIVE(cnum
)) mask
|= S_IXUSR
;
260 if (!MAP_SYSTEM(cnum
)) mask
|= S_IXGRP
;
261 if (!MAP_HIDDEN(cnum
)) mask
|= S_IXOTH
;
263 unixmode
|= (st
->st_mode
& mask
);
265 /* if we previously had any r bits set then leave them alone */
266 if ((tmp
= st
->st_mode
& (S_IRUSR
|S_IRGRP
|S_IROTH
))) {
267 unixmode
&= ~(S_IRUSR
|S_IRGRP
|S_IROTH
);
271 /* if we previously had any w bits set then leave them alone
272 if the new mode is not rdonly */
273 if (!IS_DOS_READONLY(dosmode
) &&
274 (tmp
= st
->st_mode
& (S_IWUSR
|S_IWGRP
|S_IWOTH
))) {
275 unixmode
&= ~(S_IWUSR
|S_IWGRP
|S_IWOTH
);
279 return(sys_chmod(fname
,unixmode
));
283 /****************************************************************************
284 check if two filenames are equal
286 this needs to be careful about whether we are case sensitive
287 ****************************************************************************/
288 static BOOL
fname_equal(char *name1
, char *name2
)
290 int l1
= strlen(name1
);
291 int l2
= strlen(name2
);
293 /* handle filenames ending in a single dot */
294 if (l1
-l2
== 1 && name1
[l1
-1] == '.' && lp_strip_dot())
298 ret
= fname_equal(name1
,name2
);
303 if (l2
-l1
== 1 && name2
[l2
-1] == '.' && lp_strip_dot())
307 ret
= fname_equal(name1
,name2
);
312 /* now normal filename handling */
314 return(strcmp(name1
,name2
) == 0);
316 return(strequal(name1
,name2
));
320 /****************************************************************************
321 mangle the 2nd name and check if it is then equal to the first name
322 ****************************************************************************/
323 static BOOL
mangled_equal(char *name1
, char *name2
)
327 if (is_8_3(name2
, True
))
330 strcpy(tmpname
,name2
);
331 mangle_name_83(tmpname
);
333 return(strequal(name1
,tmpname
));
337 /****************************************************************************
338 scan a directory to find a filename, matching without case sensitivity
340 If the name looks like a mangled name then try via the mangling functions
341 ****************************************************************************/
342 static BOOL
scan_directory(char *path
, char *name
,int snum
,BOOL docache
)
349 mangled
= is_mangled(name
);
351 /* handle null paths */
355 if (docache
&& (dname
= DirCacheCheck(path
,name
,snum
))) {
361 check_mangled_stack(name
);
363 /* open the directory */
364 if (!(cur_dir
= OpenDir(path
)))
366 DEBUG(3,("scan dir didn't open dir [%s]\n",path
));
370 /* now scan for matching names */
371 while ((dname
= ReadDirName(cur_dir
)))
374 (strequal(dname
,".") || strequal(dname
,"..")))
378 if (!name_map_mangle(name2
,False
,snum
)) continue;
380 if ((mangled
&& mangled_equal(name
,name2
))
381 || fname_equal(name
, name2
))
383 /* we've found the file, change it's name and return */
384 if (docache
) DirCacheAdd(path
,name
,dname
,snum
);
395 /****************************************************************************
396 This routine is called to convert names from the dos namespace to unix
397 namespace. It needs to handle any case conversions, mangling, format
400 We assume that we have already done a chdir() to the right "root" directory
403 The function will return False if some part of the name except for the last
404 part cannot be resolved
406 If the saved_last_component != 0, then the unmodified last component
407 of the pathname is returned there. This is used in an exceptional
408 case in reply_mv (so far). If saved_last_component == 0 then nothing
410 ****************************************************************************/
411 BOOL
unix_convert(char *name
,int cnum
,pstring saved_last_component
)
418 if(saved_last_component
)
419 *saved_last_component
= 0;
421 /* convert to basic unix format - removing \ chars and cleaning it up */
423 unix_clean_name(name
);
425 /* names must be relative to the root of the service - trim any leading /.
426 also trim trailing /'s */
427 trim_string(name
,"/","/");
430 * Ensure saved_last_component is valid even if file exists.
432 if(saved_last_component
) {
433 end
= strrchr(name
, '/');
435 strcpy(saved_last_component
, end
+ 1);
437 strcpy(saved_last_component
, name
);
440 if (!case_sensitive
&&
441 (!case_preserve
|| (is_8_3(name
, False
) && !short_case_preserve
)))
444 /* check if it's a printer file */
445 if (Connections
[cnum
].printer
)
447 if ((! *name
) || strchr(name
,'/') || !is_8_3(name
, True
))
451 sprintf(name2
,"%.6s.XXXXXX",remote_machine
);
452 /* sanitise the name */
453 for (s
=name2
; *s
; s
++)
454 if (!issafe(*s
)) *s
= '_';
455 strcpy(name
,(char *)mktemp(name2
));
460 /* stat the name - if it exists then we are all done! */
461 if (sys_stat(name
,&st
) == 0)
464 DEBUG(5,("unix_convert(%s,%d)\n",name
,cnum
));
466 /* a special case - if we don't have any mangling chars and are case
467 sensitive then searching won't help */
468 if (case_sensitive
&& !is_mangled(name
) &&
469 !lp_strip_dot() && !use_mangled_map
)
472 /* now we need to recursively match the name against the real
473 directory structure */
476 while (strncmp(start
,"./",2) == 0)
479 /* now match each part of the path name separately, trying the names
480 as is first, then trying to scan the directory for matching names */
481 for (;start
;start
= (end
?end
+1:(char *)NULL
))
483 /* pinpoint the end of this section of the filename */
484 end
= strchr(start
, '/');
486 /* chop the name at this point */
489 if(saved_last_component
!= 0)
490 strcpy(saved_last_component
, end
? end
+ 1 : start
);
492 /* check if the name exists up to this point */
493 if (sys_stat(name
, &st
) == 0)
495 /* it exists. it must either be a directory or this must be
496 the last part of the path for it to be OK */
497 if (end
&& !(st
.st_mode
& S_IFDIR
))
499 /* an intermediate part of the name isn't a directory */
500 DEBUG(5,("Not a dir %s\n",start
));
511 /* remember the rest of the pathname so it can be restored
513 if (end
) strcpy(rest
,end
+1);
515 /* try to find this part of the path in the directory */
516 if (strchr(start
,'?') || strchr(start
,'*') ||
517 !scan_directory(dirpath
, start
, SNUM(cnum
), end
?True
:False
))
521 /* an intermediate part of the name can't be found */
522 DEBUG(5,("Intermediate not found %s\n",start
));
527 /* just the last part of the name doesn't exist */
528 /* we may need to strupper() or strlower() it in case
529 this conversion is being used for file creation
531 /* if the filename is of mixed case then don't normalise it */
532 if (!case_preserve
&&
533 (!strhasupper(start
) || !strhaslower(start
)))
536 /* check on the mangled stack to see if we can recover the
537 base of the filename */
538 if (is_mangled(start
))
539 check_mangled_stack(start
);
541 DEBUG(5,("New file %s\n",start
));
545 /* restore the rest of the string */
548 strcpy(start
+strlen(start
)+1,rest
);
549 end
= start
+ strlen(start
);
553 /* add to the dirpath that we have resolved so far */
554 if (*dirpath
) strcat(dirpath
,"/");
555 strcat(dirpath
,start
);
557 /* restore the / that we wiped out earlier */
561 /* the name has been resolved */
562 DEBUG(5,("conversion finished %s\n",name
));
567 /****************************************************************************
568 normalise for DOS usage
569 ****************************************************************************/
570 static void disk_norm(int *bsize
,int *dfree
,int *dsize
)
572 /* check if the disk is beyond the max disk size */
573 int maxdisksize
= lp_maxdisksize();
575 /* convert to blocks - and don't overflow */
576 maxdisksize
= ((maxdisksize
*1024)/(*bsize
))*1024;
577 if (*dsize
> maxdisksize
) *dsize
= maxdisksize
;
578 if (*dfree
> maxdisksize
) *dfree
= maxdisksize
-1; /* the -1 should stop
583 while (*dfree
> WORDMAX
|| *dsize
> WORDMAX
|| *bsize
< 512)
588 if (*bsize
> WORDMAX
)
591 if (*dsize
> WORDMAX
)
593 if (*dfree
> WORDMAX
)
600 /****************************************************************************
601 return number of 1K blocks available on a path and total number
602 ****************************************************************************/
603 int disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
605 char *df_command
= lp_dfree_command();
619 if (disk_quotas(path
, bsize
, dfree
, dsize
))
621 disk_norm(bsize
,dfree
,dsize
);
622 return(((*bsize
)/1024)*(*dfree
));
627 /* possibly use system() to get the result */
628 if (df_command
&& *df_command
)
634 sprintf(outfile
,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
635 sprintf(syscmd
,"%s %s",df_command
,path
);
636 standard_sub_basic(syscmd
);
638 ret
= smbrun(syscmd
,outfile
,False
);
639 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
642 FILE *f
= fopen(outfile
,"r");
648 fscanf(f
,"%d %d %d",dsize
,dfree
,bsize
);
652 DEBUG(0,("Can't open %s\n",outfile
));
656 disk_norm(bsize
,dfree
,dsize
);
657 return(((*bsize
)/1024)*(*dfree
));
661 DEBUG(1,("Warning - no statfs function\n"));
665 if (statfs(path
,&fs
,sizeof(fs
),0) != 0)
668 if (statvfs(path
, &fs
))
671 if (statfs(path
,&fs
,sizeof(fs
)) == -1)
673 if (statfs(path
,&fs
) == -1)
675 #endif /* USE_STATVFS */
678 DEBUG(3,("dfree call failed code errno=%d\n",errno
));
682 return(((*bsize
)/1024)*(*dfree
));
687 *dfree
= fs
.fd_req
.bfree
;
688 *dsize
= fs
.fd_req
.btot
;
691 *bsize
= fs
.f_frsize
;
694 /* eg: osf1 has f_fsize = fundamental filesystem block size,
695 f_bsize = optimal transfer block size (MX: 94-04-19) */
700 #endif /* USE_STATVFS */
705 *dfree
= fs
.f_bavail
;
707 *dsize
= fs
.f_blocks
;
710 #if defined(SCO) || defined(ISC) || defined(MIPS)
714 /* handle rediculous bsize values - some OSes are broken */
715 if ((*bsize
) < 512 || (*bsize
)>0xFFFF) *bsize
= 1024;
717 disk_norm(bsize
,dfree
,dsize
);
723 DEBUG(0,("dfree seems to be broken on your system\n"));
724 *dsize
= 20*1024*1024/(*bsize
);
725 *dfree
= MAX(1,*dfree
);
727 return(((*bsize
)/1024)*(*dfree
));
732 /****************************************************************************
733 wrap it to get filenames right
734 ****************************************************************************/
735 int sys_disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
737 return(disk_free(dos_to_unix(path
,False
),bsize
,dfree
,dsize
));
742 /****************************************************************************
743 check a filename - possibly caling reducename
745 This is called by every routine before it allows an operation on a filename.
746 It does any final confirmation necessary to ensure that the filename is
747 a valid one for the user to access.
748 ****************************************************************************/
749 BOOL
check_name(char *name
,int cnum
)
755 if( is_vetoed_path(name
))
757 DEBUG(5,("file path name %s vetoed\n",name
));
761 ret
= reduce_name(name
,Connections
[cnum
].connectpath
,lp_widelinks(SNUM(cnum
)));
763 DEBUG(5,("check_name on %s failed\n",name
));
768 /****************************************************************************
769 check a filename - possibly caling reducename
770 ****************************************************************************/
771 static void check_for_pipe(char *fname
)
773 /* special case of pipe opens */
777 if (strstr(s
,"pipe/"))
779 DEBUG(3,("Rejecting named pipe open for %s\n",fname
));
780 unix_ERR_class
= ERRSRV
;
781 unix_ERR_code
= ERRaccess
;
785 /****************************************************************************
786 fd support routines - attempt to do a sys_open
787 ****************************************************************************/
789 int fd_attempt_open(char *fname
, int flags
, int mode
)
791 int fd
= sys_open(fname
,flags
,mode
);
793 /* Fix for files ending in '.' */
794 if((fd
== -1) && (errno
== ENOENT
) &&
795 (strchr(fname
,'.')==NULL
))
798 fd
= sys_open(fname
,flags
,mode
);
801 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
802 if ((fd
== -1) && (errno
== ENAMETOOLONG
))
805 char *p
= strrchr(fname
, '/');
807 if (p
== fname
) /* name is "/xxx" */
809 max_len
= pathconf("/", _PC_NAME_MAX
);
812 else if ((p
== NULL
) || (p
== fname
))
815 max_len
= pathconf(".", _PC_NAME_MAX
);
820 max_len
= pathconf(fname
, _PC_NAME_MAX
);
824 if (strlen(p
) > max_len
)
826 char tmp
= p
[max_len
];
829 if ((fd
= sys_open(fname
,flags
,mode
)) == -1)
837 /****************************************************************************
838 fd support routines - attempt to find an already open file by dev
839 and inode - increments the ref_count of the returned file_fd_struct *.
840 ****************************************************************************/
841 file_fd_struct
*fd_get_already_open(struct stat
*sbuf
)
844 file_fd_struct
*fd_ptr
;
849 for(i
= 0; i
<= max_file_fd_used
; i
++) {
851 if((fd_ptr
->ref_count
> 0) &&
852 (((uint32
)sbuf
->st_dev
) == fd_ptr
->dev
) &&
853 (((uint32
)sbuf
->st_ino
) == fd_ptr
->inode
)) {
856 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
857 i
, fd_ptr
->dev
, fd_ptr
->inode
, fd_ptr
->ref_count
));
864 /****************************************************************************
865 fd support routines - attempt to find a empty slot in the FileFd array.
866 Increments the ref_count of the returned entry.
867 ****************************************************************************/
868 file_fd_struct
*fd_get_new()
871 file_fd_struct
*fd_ptr
;
873 for(i
= 0; i
< MAX_OPEN_FILES
; i
++) {
875 if(fd_ptr
->ref_count
== 0) {
876 fd_ptr
->dev
= (uint32
)-1;
877 fd_ptr
->inode
= (uint32
)-1;
879 fd_ptr
->fd_readonly
= -1;
880 fd_ptr
->fd_writeonly
= -1;
881 fd_ptr
->real_open_flags
= -1;
883 /* Increment max used counter if neccessary, cuts down
884 on search time when re-using */
885 if(i
> max_file_fd_used
)
886 max_file_fd_used
= i
;
887 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
888 i
, fd_ptr
->dev
, fd_ptr
->inode
));
892 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
897 /****************************************************************************
898 fd support routines - attempt to re-open an already open fd as O_RDWR.
899 Save the already open fd (we cannot close due to POSIX file locking braindamage.
900 ****************************************************************************/
902 void fd_attempt_reopen(char *fname
, int mode
, file_fd_struct
*fd_ptr
)
904 int fd
= sys_open( fname
, O_RDWR
, mode
);
909 if(fd_ptr
->real_open_flags
== O_RDONLY
)
910 fd_ptr
->fd_readonly
= fd_ptr
->fd
;
911 if(fd_ptr
->real_open_flags
== O_WRONLY
)
912 fd_ptr
->fd_writeonly
= fd_ptr
->fd
;
915 fd_ptr
->real_open_flags
= O_RDWR
;
918 /****************************************************************************
919 fd support routines - attempt to close the file referenced by this fd.
920 Decrements the ref_count and returns it.
921 ****************************************************************************/
922 int fd_attempt_close(file_fd_struct
*fd_ptr
)
924 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
926 fd_ptr
->fd
, fd_ptr
->dev
, fd_ptr
->inode
,
927 fd_ptr
->real_open_flags
,
929 if(fd_ptr
->ref_count
> 0) {
931 if(fd_ptr
->ref_count
== 0) {
934 if(fd_ptr
->fd_readonly
!= -1)
935 close(fd_ptr
->fd_readonly
);
936 if(fd_ptr
->fd_writeonly
!= -1)
937 close(fd_ptr
->fd_writeonly
);
939 fd_ptr
->fd_readonly
= -1;
940 fd_ptr
->fd_writeonly
= -1;
941 fd_ptr
->real_open_flags
= -1;
942 fd_ptr
->dev
= (uint32
)-1;
943 fd_ptr
->inode
= (uint32
)-1;
946 return fd_ptr
->ref_count
;
949 /****************************************************************************
951 ****************************************************************************/
952 static void open_file(int fnum
,int cnum
,char *fname1
,int flags
,int mode
, struct stat
*sbuf
)
954 extern struct current_user current_user
;
957 file_fd_struct
*fd_ptr
;
959 Files
[fnum
].open
= False
;
960 Files
[fnum
].fd_ptr
= 0;
963 strcpy(fname
,fname1
);
965 /* check permissions */
966 if ((flags
!= O_RDONLY
) && !CAN_WRITE(cnum
) && !Connections
[cnum
].printer
)
968 DEBUG(3,("Permission denied opening %s\n",fname
));
969 check_for_pipe(fname
);
973 /* this handles a bug in Win95 - it doesn't say to create the file when it
975 if (Connections
[cnum
].printer
)
979 if (flags == O_WRONLY)
980 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
984 /* XXXX - is this OK?? */
985 /* this works around a utime bug but can cause other problems */
986 if ((flags
& (O_WRONLY
|O_RDWR
)) && (flags
& O_CREAT
) && !(flags
& O_APPEND
))
991 * Ensure we have a valid struct stat so we can search the
995 if(stat(fname
, &statbuf
) < 0) {
996 if(errno
!= ENOENT
) {
997 DEBUG(3,("Error doing stat on file %s (%s)\n",
998 fname
,strerror(errno
)));
1000 check_for_pipe(fname
);
1010 * Check to see if we have this file already
1011 * open. If we do, just use the already open fd and increment the
1012 * reference count (fd_get_already_open increments the ref_count).
1014 if((fd_ptr
= fd_get_already_open(sbuf
))!= 0) {
1016 int accmode
= (flags
& (O_RDONLY
| O_WRONLY
| O_RDWR
));
1018 /* File was already open. */
1019 if((flags
& O_CREAT
) && (flags
& O_EXCL
)) {
1020 fd_ptr
->ref_count
--;
1026 * If not opened O_RDWR try
1027 * and do that here - a chmod may have been done
1028 * between the last open and now.
1030 if(fd_ptr
->real_open_flags
!= O_RDWR
)
1031 fd_attempt_reopen(fname
, mode
, fd_ptr
);
1034 * Ensure that if we wanted write access
1035 * it has been opened for write, and if we wanted read it
1036 * was open for read.
1038 if(((accmode
== O_WRONLY
) && (fd_ptr
->real_open_flags
== O_RDONLY
)) ||
1039 ((accmode
== O_RDONLY
) && (fd_ptr
->real_open_flags
== O_WRONLY
)) ||
1040 ((accmode
== O_RDWR
) && (fd_ptr
->real_open_flags
!= O_RDWR
))) {
1041 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1042 fd_ptr
->real_open_flags
, fname
,strerror(EACCES
),flags
));
1043 check_for_pipe(fname
);
1044 fd_ptr
->ref_count
--;
1050 /* We need to allocate a new file_fd_struct (this increments the
1052 if((fd_ptr
= fd_get_new()) == 0)
1055 * Whatever the requested flags, attempt read/write access,
1056 * as we don't know what flags future file opens may require.
1057 * If this fails, try again with the required flags.
1058 * Even if we open read/write when only read access was
1059 * requested the setting of the can_write flag in
1060 * the file_struct will protect us from errant
1061 * write requests. We never need to worry about O_APPEND
1062 * as this is not set anywhere in Samba.
1064 fd_ptr
->real_open_flags
= O_RDWR
;
1065 /* Set the flags as needed without the read/write modes. */
1066 open_flags
= flags
& ~(O_RDWR
|O_WRONLY
|O_RDONLY
);
1067 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDWR
, mode
);
1069 * On some systems opening a file for R/W access on a read only
1070 * filesystems sets errno to EROFS.
1073 if((fd_ptr
->fd
== -1) && ((errno
== EACCES
) || (errno
== EROFS
))) {
1074 #else /* No EROFS */
1075 if((fd_ptr
->fd
== -1) && (errno
== EACCES
)) {
1077 if(flags
& O_WRONLY
) {
1078 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_WRONLY
, mode
);
1079 fd_ptr
->real_open_flags
= O_WRONLY
;
1081 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDONLY
, mode
);
1082 fd_ptr
->real_open_flags
= O_RDONLY
;
1087 if ((fd_ptr
->fd
>=0) &&
1088 Connections
[cnum
].printer
&& lp_minprintspace(SNUM(cnum
))) {
1092 strcpy(dname
,fname
);
1093 p
= strrchr(dname
,'/');
1095 if (sys_disk_free(dname
,&dum1
,&dum2
,&dum3
) <
1096 lp_minprintspace(SNUM(cnum
))) {
1097 fd_attempt_close(fd_ptr
);
1098 Files
[fnum
].fd_ptr
= 0;
1099 if(fd_ptr
->ref_count
== 0)
1108 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1109 fname
,strerror(errno
),flags
));
1110 /* Ensure the ref_count is decremented. */
1111 fd_attempt_close(fd_ptr
);
1112 check_for_pipe(fname
);
1116 if (fd_ptr
->fd
>= 0)
1120 if(fstat(fd_ptr
->fd
, &statbuf
) == -1) {
1121 /* Error - backout !! */
1122 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1123 fd_ptr
->fd
, fname
,strerror(errno
)));
1124 /* Ensure the ref_count is decremented. */
1125 fd_attempt_close(fd_ptr
);
1130 /* Set the correct entries in fd_ptr. */
1131 fd_ptr
->dev
= (uint32
)sbuf
->st_dev
;
1132 fd_ptr
->inode
= (uint32
)sbuf
->st_ino
;
1134 Files
[fnum
].fd_ptr
= fd_ptr
;
1135 Connections
[cnum
].num_files_open
++;
1136 Files
[fnum
].mode
= sbuf
->st_mode
;
1137 GetTimeOfDay(&Files
[fnum
].open_time
);
1138 Files
[fnum
].uid
= current_user
.id
;
1139 Files
[fnum
].size
= 0;
1140 Files
[fnum
].pos
= -1;
1141 Files
[fnum
].open
= True
;
1142 Files
[fnum
].mmap_ptr
= NULL
;
1143 Files
[fnum
].mmap_size
= 0;
1144 Files
[fnum
].can_lock
= True
;
1145 Files
[fnum
].can_read
= ((flags
& O_WRONLY
)==0);
1146 Files
[fnum
].can_write
= ((flags
& (O_WRONLY
|O_RDWR
))!=0);
1147 Files
[fnum
].share_mode
= 0;
1148 Files
[fnum
].print_file
= Connections
[cnum
].printer
;
1149 Files
[fnum
].modified
= False
;
1150 Files
[fnum
].cnum
= cnum
;
1151 string_set(&Files
[fnum
].name
,dos_to_unix(fname
,False
));
1152 Files
[fnum
].wbmpx_ptr
= NULL
;
1155 * If the printer is marked as postscript output a leading
1156 * file identifier to ensure the file is treated as a raw
1158 * This has a similar effect as CtrlD=0 in WIN.INI file.
1159 * tim@fsg.com 09/06/94
1161 if (Files
[fnum
].print_file
&& POSTSCRIPT(cnum
) &&
1162 Files
[fnum
].can_write
)
1164 DEBUG(3,("Writing postscript line\n"));
1165 write_file(fnum
,"%!\n",3);
1168 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1169 timestring(),Connections
[cnum
].user
,fname
,
1170 BOOLSTR(Files
[fnum
].can_read
),BOOLSTR(Files
[fnum
].can_write
),
1171 Connections
[cnum
].num_files_open
,fnum
));
1176 /* mmap it if read-only */
1177 if (!Files
[fnum
].can_write
)
1179 Files
[fnum
].mmap_size
= file_size(fname
);
1180 Files
[fnum
].mmap_ptr
= (char *)mmap(NULL
,Files
[fnum
].mmap_size
,
1181 PROT_READ
,MAP_SHARED
,Files
[fnum
].fd_ptr
->fd
,0);
1183 if (Files
[fnum
].mmap_ptr
== (char *)-1 || !Files
[fnum
].mmap_ptr
)
1185 DEBUG(3,("Failed to mmap() %s - %s\n",fname
,strerror(errno
)));
1186 Files
[fnum
].mmap_ptr
= NULL
;
1192 /*******************************************************************
1194 ********************************************************************/
1195 void sync_file(int fnum
)
1198 fsync(Files
[fnum
].fd_ptr
->fd
);
1202 /****************************************************************************
1203 run a file if it is a magic script
1204 ****************************************************************************/
1205 static void check_magic(int fnum
,int cnum
)
1207 if (!*lp_magicscript(SNUM(cnum
)))
1210 DEBUG(5,("checking magic for %s\n",Files
[fnum
].name
));
1214 if (!(p
= strrchr(Files
[fnum
].name
,'/')))
1215 p
= Files
[fnum
].name
;
1219 if (!strequal(lp_magicscript(SNUM(cnum
)),p
))
1225 pstring magic_output
;
1227 strcpy(fname
,Files
[fnum
].name
);
1229 if (*lp_magicoutput(SNUM(cnum
)))
1230 strcpy(magic_output
,lp_magicoutput(SNUM(cnum
)));
1232 sprintf(magic_output
,"%s.out",fname
);
1235 ret
= smbrun(fname
,magic_output
,False
);
1236 DEBUG(3,("Invoking magic command %s gave %d\n",fname
,ret
));
1242 /****************************************************************************
1243 close a file - possibly invalidating the read prediction
1244 ****************************************************************************/
1245 void close_file(int fnum
)
1247 files_struct
*fs_p
= &Files
[fnum
];
1248 int cnum
= fs_p
->cnum
;
1249 uint32 dev
= fs_p
->fd_ptr
->dev
;
1250 uint32 inode
= fs_p
->fd_ptr
->inode
;
1251 share_lock_token token
;
1253 invalidate_read_prediction(fs_p
->fd_ptr
->fd
);
1255 Connections
[cnum
].num_files_open
--;
1258 free((char *)fs_p
->wbmpx_ptr
);
1259 fs_p
->wbmpx_ptr
= NULL
;
1265 munmap(fs_p
->mmap_ptr
,fs_p
->mmap_size
);
1266 fs_p
->mmap_ptr
= NULL
;
1270 if (lp_share_modes(SNUM(cnum
)))
1272 lock_share_entry( cnum
, dev
, inode
, &token
);
1273 del_share_mode(token
, fnum
);
1276 fd_attempt_close(fs_p
->fd_ptr
);
1278 if (lp_share_modes(SNUM(cnum
)))
1279 unlock_share_entry( cnum
, dev
, inode
, token
);
1281 /* NT uses smbclose to start a print - weird */
1282 if (fs_p
->print_file
)
1285 /* check for magic scripts */
1286 check_magic(fnum
,cnum
);
1288 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1289 timestring(),Connections
[cnum
].user
,fs_p
->name
,
1290 Connections
[cnum
].num_files_open
));
1293 enum {AFAIL
,AREAD
,AWRITE
,AALL
};
1295 /*******************************************************************
1296 reproduce the share mode access table
1297 ********************************************************************/
1298 static int access_table(int new_deny
,int old_deny
,int old_mode
,
1299 int share_pid
,char *fname
)
1301 if (new_deny
== DENY_ALL
|| old_deny
== DENY_ALL
) return(AFAIL
);
1303 if (new_deny
== DENY_DOS
|| old_deny
== DENY_DOS
) {
1304 if (old_deny
== new_deny
&& share_pid
== getpid())
1307 if (old_mode
== 0) return(AREAD
);
1309 /* the new smbpub.zip spec says that if the file extension is
1310 .com, .dll, .exe or .sym then allow the open. I will force
1311 it to read-only as this seems sensible although the spec is
1312 a little unclear on this. */
1313 if ((fname
= strrchr(fname
,'.'))) {
1314 if (strequal(fname
,".com") ||
1315 strequal(fname
,".dll") ||
1316 strequal(fname
,".exe") ||
1317 strequal(fname
,".sym"))
1327 if (old_deny
==DENY_WRITE
&& old_mode
==0) return(AREAD
);
1328 if (old_deny
==DENY_READ
&& old_mode
==0) return(AWRITE
);
1329 if (old_deny
==DENY_NONE
&& old_mode
==0) return(AALL
);
1332 if (old_deny
==DENY_WRITE
&& old_mode
==1) return(AREAD
);
1333 if (old_deny
==DENY_READ
&& old_mode
==1) return(AWRITE
);
1334 if (old_deny
==DENY_NONE
&& old_mode
==1) return(AALL
);
1337 if (old_deny
==DENY_WRITE
) return(AREAD
);
1338 if (old_deny
==DENY_READ
) return(AWRITE
);
1339 if (old_deny
==DENY_NONE
) return(AALL
);
1345 /*******************************************************************
1346 check if the share mode on a file allows it to be deleted or unlinked
1347 return True if sharing doesn't prevent the operation
1348 ********************************************************************/
1349 BOOL
check_file_sharing(int cnum
,char *fname
)
1353 min_share_mode_entry
*old_shares
= 0;
1354 int num_share_modes
;
1356 share_lock_token token
;
1359 if(!lp_share_modes(SNUM(cnum
)))
1362 if (stat(fname
,&sbuf
) == -1) return(True
);
1364 lock_share_entry(cnum
, (uint32
)sbuf
.st_dev
, (uint32
)sbuf
.st_ino
, &token
);
1365 num_share_modes
= get_share_modes(cnum
, token
,
1366 (uint32
)sbuf
.st_dev
, (uint32
)sbuf
.st_ino
, &old_shares
);
1368 for( i
= 0; i
< num_share_modes
; i
++)
1370 if (old_shares
[i
].share_mode
!= DENY_DOS
)
1373 if(old_shares
[i
].pid
!= pid
)
1377 /* XXXX exactly what share mode combinations should be allowed for
1378 deleting/renaming? */
1379 /* If we got here then either there were no share modes or
1380 all share modes were DENY_DOS and the pid == getpid() */
1385 unlock_share_entry(cnum
, (uint32
)sbuf
.st_dev
, (uint32
)sbuf
.st_ino
, token
);
1386 if(old_shares
!= NULL
)
1387 free((char *)old_shares
);
1391 /****************************************************************************
1393 Helper for open_file_shared.
1394 Truncate a file after checking locking; close file if locked.
1395 **************************************************************************/
1396 static void truncate_unless_locked(int fnum
, int cnum
, share_lock_token token
,
1399 if (Files
[fnum
].can_write
){
1400 if (is_locked(fnum
,cnum
,0x3FFFFFFF,0)){
1401 /* If share modes are in force for this connection we
1402 have the share entry locked. Unlock it before closing. */
1403 if (*share_locked
&& lp_share_modes(SNUM(cnum
)))
1404 unlock_share_entry( cnum
, Files
[fnum
].fd_ptr
->dev
,
1405 Files
[fnum
].fd_ptr
->inode
, token
);
1407 /* Share mode no longer locked. */
1408 *share_locked
= False
;
1410 unix_ERR_class
= ERRDOS
;
1411 unix_ERR_code
= ERRlock
;
1414 ftruncate(Files
[fnum
].fd_ptr
->fd
,0);
1419 /****************************************************************************
1420 open a file with a share mode
1421 ****************************************************************************/
1422 void open_file_shared(int fnum
,int cnum
,char *fname
,int share_mode
,int ofun
,
1423 int mode
,int *Access
,int *action
)
1425 files_struct
*fs_p
= &Files
[fnum
];
1428 int deny_mode
= (share_mode
>>4)&7;
1430 BOOL file_existed
= file_exist(fname
,&sbuf
);
1431 BOOL share_locked
= False
;
1432 BOOL fcbopen
= False
;
1433 share_lock_token token
;
1440 /* this is for OS/2 EAs - try and say we don't support them */
1441 if (strstr(fname
,".+,;=[]."))
1443 unix_ERR_class
= ERRDOS
;
1444 unix_ERR_code
= ERROR_EAS_NOT_SUPPORTED
;
1448 if ((ofun
& 0x3) == 0 && file_existed
)
1456 if ((ofun
& 0x3) == 2)
1459 /* note that we ignore the append flag as
1460 append does not mean the same thing under dos and unix */
1462 switch (share_mode
&0xF)
1479 if (flags
!= O_RDONLY
&& file_existed
&&
1480 (!CAN_WRITE(cnum
) || IS_DOS_READONLY(dos_mode(cnum
,fname
,&sbuf
))))
1490 if (deny_mode
> DENY_NONE
&& deny_mode
!=DENY_FCB
)
1492 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode
,fname
));
1497 if (deny_mode
== DENY_FCB
) deny_mode
= DENY_DOS
;
1499 if (lp_share_modes(SNUM(cnum
)))
1503 min_share_mode_entry
*old_shares
= 0;
1508 dev
= (uint32
)sbuf
.st_dev
;
1509 inode
= (uint32
)sbuf
.st_ino
;
1510 lock_share_entry(cnum
, dev
, inode
, &token
);
1511 share_locked
= True
;
1512 num_shares
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1515 for(i
= 0; i
< num_shares
; i
++)
1517 /* someone else has a share lock on it, check to see
1519 int old_open_mode
= old_shares
[i
].share_mode
&0xF;
1520 int old_deny_mode
= (old_shares
[i
].share_mode
>>4)&7;
1522 if (deny_mode
> 4 || old_deny_mode
> 4 || old_open_mode
> 2)
1524 DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
1525 deny_mode
,old_deny_mode
,old_open_mode
,fname
));
1526 free((char *)old_shares
);
1528 unlock_share_entry(cnum
, dev
, inode
, token
);
1530 unix_ERR_class
= ERRDOS
;
1531 unix_ERR_code
= ERRbadshare
;
1536 int access_allowed
= access_table(deny_mode
,old_deny_mode
,old_open_mode
,
1537 old_shares
[i
].pid
,fname
);
1539 if ((access_allowed
== AFAIL
) ||
1540 (!fcbopen
&& (access_allowed
== AREAD
&& flags
== O_RDWR
)) ||
1541 (access_allowed
== AREAD
&& flags
== O_WRONLY
) ||
1542 (access_allowed
== AWRITE
&& flags
== O_RDONLY
))
1544 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1545 deny_mode
,old_deny_mode
,old_open_mode
,
1546 old_shares
[i
].pid
,fname
,
1548 free((char *)old_shares
);
1550 unlock_share_entry(cnum
, dev
, inode
, token
);
1552 unix_ERR_class
= ERRDOS
;
1553 unix_ERR_code
= ERRbadshare
;
1557 if (access_allowed
== AREAD
)
1560 if (access_allowed
== AWRITE
)
1565 free((char *)old_shares
);
1568 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1569 flags
,flags2
,mode
));
1571 open_file(fnum
,cnum
,fname
,flags
|(flags2
&~(O_TRUNC
)),mode
,file_existed
? &sbuf
: 0);
1572 if (!fs_p
->open
&& flags
==O_RDWR
&& errno
!=ENOENT
&& fcbopen
)
1575 open_file(fnum
,cnum
,fname
,flags
,mode
,file_existed
? &sbuf
: 0 );
1582 if((share_locked
== False
) && lp_share_modes(SNUM(cnum
)))
1584 /* We created the file - thus we must now lock the share entry before creating it. */
1585 dev
= fs_p
->fd_ptr
->dev
;
1586 inode
= fs_p
->fd_ptr
->inode
;
1587 lock_share_entry(cnum
, dev
, inode
, &token
);
1588 share_locked
= True
;
1604 fs_p
->share_mode
= (deny_mode
<<4) | open_mode
;
1607 (*Access
) = open_mode
;
1611 if (file_existed
&& !(flags2
& O_TRUNC
)) *action
= 1;
1612 if (!file_existed
) *action
= 2;
1613 if (file_existed
&& (flags2
& O_TRUNC
)) *action
= 3;
1615 /* We must create the share mode entry before truncate as
1616 truncate can fail due to locking and have to close the
1617 file (which expects the share_mode_entry to be there).
1619 if (lp_share_modes(SNUM(cnum
)))
1620 set_share_mode(token
, fnum
);
1622 if ((flags2
&O_TRUNC
) && file_existed
)
1623 truncate_unless_locked(fnum
,cnum
,token
,&share_locked
);
1626 if (share_locked
&& lp_share_modes(SNUM(cnum
)))
1627 unlock_share_entry( cnum
, dev
, inode
, token
);
1630 /****************************************************************************
1631 seek a file. Try to avoid the seek if possible
1632 ****************************************************************************/
1633 int seek_file(int fnum
,int pos
)
1636 if (Files
[fnum
].print_file
&& POSTSCRIPT(Files
[fnum
].cnum
))
1639 Files
[fnum
].pos
= lseek(Files
[fnum
].fd_ptr
->fd
,pos
+offset
,SEEK_SET
) - offset
;
1640 return(Files
[fnum
].pos
);
1643 /****************************************************************************
1645 ****************************************************************************/
1646 int read_file(int fnum
,char *data
,int pos
,int n
)
1650 if (!Files
[fnum
].can_write
)
1652 ret
= read_predict(Files
[fnum
].fd_ptr
->fd
,pos
,data
,NULL
,n
);
1660 if (Files
[fnum
].mmap_ptr
)
1662 int num
= MIN(n
,Files
[fnum
].mmap_size
-pos
);
1665 memcpy(data
,Files
[fnum
].mmap_ptr
+pos
,num
);
1677 if (seek_file(fnum
,pos
) != pos
)
1679 DEBUG(3,("Failed to seek to %d\n",pos
));
1684 readret
= read(Files
[fnum
].fd_ptr
->fd
,data
,n
);
1685 if (readret
> 0) ret
+= readret
;
1692 /****************************************************************************
1694 ****************************************************************************/
1695 int write_file(int fnum
,char *data
,int n
)
1697 if (!Files
[fnum
].can_write
) {
1702 if (!Files
[fnum
].modified
) {
1704 Files
[fnum
].modified
= True
;
1705 if (fstat(Files
[fnum
].fd_ptr
->fd
,&st
) == 0) {
1706 int dosmode
= dos_mode(Files
[fnum
].cnum
,Files
[fnum
].name
,&st
);
1707 if (MAP_ARCHIVE(Files
[fnum
].cnum
) && !IS_DOS_ARCHIVE(dosmode
)) {
1708 dos_chmod(Files
[fnum
].cnum
,Files
[fnum
].name
,dosmode
| aARCH
,&st
);
1713 return(write_data(Files
[fnum
].fd_ptr
->fd
,data
,n
));
1717 /****************************************************************************
1718 load parameters specific to a connection/service
1719 ****************************************************************************/
1720 BOOL
become_service(int cnum
,BOOL do_chdir
)
1722 extern char magic_char
;
1723 static int last_cnum
= -1;
1726 if (!OPEN_CNUM(cnum
))
1732 Connections
[cnum
].lastused
= smb_last_time
;
1737 ChDir(Connections
[cnum
].connectpath
) != 0 &&
1738 ChDir(Connections
[cnum
].origpath
) != 0)
1740 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
1741 Connections
[cnum
].connectpath
,cnum
));
1745 if (cnum
== last_cnum
)
1750 case_default
= lp_defaultcase(snum
);
1751 case_preserve
= lp_preservecase(snum
);
1752 short_case_preserve
= lp_shortpreservecase(snum
);
1753 case_mangle
= lp_casemangle(snum
);
1754 case_sensitive
= lp_casesensitive(snum
);
1755 magic_char
= lp_magicchar(snum
);
1756 use_mangled_map
= (*lp_mangled_map(snum
) ? True
:False
);
1761 /****************************************************************************
1762 find a service entry
1763 ****************************************************************************/
1764 int find_service(char *service
)
1768 string_sub(service
,"\\","/");
1770 iService
= lp_servicenumber(service
);
1772 /* now handle the special case of a home directory */
1775 char *phome_dir
= get_home_dir(service
);
1776 DEBUG(3,("checking for home directory %s gave %s\n",service
,
1777 phome_dir
?phome_dir
:"(NULL)"));
1781 if ((iHomeService
= lp_servicenumber(HOMES_NAME
)) >= 0)
1783 lp_add_home(service
,iHomeService
,phome_dir
);
1784 iService
= lp_servicenumber(service
);
1789 /* If we still don't have a service, attempt to add it as a printer. */
1792 int iPrinterService
;
1794 if ((iPrinterService
= lp_servicenumber(PRINTERS_NAME
)) >= 0)
1798 DEBUG(3,("checking whether %s is a valid printer name...\n", service
));
1800 if ((pszTemp
!= NULL
) && pcap_printername_ok(service
, pszTemp
))
1802 DEBUG(3,("%s is a valid printer name\n", service
));
1803 DEBUG(3,("adding %s as a printer service\n", service
));
1804 lp_add_printer(service
,iPrinterService
);
1805 iService
= lp_servicenumber(service
);
1807 DEBUG(0,("failed to add %s as a printer service!\n", service
));
1810 DEBUG(3,("%s is not a valid printer name\n", service
));
1814 /* just possibly it's a default service? */
1817 char *defservice
= lp_defaultservice();
1818 if (defservice
&& *defservice
&& !strequal(defservice
,service
)) {
1819 iService
= find_service(defservice
);
1820 if (iService
>= 0) {
1821 string_sub(service
,"_","/");
1822 iService
= lp_add_service(service
,iService
);
1828 if (!VALID_SNUM(iService
))
1830 DEBUG(0,("Invalid snum %d for %s\n",iService
,service
));
1835 DEBUG(3,("find_service() failed to find service %s\n", service
));
1841 /****************************************************************************
1842 create an error packet from a cached error.
1843 ****************************************************************************/
1844 int cached_error_packet(char *inbuf
,char *outbuf
,int fnum
,int line
)
1846 write_bmpx_struct
*wbmpx
= Files
[fnum
].wbmpx_ptr
;
1848 int32 eclass
= wbmpx
->wr_errclass
;
1849 int32 err
= wbmpx
->wr_error
;
1851 /* We can now delete the auxiliary struct */
1852 free((char *)wbmpx
);
1853 Files
[fnum
].wbmpx_ptr
= NULL
;
1854 return error_packet(inbuf
,outbuf
,eclass
,err
,line
);
1863 } unix_smb_errmap
[] =
1865 {EPERM
,ERRDOS
,ERRnoaccess
},
1866 {EACCES
,ERRDOS
,ERRnoaccess
},
1867 {ENOENT
,ERRDOS
,ERRbadfile
},
1868 {EIO
,ERRHRD
,ERRgeneral
},
1869 {EBADF
,ERRSRV
,ERRsrverror
},
1870 {EINVAL
,ERRSRV
,ERRsrverror
},
1871 {EEXIST
,ERRDOS
,ERRfilexists
},
1872 {ENFILE
,ERRDOS
,ERRnofids
},
1873 {EMFILE
,ERRDOS
,ERRnofids
},
1874 {ENOSPC
,ERRHRD
,ERRdiskfull
},
1876 {EDQUOT
,ERRHRD
,ERRdiskfull
},
1879 {ENOTEMPTY
,ERRDOS
,ERRnoaccess
},
1882 {EXDEV
,ERRDOS
,ERRdiffdevice
},
1884 {EROFS
,ERRHRD
,ERRnowrite
},
1889 /****************************************************************************
1890 create an error packet from errno
1891 ****************************************************************************/
1892 int unix_error_packet(char *inbuf
,char *outbuf
,int def_class
,uint32 def_code
,int line
)
1894 int eclass
=def_class
;
1898 if (unix_ERR_class
!= SUCCESS
)
1900 eclass
= unix_ERR_class
;
1901 ecode
= unix_ERR_code
;
1902 unix_ERR_class
= SUCCESS
;
1907 while (unix_smb_errmap
[i
].smbclass
!= 0)
1909 if (unix_smb_errmap
[i
].unixerror
== errno
)
1911 eclass
= unix_smb_errmap
[i
].smbclass
;
1912 ecode
= unix_smb_errmap
[i
].smbcode
;
1919 return(error_packet(inbuf
,outbuf
,eclass
,ecode
,line
));
1923 /****************************************************************************
1924 create an error packet. Normally called using the ERROR() macro
1925 ****************************************************************************/
1926 int error_packet(char *inbuf
,char *outbuf
,int error_class
,uint32 error_code
,int line
)
1928 int outsize
= set_message(outbuf
,0,0,True
);
1930 cmd
= CVAL(inbuf
,smb_com
);
1932 CVAL(outbuf
,smb_rcls
) = error_class
;
1933 SSVAL(outbuf
,smb_err
,error_code
);
1935 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
1938 (int)CVAL(inbuf
,smb_com
),
1939 smb_fn_name(CVAL(inbuf
,smb_com
)),
1944 DEBUG(3,("error string = %s\n",strerror(errno
)));
1950 #ifndef SIGCLD_IGNORE
1951 /****************************************************************************
1952 this prevents zombie child processes
1953 ****************************************************************************/
1954 static int sig_cld()
1956 static int depth
= 0;
1959 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
1965 BlockSignals(True
,SIGCLD
);
1966 DEBUG(5,("got SIGCLD\n"));
1969 while (sys_waitpid((pid_t
)-1,(int *)NULL
, WNOHANG
) > 0);
1973 /* Stevens, Adv. Unix Prog. says that on system V you must call
1974 wait before reinstalling the signal handler, because the kernel
1975 calls the handler from within the signal-call when there is a
1976 child that has exited. This would lead to an infinite recursion
1977 if done vice versa. */
1979 #ifndef DONT_REINSTALL_SIG
1980 #ifdef SIGCLD_IGNORE
1981 signal(SIGCLD
, SIG_IGN
);
1983 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
1988 while (wait3(WAIT3_CAST1 NULL
, WNOHANG
, WAIT3_CAST2 NULL
) > 0);
1991 BlockSignals(False
,SIGCLD
);
1996 /****************************************************************************
1997 this is called when the client exits abruptly
1998 **************************************************************************/
1999 static int sig_pipe()
2001 extern int password_client
;
2002 BlockSignals(True
,SIGPIPE
);
2004 if (password_client
!= -1) {
2005 DEBUG(3,("lost connection to password server\n"));
2006 close(password_client
);
2007 password_client
= -1;
2008 #ifndef DONT_REINSTALL_SIG
2009 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2011 BlockSignals(False
,SIGPIPE
);
2015 exit_server("Got sigpipe\n");
2019 /****************************************************************************
2020 open the socket communication
2021 ****************************************************************************/
2022 static BOOL
open_sockets(BOOL is_daemon
,int port
)
2029 struct sockaddr addr
;
2030 int in_addrlen
= sizeof(addr
);
2033 #ifdef SIGCLD_IGNORE
2034 signal(SIGCLD
, SIG_IGN
);
2036 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
2039 /* open an incoming socket */
2040 s
= open_socket_in(SOCK_STREAM
, port
, 0,interpret_addr(lp_socket_address()));
2044 /* ready to listen */
2045 if (listen(s
, 5) == -1)
2047 DEBUG(0,("listen: %s",strerror(errno
)));
2055 /* now accept incoming connections - forking a new process
2056 for each incoming connection */
2057 DEBUG(2,("waiting for a connection\n"));
2060 Client
= accept(s
,&addr
,&in_addrlen
);
2062 if (Client
== -1 && errno
== EINTR
)
2067 DEBUG(0,("accept: %s",strerror(errno
)));
2071 #ifdef NO_FORK_DEBUG
2072 #ifndef NO_SIGNAL_TEST
2073 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2074 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2078 if (Client
!= -1 && fork()==0)
2080 /* Child code ... */
2081 #ifndef NO_SIGNAL_TEST
2082 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2083 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2085 /* close the listening socket */
2088 /* close our standard file descriptors */
2092 set_socket_options(Client
,"SO_KEEPALIVE");
2093 set_socket_options(Client
,user_socket_options
);
2095 /* Reset global variables in util.c so that
2096 client substitutions will be done correctly
2099 reset_globals_after_fork();
2102 close(Client
); /* The parent doesn't need this socket */
2108 /* We will abort gracefully when the client or remote system
2110 #ifndef NO_SIGNAL_TEST
2111 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2115 /* close our standard file descriptors */
2118 set_socket_options(Client
,"SO_KEEPALIVE");
2119 set_socket_options(Client
,user_socket_options
);
2126 /****************************************************************************
2127 check if a snum is in use
2128 ****************************************************************************/
2129 BOOL
snum_used(int snum
)
2132 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
2133 if (OPEN_CNUM(i
) && (SNUM(i
) == snum
))
2138 /****************************************************************************
2139 reload the services file
2140 **************************************************************************/
2141 BOOL
reload_services(BOOL test
)
2148 strcpy(fname
,lp_configfile());
2149 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
2151 strcpy(servicesf
,fname
);
2158 if (test
&& !lp_file_list_changed())
2161 lp_killunused(snum_used
);
2163 ret
= lp_load(servicesf
,False
);
2165 /* perhaps the config filename is now set */
2167 reload_services(True
);
2176 set_socket_options(Client
,"SO_KEEPALIVE");
2177 set_socket_options(Client
,user_socket_options
);
2181 create_mangled_stack(lp_mangledstack());
2183 /* this forces service parameters to be flushed */
2184 become_service(-1,True
);
2191 /****************************************************************************
2192 this prevents zombie child processes
2193 ****************************************************************************/
2194 static int sig_hup()
2196 BlockSignals(True
,SIGHUP
);
2197 DEBUG(0,("Got SIGHUP\n"));
2198 reload_services(False
);
2199 #ifndef DONT_REINSTALL_SIG
2200 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
2202 BlockSignals(False
,SIGHUP
);
2206 /****************************************************************************
2207 Setup the groups a user belongs to.
2208 ****************************************************************************/
2209 int setup_groups(char *user
, int uid
, int gid
, int *p_ngroups
,
2210 int **p_igroups
, gid_t
**p_groups
)
2212 if (-1 == initgroups(user
,gid
))
2216 DEBUG(0,("Unable to initgroups!\n"));
2217 if (gid
< 0 || gid
> 16000 || uid
< 0 || uid
> 16000)
2218 DEBUG(0,("This is probably a problem with the account %s\n",user
));
2226 ngroups
= getgroups(0,&grp
);
2229 igroups
= (int *)malloc(sizeof(int)*ngroups
);
2230 for (i
=0;i
<ngroups
;i
++)
2231 igroups
[i
] = 0x42424242;
2232 ngroups
= getgroups(ngroups
,(gid_t
*)igroups
);
2234 if (igroups
[0] == 0x42424242)
2237 *p_ngroups
= ngroups
;
2239 /* The following bit of code is very strange. It is due to the
2240 fact that some OSes use int* and some use gid_t* for
2241 getgroups, and some (like SunOS) use both, one in prototypes,
2242 and one in man pages and the actual code. Thus we detect it
2243 dynamically using some very ugly code */
2246 /* does getgroups return ints or gid_t ?? */
2247 static BOOL groups_use_ints
= True
;
2249 if (groups_use_ints
&&
2251 SVAL(igroups
,2) == 0x4242)
2252 groups_use_ints
= False
;
2254 for (i
=0;groups_use_ints
&& i
<ngroups
;i
++)
2255 if (igroups
[i
] == 0x42424242)
2256 groups_use_ints
= False
;
2258 if (groups_use_ints
)
2260 *p_igroups
= igroups
;
2261 *p_groups
= (gid_t
*)igroups
;
2265 gid_t
*groups
= (gid_t
*)igroups
;
2266 igroups
= (int *)malloc(sizeof(int)*ngroups
);
2267 for (i
=0;i
<ngroups
;i
++)
2268 igroups
[i
] = groups
[i
];
2269 *p_igroups
= igroups
;
2270 *p_groups
= (gid_t
*)groups
;
2273 DEBUG(3,("%s is in %d groups\n",user
,ngroups
));
2274 for (i
=0;i
<ngroups
;i
++)
2275 DEBUG(3,("%d ",igroups
[i
]));
2281 /****************************************************************************
2282 make a connection to a service
2283 ****************************************************************************/
2284 int make_connection(char *service
,char *user
,char *password
, int pwlen
, char *dev
,uint16 vuid
)
2288 struct passwd
*pass
= NULL
;
2289 connection_struct
*pcon
;
2292 static BOOL first_connection
= True
;
2296 snum
= find_service(service
);
2299 if (strequal(service
,"IPC$"))
2301 DEBUG(3,("%s refusing IPC connection\n",timestring()));
2305 DEBUG(0,("%s couldn't find service %s\n",timestring(),service
));
2309 if (strequal(service
,HOMES_NAME
))
2311 if (*user
&& Get_Pwnam(user
,True
))
2312 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
2314 if (validated_username(vuid
))
2316 strcpy(user
,validated_username(vuid
));
2317 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
2321 if (!lp_snum_ok(snum
) || !check_access(snum
)) {
2325 /* you can only connect to the IPC$ service as an ipc device */
2326 if (strequal(service
,"IPC$"))
2329 if (*dev
== '?' || !*dev
)
2331 if (lp_print_ok(snum
))
2332 strcpy(dev
,"LPT1:");
2337 /* if the request is as a printer and you can't print then refuse */
2339 if (!lp_print_ok(snum
) && (strncmp(dev
,"LPT",3) == 0)) {
2340 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
2344 /* lowercase the user name */
2347 /* add it as a possible user name */
2348 add_session_user(service
);
2350 /* shall we let them in? */
2351 if (!authorise_login(snum
,user
,password
,pwlen
,&guest
,&force
,vuid
))
2353 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service
));
2357 cnum
= find_free_connection(str_checksum(service
) + str_checksum(user
));
2360 DEBUG(0,("%s couldn't find free connection\n",timestring()));
2364 pcon
= &Connections
[cnum
];
2365 bzero((char *)pcon
,sizeof(*pcon
));
2367 /* find out some info about the user */
2368 pass
= Get_Pwnam(user
,True
);
2372 DEBUG(0,("%s couldn't find account %s\n",timestring(),user
));
2376 pcon
->read_only
= lp_readonly(snum
);
2380 StrnCpy(list
,lp_readlist(snum
),sizeof(pstring
)-1);
2381 string_sub(list
,"%S",service
);
2383 if (user_in_list(user
,list
))
2384 pcon
->read_only
= True
;
2386 StrnCpy(list
,lp_writelist(snum
),sizeof(pstring
)-1);
2387 string_sub(list
,"%S",service
);
2389 if (user_in_list(user
,list
))
2390 pcon
->read_only
= False
;
2393 /* admin user check */
2394 if (user_in_list(user
,lp_admin_users(snum
)) &&
2397 pcon
->admin_user
= True
;
2398 DEBUG(0,("%s logged in as admin user (root privileges)\n",user
));
2401 pcon
->admin_user
= False
;
2403 pcon
->force_user
= force
;
2405 pcon
->uid
= pass
->pw_uid
;
2406 pcon
->gid
= pass
->pw_gid
;
2407 pcon
->num_files_open
= 0;
2408 pcon
->lastused
= time(NULL
);
2409 pcon
->service
= snum
;
2411 pcon
->printer
= (strncmp(dev
,"LPT",3) == 0);
2412 pcon
->ipc
= (strncmp(dev
,"IPC",3) == 0);
2413 pcon
->dirptr
= NULL
;
2414 string_set(&pcon
->dirpath
,"");
2415 string_set(&pcon
->user
,user
);
2418 if (*lp_force_group(snum
))
2423 StrnCpy(gname
,lp_force_group(snum
),sizeof(pstring
)-1);
2424 /* default service may be a group name */
2425 string_sub(gname
,"%S",service
);
2426 gptr
= (struct group
*)getgrnam(gname
);
2430 pcon
->gid
= gptr
->gr_gid
;
2431 DEBUG(3,("Forced group %s\n",gname
));
2434 DEBUG(1,("Couldn't find group %s\n",gname
));
2438 if (*lp_force_user(snum
))
2440 struct passwd
*pass2
;
2442 strcpy(fuser
,lp_force_user(snum
));
2443 pass2
= (struct passwd
*)Get_Pwnam(fuser
,True
);
2446 pcon
->uid
= pass2
->pw_uid
;
2447 string_set(&pcon
->user
,fuser
);
2449 pcon
->force_user
= True
;
2450 DEBUG(3,("Forced user %s\n",fuser
));
2453 DEBUG(1,("Couldn't find user %s\n",fuser
));
2458 strcpy(s
,lp_pathname(snum
));
2459 standard_sub(cnum
,s
);
2460 string_set(&pcon
->connectpath
,s
);
2461 DEBUG(3,("Connect path is %s\n",s
));
2464 /* groups stuff added by ih */
2466 pcon
->groups
= NULL
;
2470 /* Find all the groups this uid is in and store them. Used by become_user() */
2471 setup_groups(pcon
->user
,pcon
->uid
,pcon
->gid
,&pcon
->ngroups
,&pcon
->igroups
,&pcon
->groups
);
2473 /* check number of connections */
2474 if (!claim_connection(cnum
,
2475 lp_servicename(SNUM(cnum
)),
2476 lp_max_connections(SNUM(cnum
)),False
))
2478 DEBUG(1,("too many connections - rejected\n"));
2482 if (lp_status(SNUM(cnum
)))
2483 claim_connection(cnum
,"STATUS.",MAXSTATUS
,first_connection
);
2485 first_connection
= False
;
2490 /* execute any "root preexec = " line */
2491 if (*lp_rootpreexec(SNUM(cnum
)))
2494 strcpy(cmd
,lp_rootpreexec(SNUM(cnum
)));
2495 standard_sub(cnum
,cmd
);
2496 DEBUG(5,("cmd=%s\n",cmd
));
2497 smbrun(cmd
,NULL
,False
);
2500 if (!become_user(cnum
,pcon
->vuid
))
2502 DEBUG(0,("Can't become connected user!\n"));
2504 if (!IS_IPC(cnum
)) {
2505 yield_connection(cnum
,
2506 lp_servicename(SNUM(cnum
)),
2507 lp_max_connections(SNUM(cnum
)));
2508 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
2513 if (ChDir(pcon
->connectpath
) != 0)
2515 DEBUG(0,("Can't change directory to %s (%s)\n",
2516 pcon
->connectpath
,strerror(errno
)));
2519 if (!IS_IPC(cnum
)) {
2520 yield_connection(cnum
,
2521 lp_servicename(SNUM(cnum
)),
2522 lp_max_connections(SNUM(cnum
)));
2523 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
2528 string_set(&pcon
->origpath
,pcon
->connectpath
);
2530 #if SOFTLINK_OPTIMISATION
2531 /* resolve any soft links early */
2534 strcpy(s
,pcon
->connectpath
);
2536 string_set(&pcon
->connectpath
,s
);
2537 ChDir(pcon
->connectpath
);
2541 num_connections_open
++;
2542 add_session_user(user
);
2544 /* execute any "preexec = " line */
2545 if (*lp_preexec(SNUM(cnum
)))
2548 strcpy(cmd
,lp_preexec(SNUM(cnum
)));
2549 standard_sub(cnum
,cmd
);
2550 smbrun(cmd
,NULL
,False
);
2553 /* we've finished with the sensitive stuff */
2557 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
2561 lp_servicename(SNUM(cnum
)),user
,
2571 /****************************************************************************
2572 find first available file slot
2573 ****************************************************************************/
2574 int find_free_file(void )
2577 /* we start at 1 here for an obscure reason I can't now remember,
2578 but I think is important :-) */
2579 for (i
=1;i
<MAX_OPEN_FILES
;i
++)
2582 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
2586 /****************************************************************************
2587 find first available connection slot, starting from a random position.
2588 The randomisation stops problems with the server dieing and clients
2589 thinking the server is still available.
2590 ****************************************************************************/
2591 static int find_free_connection(int hash
)
2595 hash
= (hash
% (MAX_CONNECTIONS
-2))+1;
2599 for (i
=hash
+1;i
!=hash
;)
2601 if (!Connections
[i
].open
&& Connections
[i
].used
== used
)
2603 DEBUG(3,("found free connection number %d\n",i
));
2607 if (i
== MAX_CONNECTIONS
)
2617 DEBUG(1,("ERROR! Out of connection structures\n"));
2622 /****************************************************************************
2623 reply for the core protocol
2624 ****************************************************************************/
2625 int reply_corep(char *outbuf
)
2627 int outsize
= set_message(outbuf
,1,0,True
);
2629 Protocol
= PROTOCOL_CORE
;
2635 /****************************************************************************
2636 reply for the coreplus protocol
2637 ****************************************************************************/
2638 int reply_coreplus(char *outbuf
)
2640 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2641 int outsize
= set_message(outbuf
,13,0,True
);
2642 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
2643 readbraw and writebraw (possibly) */
2644 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2645 SSVAL(outbuf
,smb_vwv1
,0x1); /* user level security, don't encrypt */
2647 Protocol
= PROTOCOL_COREPLUS
;
2653 /****************************************************************************
2654 reply for the lanman 1.0 protocol
2655 ****************************************************************************/
2656 int reply_lanman1(char *outbuf
)
2658 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2660 BOOL doencrypt
= SMBENCRYPT();
2661 time_t t
= time(NULL
);
2662 /* We need to save and restore this as it can be destroyed
2663 if we call another server if security=server
2664 Thanks to Paul Nelson @ Thursby for pointing this out.
2666 uint16 mid
= SVAL(outbuf
, smb_mid
);
2668 if (lp_security()>=SEC_USER
) secword
|= 1;
2669 if (doencrypt
) secword
|= 2;
2671 set_message(outbuf
,13,doencrypt
?8:0,True
);
2672 SSVAL(outbuf
,smb_vwv1
,secword
);
2674 /* Create a token value and add it to the outgoing packet. */
2676 generate_next_challenge(smb_buf(outbuf
));
2679 Protocol
= PROTOCOL_LANMAN1
;
2681 if (lp_security() == SEC_SERVER
&& server_cryptkey(outbuf
)) {
2682 DEBUG(3,("using password server validation\n"));
2684 if (doencrypt
) set_challenge(smb_buf(outbuf
));
2688 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2689 SSVAL(outbuf
,smb_mid
,mid
); /* Restore possibly corrupted mid */
2690 SSVAL(outbuf
,smb_vwv2
,max_recv
);
2691 SSVAL(outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
2692 SSVAL(outbuf
,smb_vwv4
,1);
2693 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
2694 readbraw writebraw (possibly) */
2695 SIVAL(outbuf
,smb_vwv6
,getpid());
2696 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
2698 put_dos_date(outbuf
,smb_vwv8
,t
);
2700 return (smb_len(outbuf
)+4);
2704 /****************************************************************************
2705 reply for the lanman 2.0 protocol
2706 ****************************************************************************/
2707 int reply_lanman2(char *outbuf
)
2709 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
2711 BOOL doencrypt
= SMBENCRYPT();
2712 time_t t
= time(NULL
);
2713 /* We need to save and restore this as it can be destroyed
2714 if we call another server if security=server
2715 Thanks to Paul Nelson @ Thursby for pointing this out.
2717 uint16 mid
= SVAL(outbuf
, smb_mid
);
2719 if (lp_security()>=SEC_USER
) secword
|= 1;
2720 if (doencrypt
) secword
|= 2;
2722 set_message(outbuf
,13,doencrypt
?8:0,True
);
2723 SSVAL(outbuf
,smb_vwv1
,secword
);
2725 /* Create a token value and add it to the outgoing packet. */
2727 generate_next_challenge(smb_buf(outbuf
));
2730 SIVAL(outbuf
,smb_vwv6
,getpid());
2732 Protocol
= PROTOCOL_LANMAN2
;
2734 if (lp_security() == SEC_SERVER
&& server_cryptkey(outbuf
)) {
2735 DEBUG(3,("using password server validation\n"));
2737 if (doencrypt
) set_challenge(smb_buf(outbuf
));
2741 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
2742 SSVAL(outbuf
,smb_mid
,mid
); /* Restore possibly corrupted mid */
2743 SSVAL(outbuf
,smb_vwv2
,max_recv
);
2744 SSVAL(outbuf
,smb_vwv3
,lp_maxmux());
2745 SSVAL(outbuf
,smb_vwv4
,1);
2746 SSVAL(outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
2747 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
2748 put_dos_date(outbuf
,smb_vwv8
,t
);
2750 return (smb_len(outbuf
)+4);
2754 /****************************************************************************
2755 reply for the nt protocol
2756 ****************************************************************************/
2757 int reply_nt1(char *outbuf
)
2759 /* dual names + lock_and_read + nt SMBs + remote API calls */
2760 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
;
2762 other valid capabilities which we may support at some time...
2763 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
2764 CAP_LARGE_FILES|CAP_LARGE_READX|
2765 CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
2769 BOOL doencrypt
= SMBENCRYPT();
2770 time_t t
= time(NULL
);
2773 char challenge_len
= 8;
2774 /* We need to save and restore this as it can be destroyed
2775 if we call another server if security=server
2776 Thanks to Paul Nelson @ Thursby for pointing this out.
2778 uint16 mid
= SVAL(outbuf
, smb_mid
);
2780 if (lp_readraw() && lp_writeraw())
2782 capabilities
|= CAP_RAW_MODE
;
2785 if (lp_security()>=SEC_USER
) secword
|= 1;
2786 if (doencrypt
) secword
|= 2;
2788 /* decide where (if) to put the encryption challenge, and
2789 follow it with the OEM'd domain name
2791 encrypt_len
= doencrypt
?challenge_len
:0;
2793 data_len
= encrypt_len
+ 2*(strlen(myworkgroup
)+1);
2795 data_len
= encrypt_len
+ strlen(myworkgroup
) + 1;
2798 set_message(outbuf
,17,data_len
,True
);
2801 /* put the OEM'd domain name */
2802 PutUniCode(smb_buf(outbuf
)+encrypt_len
,myworkgroup
);
2804 strcpy(smb_buf(outbuf
)+encrypt_len
, myworkgroup
);
2807 CVAL(outbuf
,smb_vwv1
) = secword
;
2809 /* Create a token value and add it to the outgoing packet. */
2812 generate_next_challenge(smb_buf(outbuf
));
2814 /* Tell the nt machine how long the challenge is. */
2815 SSVALS(outbuf
,smb_vwv16
+1,challenge_len
);
2819 Protocol
= PROTOCOL_NT1
;
2821 if (lp_security() == SEC_SERVER
&& server_cryptkey(outbuf
)) {
2822 DEBUG(3,("using password server validation\n"));
2824 if (doencrypt
) set_challenge(smb_buf(outbuf
));
2828 SSVAL(outbuf
,smb_mid
,mid
); /* Restore possibly corrupted mid */
2829 SSVAL(outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
2830 SSVAL(outbuf
,smb_vwv2
+1,1); /* num vcs */
2831 SIVAL(outbuf
,smb_vwv3
+1,0xffff); /* max buffer. LOTS! */
2832 SIVAL(outbuf
,smb_vwv5
+1,0xffff); /* raw size. LOTS! */
2833 SIVAL(outbuf
,smb_vwv7
+1,getpid()); /* session key */
2834 SIVAL(outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
2835 put_long_date(outbuf
+smb_vwv11
+1,t
);
2836 SSVALS(outbuf
,smb_vwv15
+1,TimeDiff(t
)/60);
2837 SSVAL(outbuf
,smb_vwv17
,data_len
); /* length of challenge+domain strings */
2839 return (smb_len(outbuf
)+4);
2842 /* these are the protocol lists used for auto architecture detection:
2845 protocol [PC NETWORK PROGRAM 1.0]
2846 protocol [XENIX CORE]
2847 protocol [MICROSOFT NETWORKS 1.03]
2848 protocol [LANMAN1.0]
2849 protocol [Windows for Workgroups 3.1a]
2850 protocol [LM1.2X002]
2851 protocol [LANMAN2.1]
2852 protocol [NT LM 0.12]
2855 protocol [PC NETWORK PROGRAM 1.0]
2856 protocol [XENIX CORE]
2857 protocol [MICROSOFT NETWORKS 1.03]
2858 protocol [LANMAN1.0]
2859 protocol [Windows for Workgroups 3.1a]
2860 protocol [LM1.2X002]
2861 protocol [LANMAN2.1]
2862 protocol [NT LM 0.12]
2865 protocol [PC NETWORK PROGRAM 1.0]
2866 protocol [XENIX CORE]
2867 protocol [LANMAN1.0]
2868 protocol [LM1.2X002]
2869 protocol [LANMAN2.1]
2873 * Modified to recognize the architecture of the remote machine better.
2875 * This appears to be the matrix of which protocol is used by which
2877 Protocol WfWg Win95 WinNT OS/2
2878 PC NETWORK PROGRAM 1.0 1 1 1 1
2880 MICROSOFT NETWORKS 3.0 2 2
2882 MICROSOFT NETWORKS 1.03 3
2885 Windows for Workgroups 3.1a 5 5 5
2890 * tim@fsg.com 09/29/95
2893 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
2894 #define ARCH_WIN95 0x2
2895 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
2896 #define ARCH_WINNT 0x8
2897 #define ARCH_SAMBA 0x10
2899 #define ARCH_ALL 0x1F
2901 /* List of supported protocols, most desired first */
2905 int (*proto_reply_fn
)(char *);
2907 } supported_protocols
[] = {
2908 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
2909 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
2910 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
2911 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
2912 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
2913 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
2914 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
2915 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
2916 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
2921 /****************************************************************************
2923 ****************************************************************************/
2924 static int reply_negprot(char *inbuf
,char *outbuf
)
2926 extern fstring remote_arch
;
2927 int outsize
= set_message(outbuf
,1,0,True
);
2932 int bcc
= SVAL(smb_buf(inbuf
),-2);
2933 int arch
= ARCH_ALL
;
2935 p
= smb_buf(inbuf
)+1;
2936 while (p
< (smb_buf(inbuf
) + bcc
))
2939 DEBUG(3,("Requested protocol [%s]\n",p
));
2940 if (strcsequal(p
,"Windows for Workgroups 3.1a"))
2941 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
);
2942 else if (strcsequal(p
,"DOS LM1.2X002"))
2943 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
2944 else if (strcsequal(p
,"DOS LANMAN2.1"))
2945 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
2946 else if (strcsequal(p
,"NT LM 0.12"))
2947 arch
&= ( ARCH_WIN95
| ARCH_WINNT
);
2948 else if (strcsequal(p
,"LANMAN2.1"))
2949 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
2950 else if (strcsequal(p
,"LM1.2X002"))
2951 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
2952 else if (strcsequal(p
,"MICROSOFT NETWORKS 1.03"))
2954 else if (strcsequal(p
,"XENIX CORE"))
2955 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
2956 else if (strcsequal(p
,"Samba")) {
2966 strcpy(remote_arch
,"Samba");
2969 strcpy(remote_arch
,"WfWg");
2972 strcpy(remote_arch
,"Win95");
2975 strcpy(remote_arch
,"WinNT");
2978 strcpy(remote_arch
,"OS2");
2981 strcpy(remote_arch
,"UNKNOWN");
2985 /* possibly reload - change of architecture */
2986 reload_services(True
);
2988 /* a special case to stop password server loops */
2989 if (Index
== 1 && strequal(remote_machine
,myhostname
) &&
2990 lp_security()==SEC_SERVER
)
2991 exit_server("Password server loop!");
2993 /* Check for protocols, most desirable first */
2994 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++)
2996 p
= smb_buf(inbuf
)+1;
2998 if (lp_maxprotocol() >= supported_protocols
[protocol
].protocol_level
)
2999 while (p
< (smb_buf(inbuf
) + bcc
))
3001 if (strequal(p
,supported_protocols
[protocol
].proto_name
))
3010 SSVAL(outbuf
,smb_vwv0
,choice
);
3012 extern fstring remote_proto
;
3013 strcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
3014 reload_services(True
);
3015 outsize
= supported_protocols
[protocol
].proto_reply_fn(outbuf
);
3016 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
3019 DEBUG(0,("No protocol supported !\n"));
3021 SSVAL(outbuf
,smb_vwv0
,choice
);
3023 DEBUG(5,("%s negprot index=%d\n",timestring(),choice
));
3029 /****************************************************************************
3030 close all open files for a connection
3031 ****************************************************************************/
3032 static void close_open_files(int cnum
)
3035 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
3036 if( Files
[i
].cnum
== cnum
&& Files
[i
].open
) {
3043 /****************************************************************************
3045 ****************************************************************************/
3046 void close_cnum(int cnum
, uint16 vuid
)
3048 DirCacheFlush(SNUM(cnum
));
3052 if (!OPEN_CNUM(cnum
))
3054 DEBUG(0,("Can't close cnum %d\n",cnum
));
3058 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) closed connection to service %s\n",
3060 remote_machine
,client_addr(),
3061 lp_servicename(SNUM(cnum
))));
3063 yield_connection(cnum
,
3064 lp_servicename(SNUM(cnum
)),
3065 lp_max_connections(SNUM(cnum
)));
3067 if (lp_status(SNUM(cnum
)))
3068 yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3070 close_open_files(cnum
);
3071 dptr_closecnum(cnum
);
3073 /* execute any "postexec = " line */
3074 if (*lp_postexec(SNUM(cnum
)) && become_user(cnum
,vuid
))
3077 strcpy(cmd
,lp_postexec(SNUM(cnum
)));
3078 standard_sub(cnum
,cmd
);
3079 smbrun(cmd
,NULL
,False
);
3084 /* execute any "root postexec = " line */
3085 if (*lp_rootpostexec(SNUM(cnum
)))
3088 strcpy(cmd
,lp_rootpostexec(SNUM(cnum
)));
3089 standard_sub(cnum
,cmd
);
3090 smbrun(cmd
,NULL
,False
);
3093 Connections
[cnum
].open
= False
;
3094 num_connections_open
--;
3095 if (Connections
[cnum
].ngroups
&& Connections
[cnum
].groups
)
3097 if (Connections
[cnum
].igroups
!= (int *)Connections
[cnum
].groups
)
3098 free(Connections
[cnum
].groups
);
3099 free(Connections
[cnum
].igroups
);
3100 Connections
[cnum
].groups
= NULL
;
3101 Connections
[cnum
].igroups
= NULL
;
3102 Connections
[cnum
].ngroups
= 0;
3105 string_set(&Connections
[cnum
].user
,"");
3106 string_set(&Connections
[cnum
].dirpath
,"");
3107 string_set(&Connections
[cnum
].connectpath
,"");
3111 /****************************************************************************
3112 simple routines to do connection counting
3113 ****************************************************************************/
3114 BOOL
yield_connection(int cnum
,char *name
,int max_connections
)
3116 struct connect_record crec
;
3119 int mypid
= getpid();
3122 DEBUG(3,("Yielding connection to %d %s\n",cnum
,name
));
3124 if (max_connections
<= 0)
3127 bzero(&crec
,sizeof(crec
));
3129 strcpy(fname
,lp_lockdir());
3130 standard_sub(cnum
,fname
);
3131 trim_string(fname
,"","/");
3135 strcat(fname
,".LCK");
3137 f
= fopen(fname
,"r+");
3140 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname
,strerror(errno
)));
3144 fseek(f
,0,SEEK_SET
);
3146 /* find a free spot */
3147 for (i
=0;i
<max_connections
;i
++)
3149 if (fread(&crec
,sizeof(crec
),1,f
) != 1)
3151 DEBUG(2,("Entry not found in lock file %s\n",fname
));
3155 if (crec
.pid
== mypid
&& crec
.cnum
== cnum
)
3159 if (crec
.pid
!= mypid
|| crec
.cnum
!= cnum
)
3162 DEBUG(2,("Entry not found in lock file %s\n",fname
));
3166 bzero((void *)&crec
,sizeof(crec
));
3168 /* remove our mark */
3169 if (fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
3170 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
3172 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname
,strerror(errno
)));
3177 DEBUG(3,("Yield successful\n"));
3184 /****************************************************************************
3185 simple routines to do connection counting
3186 ****************************************************************************/
3187 BOOL
claim_connection(int cnum
,char *name
,int max_connections
,BOOL Clear
)
3189 struct connect_record crec
;
3192 int snum
= SNUM(cnum
);
3196 if (max_connections
<= 0)
3199 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name
,max_connections
));
3201 strcpy(fname
,lp_lockdir());
3202 standard_sub(cnum
,fname
);
3203 trim_string(fname
,"","/");
3205 if (!directory_exist(fname
,NULL
))
3210 strcat(fname
,".LCK");
3212 if (!file_exist(fname
,NULL
))
3214 int oldmask
= umask(022);
3215 f
= fopen(fname
,"w");
3220 total_recs
= file_size(fname
) / sizeof(crec
);
3222 f
= fopen(fname
,"r+");
3226 DEBUG(1,("couldn't open lock file %s\n",fname
));
3230 /* find a free spot */
3231 for (i
=0;i
<max_connections
;i
++)
3234 if (i
>=total_recs
||
3235 fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
3236 fread(&crec
,sizeof(crec
),1,f
) != 1)
3238 if (foundi
< 0) foundi
= i
;
3242 if (Clear
&& crec
.pid
&& !process_exists(crec
.pid
))
3244 fseek(f
,i
*sizeof(crec
),SEEK_SET
);
3245 bzero((void *)&crec
,sizeof(crec
));
3246 fwrite(&crec
,sizeof(crec
),1,f
);
3247 if (foundi
< 0) foundi
= i
;
3250 if (foundi
< 0 && (!crec
.pid
|| !process_exists(crec
.pid
)))
3259 DEBUG(3,("no free locks in %s\n",fname
));
3264 /* fill in the crec */
3265 bzero((void *)&crec
,sizeof(crec
));
3266 crec
.magic
= 0x280267;
3267 crec
.pid
= getpid();
3269 crec
.uid
= Connections
[cnum
].uid
;
3270 crec
.gid
= Connections
[cnum
].gid
;
3271 StrnCpy(crec
.name
,lp_servicename(snum
),sizeof(crec
.name
)-1);
3272 crec
.start
= time(NULL
);
3274 StrnCpy(crec
.machine
,remote_machine
,sizeof(crec
.machine
)-1);
3275 StrnCpy(crec
.addr
,client_addr(),sizeof(crec
.addr
)-1);
3278 if (fseek(f
,foundi
*sizeof(crec
),SEEK_SET
) != 0 ||
3279 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
3290 /*******************************************************************
3291 prepare to dump a core file - carefully!
3292 ********************************************************************/
3293 static BOOL
dump_core(void)
3297 strcpy(dname
,debugf
);
3298 if ((p
=strrchr(dname
,'/'))) *p
=0;
3299 strcat(dname
,"/corefiles");
3301 sys_chown(dname
,getuid(),getgid());
3303 if (chdir(dname
)) return(False
);
3306 #ifndef NO_GETRLIMIT
3310 getrlimit(RLIMIT_CORE
, &rlp
);
3311 rlp
.rlim_cur
= MAX(4*1024*1024,rlp
.rlim_cur
);
3312 setrlimit(RLIMIT_CORE
, &rlp
);
3313 getrlimit(RLIMIT_CORE
, &rlp
);
3314 DEBUG(3,("Core limits now %d %d\n",rlp
.rlim_cur
,rlp
.rlim_max
));
3320 DEBUG(0,("Dumping core in %s\n",dname
));
3325 /****************************************************************************
3327 ****************************************************************************/
3328 void exit_server(char *reason
)
3330 static int firsttime
=1;
3333 if (!firsttime
) exit(0);
3337 DEBUG(2,("Closing connections\n"));
3338 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
3339 if (Connections
[i
].open
)
3342 if (dcelogin_atmost_once
)
3346 int oldlevel
= DEBUGLEVEL
;
3348 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message
)));
3350 show_msg(last_inbuf
);
3351 DEBUGLEVEL
= oldlevel
;
3352 DEBUG(0,("===============================================================\n"));
3354 if (dump_core()) return;
3358 #ifdef FAST_SHARE_MODES
3359 stop_share_mode_mgmt();
3360 #endif /* FAST_SHARE_MODES */
3362 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason
?reason
:""));
3366 /****************************************************************************
3367 do some standard substitutions in a string
3368 ****************************************************************************/
3369 void standard_sub(int cnum
,char *s
)
3371 if (!strchr(s
,'%')) return;
3373 if (VALID_CNUM(cnum
))
3375 string_sub(s
,"%S",lp_servicename(Connections
[cnum
].service
));
3376 string_sub(s
,"%P",Connections
[cnum
].connectpath
);
3377 string_sub(s
,"%u",Connections
[cnum
].user
);
3378 if (strstr(s
,"%H")) {
3379 char *home
= get_home_dir(Connections
[cnum
].user
);
3380 if (home
) string_sub(s
,"%H",home
);
3382 string_sub(s
,"%g",gidtoname(Connections
[cnum
].gid
));
3384 standard_sub_basic(s
);
3388 These flags determine some of the permissions required to do an operation
3390 Note that I don't set NEED_WRITE on some write operations because they
3391 are used by some brain-dead clients when printing, and I don't want to
3392 force write permissions on print services.
3394 #define AS_USER (1<<0)
3395 #define NEED_WRITE (1<<1)
3396 #define TIME_INIT (1<<2)
3397 #define CAN_IPC (1<<3)
3398 #define AS_GUEST (1<<5)
3402 define a list of possible SMB messages and their corresponding
3403 functions. Any message that has a NULL function is unimplemented -
3404 please feel free to contribute implementations!
3406 struct smb_message_struct
3420 {SMBnegprot
,"SMBnegprot",reply_negprot
,0},
3421 {SMBtcon
,"SMBtcon",reply_tcon
,0},
3422 {SMBtdis
,"SMBtdis",reply_tdis
,0},
3423 {SMBexit
,"SMBexit",reply_exit
,0},
3424 {SMBioctl
,"SMBioctl",reply_ioctl
,0},
3425 {SMBecho
,"SMBecho",reply_echo
,0},
3426 {SMBsesssetupX
,"SMBsesssetupX",reply_sesssetup_and_X
,0},
3427 {SMBtconX
,"SMBtconX",reply_tcon_and_X
,0},
3428 {SMBulogoffX
, "SMBulogoffX", reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
3429 {SMBgetatr
,"SMBgetatr",reply_getatr
,AS_USER
},
3430 {SMBsetatr
,"SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
3431 {SMBchkpth
,"SMBchkpth",reply_chkpth
,AS_USER
},
3432 {SMBsearch
,"SMBsearch",reply_search
,AS_USER
},
3433 {SMBopen
,"SMBopen",reply_open
,AS_USER
},
3435 /* note that SMBmknew and SMBcreate are deliberately overloaded */
3436 {SMBcreate
,"SMBcreate",reply_mknew
,AS_USER
},
3437 {SMBmknew
,"SMBmknew",reply_mknew
,AS_USER
},
3439 {SMBunlink
,"SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
3440 {SMBread
,"SMBread",reply_read
,AS_USER
},
3441 {SMBwrite
,"SMBwrite",reply_write
,AS_USER
},
3442 {SMBclose
,"SMBclose",reply_close
,AS_USER
| CAN_IPC
},
3443 {SMBmkdir
,"SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
3444 {SMBrmdir
,"SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
3445 {SMBdskattr
,"SMBdskattr",reply_dskattr
,AS_USER
},
3446 {SMBmv
,"SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
3448 /* this is a Pathworks specific call, allowing the
3449 changing of the root path */
3450 {pSETDIR
,"pSETDIR",reply_setdir
,AS_USER
},
3452 {SMBlseek
,"SMBlseek",reply_lseek
,AS_USER
},
3453 {SMBflush
,"SMBflush",reply_flush
,AS_USER
},
3454 {SMBctemp
,"SMBctemp",reply_ctemp
,AS_USER
},
3455 {SMBsplopen
,"SMBsplopen",reply_printopen
,AS_USER
},
3456 {SMBsplclose
,"SMBsplclose",reply_printclose
,AS_USER
},
3457 {SMBsplretq
,"SMBsplretq",reply_printqueue
,AS_USER
|AS_GUEST
},
3458 {SMBsplwr
,"SMBsplwr",reply_printwrite
,AS_USER
},
3459 {SMBlock
,"SMBlock",reply_lock
,AS_USER
},
3460 {SMBunlock
,"SMBunlock",reply_unlock
,AS_USER
},
3462 /* CORE+ PROTOCOL FOLLOWS */
3464 {SMBreadbraw
,"SMBreadbraw",reply_readbraw
,AS_USER
},
3465 {SMBwritebraw
,"SMBwritebraw",reply_writebraw
,AS_USER
},
3466 {SMBwriteclose
,"SMBwriteclose",reply_writeclose
,AS_USER
},
3467 {SMBlockread
,"SMBlockread",reply_lockread
,AS_USER
},
3468 {SMBwriteunlock
,"SMBwriteunlock",reply_writeunlock
,AS_USER
},
3470 /* LANMAN1.0 PROTOCOL FOLLOWS */
3472 {SMBreadBmpx
,"SMBreadBmpx",reply_readbmpx
,AS_USER
},
3473 {SMBreadBs
,"SMBreadBs",NULL
,AS_USER
},
3474 {SMBwriteBmpx
,"SMBwriteBmpx",reply_writebmpx
,AS_USER
},
3475 {SMBwriteBs
,"SMBwriteBs",reply_writebs
,AS_USER
},
3476 {SMBwritec
,"SMBwritec",NULL
,AS_USER
},
3477 {SMBsetattrE
,"SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
3478 {SMBgetattrE
,"SMBgetattrE",reply_getattrE
,AS_USER
},
3479 {SMBtrans
,"SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
3480 {SMBtranss
,"SMBtranss",NULL
,AS_USER
| CAN_IPC
},
3481 {SMBioctls
,"SMBioctls",NULL
,AS_USER
},
3482 {SMBcopy
,"SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
3483 {SMBmove
,"SMBmove",NULL
,AS_USER
| NEED_WRITE
},
3485 {SMBopenX
,"SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
3486 {SMBreadX
,"SMBreadX",reply_read_and_X
,AS_USER
},
3487 {SMBwriteX
,"SMBwriteX",reply_write_and_X
,AS_USER
},
3488 {SMBlockingX
,"SMBlockingX",reply_lockingX
,AS_USER
},
3490 {SMBffirst
,"SMBffirst",reply_search
,AS_USER
},
3491 {SMBfunique
,"SMBfunique",reply_search
,AS_USER
},
3492 {SMBfclose
,"SMBfclose",reply_fclose
,AS_USER
},
3494 /* LANMAN2.0 PROTOCOL FOLLOWS */
3495 {SMBfindnclose
, "SMBfindnclose", reply_findnclose
, AS_USER
},
3496 {SMBfindclose
, "SMBfindclose", reply_findclose
,AS_USER
},
3497 {SMBtrans2
, "SMBtrans2", reply_trans2
, AS_USER
},
3498 {SMBtranss2
, "SMBtranss2", reply_transs2
, AS_USER
},
3500 /* messaging routines */
3501 {SMBsends
,"SMBsends",reply_sends
,AS_GUEST
},
3502 {SMBsendstrt
,"SMBsendstrt",reply_sendstrt
,AS_GUEST
},
3503 {SMBsendend
,"SMBsendend",reply_sendend
,AS_GUEST
},
3504 {SMBsendtxt
,"SMBsendtxt",reply_sendtxt
,AS_GUEST
},
3506 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
3508 {SMBsendb
,"SMBsendb",NULL
,AS_GUEST
},
3509 {SMBfwdname
,"SMBfwdname",NULL
,AS_GUEST
},
3510 {SMBcancelf
,"SMBcancelf",NULL
,AS_GUEST
},
3511 {SMBgetmac
,"SMBgetmac",NULL
,AS_GUEST
}
3514 /****************************************************************************
3515 return a string containing the function name of a SMB command
3516 ****************************************************************************/
3517 char *smb_fn_name(int type
)
3519 static char *unknown_name
= "SMBunknown";
3520 static int num_smb_messages
=
3521 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
3524 for (match
=0;match
<num_smb_messages
;match
++)
3525 if (smb_messages
[match
].code
== type
)
3528 if (match
== num_smb_messages
)
3529 return(unknown_name
);
3531 return(smb_messages
[match
].name
);
3535 /****************************************************************************
3536 do a switch on the message type, and return the response size
3537 ****************************************************************************/
3538 static int switch_message(int type
,char *inbuf
,char *outbuf
,int size
,int bufsize
)
3542 static int num_smb_messages
=
3543 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
3547 struct timeval msg_start_time
;
3548 struct timeval msg_end_time
;
3549 static unsigned long total_time
= 0;
3551 GetTimeOfDay(&msg_start_time
);
3558 last_message
= type
;
3560 /* make sure this is an SMB packet */
3561 if (strncmp(smb_base(inbuf
),"\377SMB",4) != 0)
3563 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf
)));
3567 for (match
=0;match
<num_smb_messages
;match
++)
3568 if (smb_messages
[match
].code
== type
)
3571 if (match
== num_smb_messages
)
3573 DEBUG(0,("Unknown message type %d!\n",type
));
3574 outsize
= reply_unknown(inbuf
,outbuf
);
3578 DEBUG(3,("switch message %s (pid %d)\n",smb_messages
[match
].name
,pid
));
3579 if (smb_messages
[match
].fn
)
3581 int cnum
= SVAL(inbuf
,smb_tid
);
3582 int flags
= smb_messages
[match
].flags
;
3583 uint16 session_tag
= SVAL(inbuf
,smb_uid
);
3585 /* does this protocol need to be run as root? */
3586 if (!(flags
& AS_USER
))
3589 /* does this protocol need to be run as the connected user? */
3590 if ((flags
& AS_USER
) && !become_user(cnum
,session_tag
)) {
3591 if (flags
& AS_GUEST
)
3594 return(ERROR(ERRSRV
,ERRinvnid
));
3596 /* this code is to work around a bug is MS client 3 without
3597 introducing a security hole - it needs to be able to do
3598 print queue checks as guest if it isn't logged in properly */
3599 if (flags
& AS_USER
)
3602 /* does it need write permission? */
3603 if ((flags
& NEED_WRITE
) && !CAN_WRITE(cnum
))
3604 return(ERROR(ERRSRV
,ERRaccess
));
3606 /* ipc services are limited */
3607 if (IS_IPC(cnum
) && (flags
& AS_USER
) && !(flags
& CAN_IPC
))
3608 return(ERROR(ERRSRV
,ERRaccess
));
3610 /* load service specific parameters */
3611 if (OPEN_CNUM(cnum
) && !become_service(cnum
,(flags
& AS_USER
)?True
:False
))
3612 return(ERROR(ERRSRV
,ERRaccess
));
3614 /* does this protocol need to be run as guest? */
3615 if ((flags
& AS_GUEST
) && (!become_guest() || !check_access(-1)))
3616 return(ERROR(ERRSRV
,ERRaccess
));
3620 outsize
= smb_messages
[match
].fn(inbuf
,outbuf
,size
,bufsize
);
3624 outsize
= reply_unknown(inbuf
,outbuf
);
3629 GetTimeOfDay(&msg_end_time
);
3630 if (!(smb_messages
[match
].flags
& TIME_INIT
))
3632 smb_messages
[match
].time
= 0;
3633 smb_messages
[match
].flags
|= TIME_INIT
;
3636 unsigned long this_time
=
3637 (msg_end_time
.tv_sec
- msg_start_time
.tv_sec
)*1e6
+
3638 (msg_end_time
.tv_usec
- msg_start_time
.tv_usec
);
3639 smb_messages
[match
].time
+= this_time
;
3640 total_time
+= this_time
;
3642 DEBUG(2,("TIME %s %d usecs %g pct\n",
3643 smb_fn_name(type
),smb_messages
[match
].time
,
3644 (100.0*smb_messages
[match
].time
) / total_time
));
3651 /****************************************************************************
3652 construct a chained reply and add it to the already made reply
3653 **************************************************************************/
3654 int chain_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
3656 static char *orig_inbuf
;
3657 static char *orig_outbuf
;
3658 int smb_com1
, smb_com2
= CVAL(inbuf
,smb_vwv0
);
3659 unsigned smb_off2
= SVAL(inbuf
,smb_vwv1
);
3660 char *inbuf2
, *outbuf2
;
3662 char inbuf_saved
[smb_wct
];
3663 char outbuf_saved
[smb_wct
];
3664 extern int chain_size
;
3665 int wct
= CVAL(outbuf
,smb_wct
);
3666 int outsize
= smb_size
+ 2*wct
+ SVAL(outbuf
,smb_vwv0
+2*wct
);
3668 /* maybe its not chained */
3669 if (smb_com2
== 0xFF) {
3670 CVAL(outbuf
,smb_vwv0
) = 0xFF;
3674 if (chain_size
== 0) {
3675 /* this is the first part of the chain */
3677 orig_outbuf
= outbuf
;
3680 /* we need to tell the client where the next part of the reply will be */
3681 SSVAL(outbuf
,smb_vwv1
,smb_offset(outbuf
+outsize
,outbuf
));
3682 CVAL(outbuf
,smb_vwv0
) = smb_com2
;
3684 /* remember how much the caller added to the chain, only counting stuff
3685 after the parameter words */
3686 chain_size
+= outsize
- smb_wct
;
3688 /* work out pointers into the original packets. The
3689 headers on these need to be filled in */
3690 inbuf2
= orig_inbuf
+ smb_off2
+ 4 - smb_wct
;
3691 outbuf2
= orig_outbuf
+ SVAL(outbuf
,smb_vwv1
) + 4 - smb_wct
;
3693 /* remember the original command type */
3694 smb_com1
= CVAL(orig_inbuf
,smb_com
);
3696 /* save the data which will be overwritten by the new headers */
3697 memcpy(inbuf_saved
,inbuf2
,smb_wct
);
3698 memcpy(outbuf_saved
,outbuf2
,smb_wct
);
3700 /* give the new packet the same header as the last part of the SMB */
3701 memmove(inbuf2
,inbuf
,smb_wct
);
3703 /* create the in buffer */
3704 CVAL(inbuf2
,smb_com
) = smb_com2
;
3706 /* create the out buffer */
3707 bzero(outbuf2
,smb_size
);
3708 set_message(outbuf2
,0,0,True
);
3709 CVAL(outbuf2
,smb_com
) = CVAL(inbuf2
,smb_com
);
3711 memcpy(outbuf2
+4,inbuf2
+4,4);
3712 CVAL(outbuf2
,smb_rcls
) = SUCCESS
;
3713 CVAL(outbuf2
,smb_reh
) = 0;
3714 CVAL(outbuf2
,smb_flg
) = 0x80 | (CVAL(inbuf2
,smb_flg
) & 0x8); /* bit 7 set
3716 SSVAL(outbuf2
,smb_flg2
,1); /* say we support long filenames */
3717 SSVAL(outbuf2
,smb_err
,SUCCESS
);
3718 SSVAL(outbuf2
,smb_tid
,SVAL(inbuf2
,smb_tid
));
3719 SSVAL(outbuf2
,smb_pid
,SVAL(inbuf2
,smb_pid
));
3720 SSVAL(outbuf2
,smb_uid
,SVAL(inbuf2
,smb_uid
));
3721 SSVAL(outbuf2
,smb_mid
,SVAL(inbuf2
,smb_mid
));
3723 DEBUG(3,("Chained message\n"));
3726 /* process the request */
3727 outsize2
= switch_message(smb_com2
,inbuf2
,outbuf2
,size
-chain_size
,
3728 bufsize
-chain_size
);
3730 /* copy the new reply and request headers over the old ones, but
3731 preserve the smb_com field */
3732 memmove(orig_outbuf
,outbuf2
,smb_wct
);
3733 CVAL(orig_outbuf
,smb_com
) = smb_com1
;
3735 /* restore the saved data, being careful not to overwrite any
3736 data from the reply header */
3737 memcpy(inbuf2
,inbuf_saved
,smb_wct
);
3739 int ofs
= smb_wct
- PTR_DIFF(outbuf2
,orig_outbuf
);
3740 if (ofs
< 0) ofs
= 0;
3741 memmove(outbuf2
+ofs
,outbuf_saved
+ofs
,smb_wct
-ofs
);
3749 /****************************************************************************
3750 construct a reply to the incoming packet
3751 ****************************************************************************/
3752 int construct_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
3754 int type
= CVAL(inbuf
,smb_com
);
3756 int msg_type
= CVAL(inbuf
,0);
3757 extern int chain_size
;
3759 smb_last_time
= time(NULL
);
3764 bzero(outbuf
,smb_size
);
3767 return(reply_special(inbuf
,outbuf
));
3769 CVAL(outbuf
,smb_com
) = CVAL(inbuf
,smb_com
);
3770 set_message(outbuf
,0,0,True
);
3772 memcpy(outbuf
+4,inbuf
+4,4);
3773 CVAL(outbuf
,smb_rcls
) = SUCCESS
;
3774 CVAL(outbuf
,smb_reh
) = 0;
3775 CVAL(outbuf
,smb_flg
) = 0x80 | (CVAL(inbuf
,smb_flg
) & 0x8); /* bit 7 set
3777 SSVAL(outbuf
,smb_flg2
,1); /* say we support long filenames */
3778 SSVAL(outbuf
,smb_err
,SUCCESS
);
3779 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
3780 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
3781 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
3782 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
3784 outsize
= switch_message(type
,inbuf
,outbuf
,size
,bufsize
);
3786 outsize
+= chain_size
;
3789 smb_setlen(outbuf
,outsize
- 4);
3794 /****************************************************************************
3795 process commands from the client
3796 ****************************************************************************/
3797 static void process(void)
3799 static int trans_num
= 0;
3803 InBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
3804 OutBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
3805 if ((InBuffer
== NULL
) || (OutBuffer
== NULL
))
3808 InBuffer
+= SMB_ALIGNMENT
;
3809 OutBuffer
+= SMB_ALIGNMENT
;
3812 DEBUG(3,("priming nmbd\n"));
3815 ip
= *interpret_addr2("localhost");
3816 if (zero_ip(ip
)) ip
= *interpret_addr2("127.0.0.1");
3818 send_one_packet(OutBuffer
,1,ip
,NMB_PORT
,SOCK_DGRAM
);
3828 int deadtime
= lp_deadtime()*60;
3830 int last_keepalive
=0;
3833 deadtime
= DEFAULT_SMBD_TIMEOUT
;
3835 if (lp_readprediction())
3836 do_read_prediction();
3840 for (counter
=SMBD_SELECT_LOOP
;
3841 !receive_smb(Client
,InBuffer
,SMBD_SELECT_LOOP
*1000);
3842 counter
+= SMBD_SELECT_LOOP
)
3846 BOOL allidle
= True
;
3847 extern int keepalive
;
3849 if (smb_read_error
== READ_EOF
) {
3850 DEBUG(3,("end of file from client\n"));
3854 if (smb_read_error
== READ_ERROR
) {
3855 DEBUG(3,("receive_smb error (%s) exiting\n",
3862 /* become root again if waiting */
3865 /* check for smb.conf reload */
3866 if (!(counter
%SMBD_RELOAD_CHECK
))
3867 reload_services(True
);
3870 /* check the share modes every 10 secs */
3871 if (!(counter
%SHARE_MODES_CHECK
))
3872 check_share_modes();
3874 /* clean the share modes every 5 minutes */
3875 if (!(counter
%SHARE_MODES_CLEAN
))
3876 clean_share_modes();
3879 /* automatic timeout if all connections are closed */
3880 if (num_connections_open
==0 && counter
>= IDLE_CLOSED_TIMEOUT
) {
3881 DEBUG(2,("%s Closing idle connection\n",timestring()));
3885 if (keepalive
&& (counter
-last_keepalive
)>keepalive
) {
3886 extern int password_client
;
3887 if (!send_keepalive(Client
)) {
3888 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
3891 /* also send a keepalive to the password server if its still
3893 if (password_client
!= -1)
3894 send_keepalive(password_client
);
3895 last_keepalive
= counter
;
3898 /* check for connection timeouts */
3899 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
3900 if (Connections
[i
].open
)
3902 /* close dirptrs on connections that are idle */
3903 if ((t
-Connections
[i
].lastused
)>DPTR_IDLE_TIMEOUT
)
3906 if (Connections
[i
].num_files_open
> 0 ||
3907 (t
-Connections
[i
].lastused
)<deadtime
)
3911 if (allidle
&& num_connections_open
>0) {
3912 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
3917 msg_type
= CVAL(InBuffer
,0);
3918 msg_flags
= CVAL(InBuffer
,1);
3919 type
= CVAL(InBuffer
,smb_com
);
3921 len
= smb_len(InBuffer
);
3923 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type
,len
));
3927 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num
,nread
));
3930 if(trans_num
== 1 && VT_Check(InBuffer
)) {
3940 nread
= construct_reply(InBuffer
,OutBuffer
,nread
,max_send
);
3943 if (CVAL(OutBuffer
,0) == 0)
3944 show_msg(OutBuffer
);
3946 if (nread
!= smb_len(OutBuffer
) + 4)
3948 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
3950 smb_len(OutBuffer
)));
3953 send_smb(Client
,OutBuffer
);
3960 /****************************************************************************
3961 initialise connect, service and file structs
3962 ****************************************************************************/
3963 static void init_structs(void )
3966 get_myname(myhostname
,NULL
);
3968 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
3970 Connections
[i
].open
= False
;
3971 Connections
[i
].num_files_open
=0;
3972 Connections
[i
].lastused
=0;
3973 Connections
[i
].used
=False
;
3974 string_init(&Connections
[i
].user
,"");
3975 string_init(&Connections
[i
].dirpath
,"");
3976 string_init(&Connections
[i
].connectpath
,"");
3977 string_init(&Connections
[i
].origpath
,"");
3980 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
3982 Files
[i
].open
= False
;
3983 string_init(&Files
[i
].name
,"");
3987 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
3989 file_fd_struct
*fd_ptr
= &FileFd
[i
];
3990 fd_ptr
->ref_count
= 0;
3991 fd_ptr
->dev
= (int32
)-1;
3992 fd_ptr
->inode
= (int32
)-1;
3994 fd_ptr
->fd_readonly
= -1;
3995 fd_ptr
->fd_writeonly
= -1;
3996 fd_ptr
->real_open_flags
= -1;
4002 /****************************************************************************
4003 usage on the program
4004 ****************************************************************************/
4005 static void usage(char *pname
)
4007 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4009 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname
);
4010 printf("Version %s\n",VERSION
);
4011 printf("\t-D become a daemon\n");
4012 printf("\t-p port listen on the specified port\n");
4013 printf("\t-d debuglevel set the debuglevel\n");
4014 printf("\t-l log basename. Basename for log/debug files\n");
4015 printf("\t-s services file. Filename of services file\n");
4016 printf("\t-P passive only\n");
4017 printf("\t-a overwrite log file, don't append\n");
4022 /****************************************************************************
4024 ****************************************************************************/
4025 int main(int argc
,char *argv
[])
4027 extern BOOL append_log
;
4028 /* shall I run as a daemon */
4029 BOOL is_daemon
= False
;
4030 int port
= SMB_PORT
;
4032 extern char *optarg
;
4033 char pidFile
[100] = { 0 };
4035 #ifdef NEED_AUTH_PARAMETERS
4036 set_auth_parameters(argc
,argv
);
4047 strcpy(debugf
,SMBLOGFILE
);
4049 setup_logging(argv
[0],False
);
4051 charset_initialise(-1);
4053 /* make absolutely sure we run as root - to handle cases whre people
4054 are crazy enough to have it setuid */
4064 fault_setup(exit_server
);
4065 signal(SIGTERM
, SIGNAL_CAST dflt_sig
);
4067 /* we want total control over the permissions on created files,
4068 so set our umask to 0 */
4075 /* this is for people who can't start the program correctly */
4076 while (argc
> 1 && (*argv
[1] != '-'))
4082 while ((opt
= getopt(argc
, argv
, "O:i:l:s:d:Dp:hPaf:")) != EOF
)
4086 strncpy(pidFile
, optarg
, sizeof(pidFile
));
4089 strcpy(user_socket_options
,optarg
);
4092 strcpy(scope
,optarg
);
4096 extern BOOL passive
;
4101 strcpy(servicesf
,optarg
);
4104 strcpy(debugf
,optarg
);
4108 extern BOOL append_log
;
4109 append_log
= !append_log
;
4119 DEBUGLEVEL
= atoi(optarg
);
4122 port
= atoi(optarg
);
4135 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION
));
4136 DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
4138 #ifndef NO_GETRLIMIT
4139 #ifdef RLIMIT_NOFILE
4142 getrlimit(RLIMIT_NOFILE
, &rlp
);
4143 rlp
.rlim_cur
= (MAX_OPEN_FILES
>rlp
.rlim_max
)? rlp
.rlim_max
:MAX_OPEN_FILES
;
4144 setrlimit(RLIMIT_NOFILE
, &rlp
);
4145 getrlimit(RLIMIT_NOFILE
, &rlp
);
4146 DEBUG(3,("Maximum number of open files per session is %d\n",rlp
.rlim_cur
));
4152 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4153 getuid(),getgid(),geteuid(),getegid()));
4155 if (sizeof(uint16
) < 2 || sizeof(uint32
) < 4)
4157 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
4163 if (!reload_services(False
))
4166 charset_initialise(lp_client_code_page());
4168 strcpy(myworkgroup
, lp_workgroup());
4170 #ifndef NO_SIGNAL_TEST
4171 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
4174 DEBUG(3,("%s loaded services\n",timestring()));
4176 if (!is_daemon
&& !is_a_socket(0))
4178 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
4184 DEBUG(3,("%s becoming a daemon\n",timestring()));
4193 if ((fd
= open(pidFile
,
4194 O_NONBLOCK
| O_CREAT
| O_WRONLY
| O_TRUNC
, 0644)) < 0)
4196 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile
, strerror(errno
)));
4199 if(fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)==False
)
4201 DEBUG(0,("ERROR: smbd is already running\n"));
4204 sprintf(buf
, "%u\n", (unsigned int) getpid());
4205 if (write(fd
, buf
, strlen(buf
)) < 0)
4207 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile
, strerror(errno
)));
4210 /* Leave pid file open & locked for the duration... */
4213 if (!open_sockets(is_daemon
,port
))
4216 #ifdef FAST_SHARE_MODES
4217 if (!start_share_mode_mgmt())
4219 #endif /* FAST_SHARE_MODES */
4221 /* possibly reload the services file. */
4222 reload_services(True
);
4224 max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
4228 if (sys_chroot(lp_rootdir()) == 0)
4229 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
4235 exit_server("normal exit");