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 time_t smb_last_time
=(time_t)0;
53 extern int smb_read_error
;
55 extern pstring user_socket_options
;
57 connection_struct Connections
[MAX_CONNECTIONS
];
58 files_struct Files
[MAX_OPEN_FILES
];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd
[MAX_OPEN_FILES
];
65 int max_file_fd_used
= 0;
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 /* Oplock ipc UDP socket. */
89 uint16 oplock_port
= 0;
90 /* Current number of oplocks we have outstanding. */
91 int32 global_oplocks_open
= 0;
93 BOOL global_oplock_break
= False
;
95 extern fstring remote_machine
;
97 extern pstring OriginalDir
;
99 /* these can be set by some functions to override the error codes */
100 int unix_ERR_class
=SUCCESS
;
104 extern int extra_time_offset
;
106 extern pstring myhostname
;
108 static int find_free_connection(int hash
);
110 /* for readability... */
111 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
112 #define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
113 #define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
114 #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
115 #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
117 /****************************************************************************
118 when exiting, take the whole family
119 ****************************************************************************/
122 exit_server("caught signal");
123 return 0; /* Keep -Wall happy :-) */
125 /****************************************************************************
126 Send a SIGTERM to our process group.
127 *****************************************************************************/
130 if(am_parent
) kill(0,SIGTERM
);
133 /****************************************************************************
134 change a dos mode to a unix mode
135 base permission for files:
136 everybody gets read bit set
137 dos readonly is represented in unix by removing everyone's write bit
138 dos archive is represented in unix by the user's execute bit
139 dos system is represented in unix by the group's execute bit
140 dos hidden is represented in unix by the other's execute bit
141 Then apply create mask,
143 base permission for directories:
144 dos directory is represented in unix by unix's dir bit and the exec bit
145 Then apply create mask,
147 ****************************************************************************/
148 mode_t
unix_mode(int cnum
,int dosmode
)
150 mode_t result
= (S_IRUSR
| S_IRGRP
| S_IROTH
);
152 if ( !IS_DOS_READONLY(dosmode
) )
153 result
|= (S_IWUSR
| S_IWGRP
| S_IWOTH
);
155 if (IS_DOS_DIR(dosmode
)) {
156 /* We never make directories read only for the owner as under DOS a user
157 can always create a file in a read-only directory. */
158 result
|= (S_IFDIR
| S_IXUSR
| S_IXGRP
| S_IXOTH
| S_IWUSR
);
159 /* Apply directory mask */
160 result
&= lp_dir_mode(SNUM(cnum
));
161 /* Add in force bits */
162 result
|= lp_force_dir_mode(SNUM(cnum
));
164 if (MAP_ARCHIVE(cnum
) && IS_DOS_ARCHIVE(dosmode
))
167 if (MAP_SYSTEM(cnum
) && IS_DOS_SYSTEM(dosmode
))
170 if (MAP_HIDDEN(cnum
) && IS_DOS_HIDDEN(dosmode
))
173 /* Apply mode mask */
174 result
&= lp_create_mode(SNUM(cnum
));
175 /* Add in force bits */
176 result
|= lp_force_create_mode(SNUM(cnum
));
182 /****************************************************************************
183 change a unix mode to a dos mode
184 ****************************************************************************/
185 int dos_mode(int cnum
,char *path
,struct stat
*sbuf
)
188 extern struct current_user current_user
;
190 DEBUG(8,("dos_mode: %d %s\n", cnum
, path
));
192 if (CAN_WRITE(cnum
) && !lp_alternate_permissions(SNUM(cnum
))) {
193 if (!((sbuf
->st_mode
& S_IWOTH
) ||
194 Connections
[cnum
].admin_user
||
195 ((sbuf
->st_mode
& S_IWUSR
) && current_user
.uid
==sbuf
->st_uid
) ||
196 ((sbuf
->st_mode
& S_IWGRP
) &&
197 in_group(sbuf
->st_gid
,current_user
.gid
,
198 current_user
.ngroups
,current_user
.igroups
))))
201 if ((sbuf
->st_mode
& S_IWUSR
) == 0)
205 if (MAP_ARCHIVE(cnum
) && ((sbuf
->st_mode
& S_IXUSR
) != 0))
208 if (MAP_SYSTEM(cnum
) && ((sbuf
->st_mode
& S_IXGRP
) != 0))
211 if (MAP_HIDDEN(cnum
) && ((sbuf
->st_mode
& S_IXOTH
) != 0))
214 if (S_ISDIR(sbuf
->st_mode
))
215 result
= aDIR
| (result
& aRONLY
);
219 if (S_ISLNK(sbuf
->st_mode
) && S_ISDIR(sbuf
->st_mode
))
224 /* hide files with a name starting with a . */
225 if (lp_hide_dot_files(SNUM(cnum
)))
227 char *p
= strrchr(path
,'/');
233 if (p
[0] == '.' && p
[1] != '.' && p
[1] != 0)
237 /* Optimization : Only call is_hidden_path if it's not already
239 if (!(result
& aHIDDEN
) && IS_HIDDEN_PATH(cnum
,path
))
244 DEBUG(8,("dos_mode returning "));
246 if (result
& aHIDDEN
) DEBUG(8, ("h"));
247 if (result
& aRONLY
) DEBUG(8, ("r"));
248 if (result
& aSYSTEM
) DEBUG(8, ("s"));
249 if (result
& aDIR
) DEBUG(8, ("d"));
250 if (result
& aARCH
) DEBUG(8, ("a"));
257 /*******************************************************************
258 chmod a file - but preserve some bits
259 ********************************************************************/
260 int dos_chmod(int cnum
,char *fname
,int dosmode
,struct stat
*st
)
269 if (sys_stat(fname
,st
)) return(-1);
272 if (S_ISDIR(st
->st_mode
)) dosmode
|= aDIR
;
274 if (dos_mode(cnum
,fname
,st
) == dosmode
) return(0);
276 unixmode
= unix_mode(cnum
,dosmode
);
278 /* preserve the s bits */
279 mask
|= (S_ISUID
| S_ISGID
);
281 /* preserve the t bit */
286 /* possibly preserve the x bits */
287 if (!MAP_ARCHIVE(cnum
)) mask
|= S_IXUSR
;
288 if (!MAP_SYSTEM(cnum
)) mask
|= S_IXGRP
;
289 if (!MAP_HIDDEN(cnum
)) mask
|= S_IXOTH
;
291 unixmode
|= (st
->st_mode
& mask
);
293 /* if we previously had any r bits set then leave them alone */
294 if ((tmp
= st
->st_mode
& (S_IRUSR
|S_IRGRP
|S_IROTH
))) {
295 unixmode
&= ~(S_IRUSR
|S_IRGRP
|S_IROTH
);
299 /* if we previously had any w bits set then leave them alone
300 if the new mode is not rdonly */
301 if (!IS_DOS_READONLY(dosmode
) &&
302 (tmp
= st
->st_mode
& (S_IWUSR
|S_IWGRP
|S_IWOTH
))) {
303 unixmode
&= ~(S_IWUSR
|S_IWGRP
|S_IWOTH
);
307 return(sys_chmod(fname
,unixmode
));
310 /*******************************************************************
311 Wrapper around sys_utime that possibly allows DOS semantics rather
313 *******************************************************************/
315 int file_utime(int cnum
, char *fname
, struct utimbuf
*times
)
317 extern struct current_user current_user
;
323 if(sys_utime(fname
, times
) == 0)
326 if((errno
!= EPERM
) && (errno
!= EACCES
))
329 if(!lp_dos_filetimes(SNUM(cnum
)))
332 /* We have permission (given by the Samba admin) to
333 break POSIX semantics and allow a user to change
334 the time on a file they don't own but can write to
338 if(sys_stat(fname
,&sb
) != 0)
341 /* Check if we have write access. */
342 if (CAN_WRITE(cnum
)) {
343 if (((sb
.st_mode
& S_IWOTH
) ||
344 Connections
[cnum
].admin_user
||
345 ((sb
.st_mode
& S_IWUSR
) && current_user
.uid
==sb
.st_uid
) ||
346 ((sb
.st_mode
& S_IWGRP
) &&
347 in_group(sb
.st_gid
,current_user
.gid
,
348 current_user
.ngroups
,current_user
.igroups
)))) {
349 /* We are allowed to become root and change the filetime. */
351 ret
= sys_utime(fname
, times
);
352 unbecome_root(False
);
359 /*******************************************************************
360 Change a filetime - possibly allowing DOS semantics.
361 *******************************************************************/
363 BOOL
set_filetime(int cnum
, char *fname
, time_t mtime
)
365 struct utimbuf times
;
367 if (null_mtime(mtime
)) return(True
);
369 times
.modtime
= times
.actime
= mtime
;
371 if (file_utime(cnum
, fname
, ×
)) {
372 DEBUG(4,("set_filetime(%s) failed: %s\n",fname
,strerror(errno
)));
378 /****************************************************************************
379 check if two filenames are equal
381 this needs to be careful about whether we are case sensitive
382 ****************************************************************************/
383 static BOOL
fname_equal(char *name1
, char *name2
)
385 int l1
= strlen(name1
);
386 int l2
= strlen(name2
);
388 /* handle filenames ending in a single dot */
389 if (l1
-l2
== 1 && name1
[l1
-1] == '.' && lp_strip_dot())
393 ret
= fname_equal(name1
,name2
);
398 if (l2
-l1
== 1 && name2
[l2
-1] == '.' && lp_strip_dot())
402 ret
= fname_equal(name1
,name2
);
407 /* now normal filename handling */
409 return(strcmp(name1
,name2
) == 0);
411 return(strequal(name1
,name2
));
415 /****************************************************************************
416 mangle the 2nd name and check if it is then equal to the first name
417 ****************************************************************************/
418 static BOOL
mangled_equal(char *name1
, char *name2
)
422 if (is_8_3(name2
, True
))
425 strcpy(tmpname
,name2
);
426 mangle_name_83(tmpname
);
428 return(strequal(name1
,tmpname
));
432 /****************************************************************************
433 scan a directory to find a filename, matching without case sensitivity
435 If the name looks like a mangled name then try via the mangling functions
436 ****************************************************************************/
437 static BOOL
scan_directory(char *path
, char *name
,int cnum
,BOOL docache
)
444 mangled
= is_mangled(name
);
446 /* handle null paths */
450 if (docache
&& (dname
= DirCacheCheck(path
,name
,SNUM(cnum
)))) {
456 check_mangled_stack(name
);
458 /* open the directory */
459 if (!(cur_dir
= OpenDir(cnum
, path
, True
)))
461 DEBUG(3,("scan dir didn't open dir [%s]\n",path
));
465 /* now scan for matching names */
466 while ((dname
= ReadDirName(cur_dir
)))
469 (strequal(dname
,".") || strequal(dname
,"..")))
472 pstrcpy(name2
,dname
);
473 if (!name_map_mangle(name2
,False
,SNUM(cnum
))) continue;
475 if ((mangled
&& mangled_equal(name
,name2
))
476 || fname_equal(name
, name2
)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
478 /* we've found the file, change it's name and return */
479 if (docache
) DirCacheAdd(path
,name
,dname
,SNUM(cnum
));
490 /****************************************************************************
491 This routine is called to convert names from the dos namespace to unix
492 namespace. It needs to handle any case conversions, mangling, format
495 We assume that we have already done a chdir() to the right "root" directory
498 The function will return False if some part of the name except for the last
499 part cannot be resolved
501 If the saved_last_component != 0, then the unmodified last component
502 of the pathname is returned there. This is used in an exceptional
503 case in reply_mv (so far). If saved_last_component == 0 then nothing
506 The bad_path arg is set to True if the filename walk failed. This is
507 used to pick the correct error code to return between ENOENT and ENOTDIR
508 as Windows applications depend on ERRbadpath being returned if a component
509 of a pathname does not exist.
510 ****************************************************************************/
511 BOOL
unix_convert(char *name
,int cnum
,pstring saved_last_component
, BOOL
*bad_path
)
521 if(saved_last_component
)
522 *saved_last_component
= 0;
524 /* convert to basic unix format - removing \ chars and cleaning it up */
526 unix_clean_name(name
);
528 /* names must be relative to the root of the service - trim any leading /.
529 also trim trailing /'s */
530 trim_string(name
,"/","/");
533 * Ensure saved_last_component is valid even if file exists.
535 if(saved_last_component
) {
536 end
= strrchr(name
, '/');
538 strcpy(saved_last_component
, end
+ 1);
540 strcpy(saved_last_component
, name
);
543 if (!case_sensitive
&&
544 (!case_preserve
|| (is_8_3(name
, False
) && !short_case_preserve
)))
547 /* check if it's a printer file */
548 if (Connections
[cnum
].printer
)
550 if ((! *name
) || strchr(name
,'/') || !is_8_3(name
, True
))
554 sprintf(name2
,"%.6s.XXXXXX",remote_machine
);
555 /* sanitise the name */
556 for (s
=name2
; *s
; s
++)
557 if (!issafe(*s
)) *s
= '_';
558 strcpy(name
,(char *)mktemp(name2
));
563 /* stat the name - if it exists then we are all done! */
564 if (sys_stat(name
,&st
) == 0)
569 DEBUG(5,("unix_convert(%s,%d)\n",name
,cnum
));
571 /* a special case - if we don't have any mangling chars and are case
572 sensitive then searching won't help */
573 if (case_sensitive
&& !is_mangled(name
) &&
574 !lp_strip_dot() && !use_mangled_map
&& (saved_errno
!= ENOENT
))
577 /* now we need to recursively match the name against the real
578 directory structure */
581 while (strncmp(start
,"./",2) == 0)
584 /* now match each part of the path name separately, trying the names
585 as is first, then trying to scan the directory for matching names */
586 for (;start
;start
= (end
?end
+1:(char *)NULL
))
588 /* pinpoint the end of this section of the filename */
589 end
= strchr(start
, '/');
591 /* chop the name at this point */
594 if(saved_last_component
!= 0)
595 strcpy(saved_last_component
, end
? end
+ 1 : start
);
597 /* check if the name exists up to this point */
598 if (sys_stat(name
, &st
) == 0)
600 /* it exists. it must either be a directory or this must be
601 the last part of the path for it to be OK */
602 if (end
&& !(st
.st_mode
& S_IFDIR
))
604 /* an intermediate part of the name isn't a directory */
605 DEBUG(5,("Not a dir %s\n",start
));
616 /* remember the rest of the pathname so it can be restored
618 if (end
) pstrcpy(rest
,end
+1);
620 /* try to find this part of the path in the directory */
621 if (strchr(start
,'?') || strchr(start
,'*') ||
622 !scan_directory(dirpath
, start
, cnum
, end
?True
:False
))
626 /* an intermediate part of the name can't be found */
627 DEBUG(5,("Intermediate not found %s\n",start
));
629 /* We need to return the fact that the intermediate
630 name resolution failed. This is used to return an
631 error of ERRbadpath rather than ERRbadfile. Some
632 Windows applications depend on the difference between
639 /* just the last part of the name doesn't exist */
640 /* we may need to strupper() or strlower() it in case
641 this conversion is being used for file creation
643 /* if the filename is of mixed case then don't normalise it */
644 if (!case_preserve
&&
645 (!strhasupper(start
) || !strhaslower(start
)))
648 /* check on the mangled stack to see if we can recover the
649 base of the filename */
650 if (is_mangled(start
))
651 check_mangled_stack(start
);
653 DEBUG(5,("New file %s\n",start
));
657 /* restore the rest of the string */
660 strcpy(start
+strlen(start
)+1,rest
);
661 end
= start
+ strlen(start
);
665 /* add to the dirpath that we have resolved so far */
666 if (*dirpath
) strcat(dirpath
,"/");
667 strcat(dirpath
,start
);
669 /* restore the / that we wiped out earlier */
673 /* the name has been resolved */
674 DEBUG(5,("conversion finished %s\n",name
));
679 /****************************************************************************
680 normalise for DOS usage
681 ****************************************************************************/
682 static void disk_norm(int *bsize
,int *dfree
,int *dsize
)
684 /* check if the disk is beyond the max disk size */
685 int maxdisksize
= lp_maxdisksize();
687 /* convert to blocks - and don't overflow */
688 maxdisksize
= ((maxdisksize
*1024)/(*bsize
))*1024;
689 if (*dsize
> maxdisksize
) *dsize
= maxdisksize
;
690 if (*dfree
> maxdisksize
) *dfree
= maxdisksize
-1; /* the -1 should stop
695 while (*dfree
> WORDMAX
|| *dsize
> WORDMAX
|| *bsize
< 512)
700 if (*bsize
> WORDMAX
)
703 if (*dsize
> WORDMAX
)
705 if (*dfree
> WORDMAX
)
712 /****************************************************************************
713 return number of 1K blocks available on a path and total number
714 ****************************************************************************/
715 int disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
717 char *df_command
= lp_dfree_command();
738 /* possibly use system() to get the result */
739 if (df_command
&& *df_command
)
745 sprintf(outfile
,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
746 sprintf(syscmd
,"%s %s",df_command
,path
);
747 standard_sub_basic(syscmd
);
749 ret
= smbrun(syscmd
,outfile
,False
);
750 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
753 FILE *f
= fopen(outfile
,"r");
759 fscanf(f
,"%d %d %d",dsize
,dfree
,bsize
);
763 DEBUG(0,("Can't open %s\n",outfile
));
767 disk_norm(bsize
,dfree
,dsize
);
768 dfree_retval
= ((*bsize
)/1024)*(*dfree
);
770 /* Ensure we return the min value between the users quota and
771 what's free on the disk. Thanks to Albrecht Gebhardt
772 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
774 if (disk_quotas(path
, &bsizeq
, &dfreeq
, &dsizeq
))
776 disk_norm(&bsizeq
, &dfreeq
, &dsizeq
);
777 dfreeq_retval
= ((bsizeq
)/1024)*(dfreeq
);
778 dfree_retval
= ( dfree_retval
< dfreeq_retval
) ?
779 dfree_retval
: dfreeq_retval
;
780 /* maybe dfree and dfreeq are calculated using different bsizes
781 so convert dfree from bsize into bsizeq */
782 /* avoid overflows due to multiplication, so do not:
783 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
784 bsize and bsizeq are powers of 2 so its better to
785 to divide them getting a multiplication or division factor
786 for dfree. Rene Nieuwenhuizen (07-10-1997) */
787 if (*bsize
>= bsizeq
)
788 *dfree
= *dfree
* (*bsize
/ bsizeq
);
790 *dfree
= *dfree
/ (bsizeq
/ *bsize
);
791 *dfree
= ( *dfree
< dfreeq
) ? *dfree
: dfreeq
;
796 return(dfree_retval
);
800 DEBUG(1,("Warning - no statfs function\n"));
804 if (statfs(path
,&fs
,sizeof(fs
),0) != 0)
807 if (statvfs(path
, &fs
))
810 if (statfs(path
,&fs
,sizeof(fs
)) == -1)
812 if (statfs(path
,&fs
) == -1)
814 #endif /* USE_STATVFS */
817 DEBUG(3,("dfree call failed code errno=%d\n",errno
));
821 return(((*bsize
)/1024)*(*dfree
));
826 *dfree
= fs
.fd_req
.bfree
;
827 *dsize
= fs
.fd_req
.btot
;
830 *bsize
= fs
.f_frsize
;
833 /* eg: osf1 has f_fsize = fundamental filesystem block size,
834 f_bsize = optimal transfer block size (MX: 94-04-19) */
839 #endif /* USE_STATVFS */
844 *dfree
= fs
.f_bavail
;
846 *dsize
= fs
.f_blocks
;
849 #if defined(SCO) || defined(ISC) || defined(MIPS)
853 /* handle rediculous bsize values - some OSes are broken */
854 if ((*bsize
) < 512 || (*bsize
)>0xFFFF) *bsize
= 1024;
856 disk_norm(bsize
,dfree
,dsize
);
862 DEBUG(0,("dfree seems to be broken on your system\n"));
863 *dsize
= 20*1024*1024/(*bsize
);
864 *dfree
= MAX(1,*dfree
);
866 dfree_retval
= ((*bsize
)/1024)*(*dfree
);
868 /* Ensure we return the min value between the users quota and
869 what's free on the disk. Thanks to Albrecht Gebhardt
870 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
872 if (disk_quotas(path
, &bsizeq
, &dfreeq
, &dsizeq
))
874 disk_norm(&bsizeq
, &dfreeq
, &dsizeq
);
875 dfreeq_retval
= ((bsizeq
)/1024)*(dfreeq
);
876 dfree_retval
= ( dfree_retval
< dfreeq_retval
) ?
877 dfree_retval
: dfreeq_retval
;
878 /* maybe dfree and dfreeq are calculated using different bsizes
879 so convert dfree from bsize into bsizeq */
880 /* avoid overflows due to multiplication, so do not:
881 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
882 bsize and bsizeq are powers of 2 so its better to
883 to divide them getting a multiplication or division factor
884 for dfree. Rene Nieuwenhuizen (07-10-1997) */
885 if (*bsize
>= bsizeq
)
886 *dfree
= *dfree
* (*bsize
/ bsizeq
);
888 *dfree
= *dfree
/ (bsizeq
/ *bsize
);
889 *dfree
= ( *dfree
< dfreeq
) ? *dfree
: dfreeq
;
894 return(dfree_retval
);
899 /****************************************************************************
900 wrap it to get filenames right
901 ****************************************************************************/
902 int sys_disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
904 return(disk_free(dos_to_unix(path
,False
),bsize
,dfree
,dsize
));
909 /****************************************************************************
910 check a filename - possibly caling reducename
912 This is called by every routine before it allows an operation on a filename.
913 It does any final confirmation necessary to ensure that the filename is
914 a valid one for the user to access.
915 ****************************************************************************/
916 BOOL
check_name(char *name
,int cnum
)
922 if( IS_VETO_PATH(cnum
, name
))
924 DEBUG(5,("file path name %s vetoed\n",name
));
928 ret
= reduce_name(name
,Connections
[cnum
].connectpath
,lp_widelinks(SNUM(cnum
)));
930 /* Check if we are allowing users to follow symlinks */
931 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
932 University of Geneva */
935 if (!lp_symlinks(SNUM(cnum
)))
938 if ( (sys_lstat(name
,&statbuf
) != -1) &&
939 (S_ISLNK(statbuf
.st_mode
)) )
941 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name
));
948 DEBUG(5,("check_name on %s failed\n",name
));
953 /****************************************************************************
954 check a filename - possibly caling reducename
955 ****************************************************************************/
956 static void check_for_pipe(char *fname
)
958 /* special case of pipe opens */
962 if (strstr(s
,"pipe/"))
964 DEBUG(3,("Rejecting named pipe open for %s\n",fname
));
965 unix_ERR_class
= ERRSRV
;
966 unix_ERR_code
= ERRaccess
;
970 /****************************************************************************
971 fd support routines - attempt to do a sys_open
972 ****************************************************************************/
973 static int fd_attempt_open(char *fname
, int flags
, int mode
)
975 int fd
= sys_open(fname
,flags
,mode
);
977 /* Fix for files ending in '.' */
978 if((fd
== -1) && (errno
== ENOENT
) &&
979 (strchr(fname
,'.')==NULL
))
982 fd
= sys_open(fname
,flags
,mode
);
985 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
986 if ((fd
== -1) && (errno
== ENAMETOOLONG
))
989 char *p
= strrchr(fname
, '/');
991 if (p
== fname
) /* name is "/xxx" */
993 max_len
= pathconf("/", _PC_NAME_MAX
);
996 else if ((p
== NULL
) || (p
== fname
))
999 max_len
= pathconf(".", _PC_NAME_MAX
);
1004 max_len
= pathconf(fname
, _PC_NAME_MAX
);
1008 if (strlen(p
) > max_len
)
1010 char tmp
= p
[max_len
];
1013 if ((fd
= sys_open(fname
,flags
,mode
)) == -1)
1021 /****************************************************************************
1022 fd support routines - attempt to find an already open file by dev
1023 and inode - increments the ref_count of the returned file_fd_struct *.
1024 ****************************************************************************/
1025 static file_fd_struct
*fd_get_already_open(struct stat
*sbuf
)
1028 file_fd_struct
*fd_ptr
;
1033 for(i
= 0; i
<= max_file_fd_used
; i
++) {
1034 fd_ptr
= &FileFd
[i
];
1035 if((fd_ptr
->ref_count
> 0) &&
1036 (((uint32
)sbuf
->st_dev
) == fd_ptr
->dev
) &&
1037 (((uint32
)sbuf
->st_ino
) == fd_ptr
->inode
)) {
1038 fd_ptr
->ref_count
++;
1040 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1041 i
, fd_ptr
->dev
, fd_ptr
->inode
, fd_ptr
->ref_count
));
1048 /****************************************************************************
1049 fd support routines - attempt to find a empty slot in the FileFd array.
1050 Increments the ref_count of the returned entry.
1051 ****************************************************************************/
1052 static file_fd_struct
*fd_get_new()
1055 file_fd_struct
*fd_ptr
;
1057 for(i
= 0; i
< MAX_OPEN_FILES
; i
++) {
1058 fd_ptr
= &FileFd
[i
];
1059 if(fd_ptr
->ref_count
== 0) {
1060 fd_ptr
->dev
= (uint32
)-1;
1061 fd_ptr
->inode
= (uint32
)-1;
1063 fd_ptr
->fd_readonly
= -1;
1064 fd_ptr
->fd_writeonly
= -1;
1065 fd_ptr
->real_open_flags
= -1;
1066 fd_ptr
->ref_count
++;
1067 /* Increment max used counter if neccessary, cuts down
1068 on search time when re-using */
1069 if(i
> max_file_fd_used
)
1070 max_file_fd_used
= i
;
1071 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1072 i
, fd_ptr
->dev
, fd_ptr
->inode
));
1076 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1081 /****************************************************************************
1082 fd support routines - attempt to re-open an already open fd as O_RDWR.
1083 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1084 ****************************************************************************/
1085 static void fd_attempt_reopen(char *fname
, int mode
, file_fd_struct
*fd_ptr
)
1087 int fd
= sys_open( fname
, O_RDWR
, mode
);
1092 if(fd_ptr
->real_open_flags
== O_RDONLY
)
1093 fd_ptr
->fd_readonly
= fd_ptr
->fd
;
1094 if(fd_ptr
->real_open_flags
== O_WRONLY
)
1095 fd_ptr
->fd_writeonly
= fd_ptr
->fd
;
1098 fd_ptr
->real_open_flags
= O_RDWR
;
1101 /****************************************************************************
1102 fd support routines - attempt to close the file referenced by this fd.
1103 Decrements the ref_count and returns it.
1104 ****************************************************************************/
1105 static int fd_attempt_close(file_fd_struct
*fd_ptr
)
1107 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1108 fd_ptr
- &FileFd
[0],
1109 fd_ptr
->fd
, fd_ptr
->dev
, fd_ptr
->inode
,
1110 fd_ptr
->real_open_flags
,
1111 fd_ptr
->ref_count
));
1112 if(fd_ptr
->ref_count
> 0) {
1113 fd_ptr
->ref_count
--;
1114 if(fd_ptr
->ref_count
== 0) {
1115 if(fd_ptr
->fd
!= -1)
1117 if(fd_ptr
->fd_readonly
!= -1)
1118 close(fd_ptr
->fd_readonly
);
1119 if(fd_ptr
->fd_writeonly
!= -1)
1120 close(fd_ptr
->fd_writeonly
);
1122 fd_ptr
->fd_readonly
= -1;
1123 fd_ptr
->fd_writeonly
= -1;
1124 fd_ptr
->real_open_flags
= -1;
1125 fd_ptr
->dev
= (uint32
)-1;
1126 fd_ptr
->inode
= (uint32
)-1;
1129 return fd_ptr
->ref_count
;
1132 /****************************************************************************
1134 ****************************************************************************/
1135 static void open_file(int fnum
,int cnum
,char *fname1
,int flags
,int mode
, struct stat
*sbuf
)
1137 extern struct current_user current_user
;
1139 struct stat statbuf
;
1140 file_fd_struct
*fd_ptr
;
1141 files_struct
*fsp
= &Files
[fnum
];
1145 fsp
->granted_oplock
= False
;
1148 pstrcpy(fname
,fname1
);
1150 /* check permissions */
1151 if ((flags
!= O_RDONLY
) && !CAN_WRITE(cnum
) && !Connections
[cnum
].printer
)
1153 DEBUG(3,("Permission denied opening %s\n",fname
));
1154 check_for_pipe(fname
);
1158 /* this handles a bug in Win95 - it doesn't say to create the file when it
1160 if (Connections
[cnum
].printer
)
1164 if (flags == O_WRONLY)
1165 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1169 * Ensure we have a valid struct stat so we can search the
1173 if(stat(fname
, &statbuf
) < 0) {
1174 if(errno
!= ENOENT
) {
1175 DEBUG(3,("Error doing stat on file %s (%s)\n",
1176 fname
,strerror(errno
)));
1178 check_for_pipe(fname
);
1188 * Check to see if we have this file already
1189 * open. If we do, just use the already open fd and increment the
1190 * reference count (fd_get_already_open increments the ref_count).
1192 if((fd_ptr
= fd_get_already_open(sbuf
))!= 0) {
1194 int accmode
= (flags
& (O_RDONLY
| O_WRONLY
| O_RDWR
));
1196 /* File was already open. */
1197 if((flags
& O_CREAT
) && (flags
& O_EXCL
)) {
1198 fd_ptr
->ref_count
--;
1204 * If not opened O_RDWR try
1205 * and do that here - a chmod may have been done
1206 * between the last open and now.
1208 if(fd_ptr
->real_open_flags
!= O_RDWR
)
1209 fd_attempt_reopen(fname
, mode
, fd_ptr
);
1212 * Ensure that if we wanted write access
1213 * it has been opened for write, and if we wanted read it
1214 * was open for read.
1216 if(((accmode
== O_WRONLY
) && (fd_ptr
->real_open_flags
== O_RDONLY
)) ||
1217 ((accmode
== O_RDONLY
) && (fd_ptr
->real_open_flags
== O_WRONLY
)) ||
1218 ((accmode
== O_RDWR
) && (fd_ptr
->real_open_flags
!= O_RDWR
))) {
1219 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1220 fd_ptr
->real_open_flags
, fname
,strerror(EACCES
),flags
));
1221 check_for_pipe(fname
);
1222 fd_ptr
->ref_count
--;
1228 /* We need to allocate a new file_fd_struct (this increments the
1230 if((fd_ptr
= fd_get_new()) == 0)
1233 * Whatever the requested flags, attempt read/write access,
1234 * as we don't know what flags future file opens may require.
1235 * If this fails, try again with the required flags.
1236 * Even if we open read/write when only read access was
1237 * requested the setting of the can_write flag in
1238 * the file_struct will protect us from errant
1239 * write requests. We never need to worry about O_APPEND
1240 * as this is not set anywhere in Samba.
1242 fd_ptr
->real_open_flags
= O_RDWR
;
1243 /* Set the flags as needed without the read/write modes. */
1244 open_flags
= flags
& ~(O_RDWR
|O_WRONLY
|O_RDONLY
);
1245 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDWR
, mode
);
1247 * On some systems opening a file for R/W access on a read only
1248 * filesystems sets errno to EROFS.
1251 if((fd_ptr
->fd
== -1) && ((errno
== EACCES
) || (errno
== EROFS
))) {
1252 #else /* No EROFS */
1253 if((fd_ptr
->fd
== -1) && (errno
== EACCES
)) {
1255 if(flags
& O_WRONLY
) {
1256 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_WRONLY
, mode
);
1257 fd_ptr
->real_open_flags
= O_WRONLY
;
1259 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDONLY
, mode
);
1260 fd_ptr
->real_open_flags
= O_RDONLY
;
1265 if ((fd_ptr
->fd
>=0) &&
1266 Connections
[cnum
].printer
&& lp_minprintspace(SNUM(cnum
))) {
1270 pstrcpy(dname
,fname
);
1271 p
= strrchr(dname
,'/');
1273 if (sys_disk_free(dname
,&dum1
,&dum2
,&dum3
) <
1274 lp_minprintspace(SNUM(cnum
))) {
1275 fd_attempt_close(fd_ptr
);
1277 if(fd_ptr
->ref_count
== 0)
1286 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1287 fname
,strerror(errno
),flags
));
1288 /* Ensure the ref_count is decremented. */
1289 fd_attempt_close(fd_ptr
);
1290 check_for_pipe(fname
);
1294 if (fd_ptr
->fd
>= 0)
1298 if(fstat(fd_ptr
->fd
, &statbuf
) == -1) {
1299 /* Error - backout !! */
1300 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1301 fd_ptr
->fd
, fname
,strerror(errno
)));
1302 /* Ensure the ref_count is decremented. */
1303 fd_attempt_close(fd_ptr
);
1308 /* Set the correct entries in fd_ptr. */
1309 fd_ptr
->dev
= (uint32
)sbuf
->st_dev
;
1310 fd_ptr
->inode
= (uint32
)sbuf
->st_ino
;
1312 fsp
->fd_ptr
= fd_ptr
;
1313 Connections
[cnum
].num_files_open
++;
1314 fsp
->mode
= sbuf
->st_mode
;
1315 GetTimeOfDay(&fsp
->open_time
);
1316 fsp
->uid
= current_user
.id
;
1320 fsp
->mmap_ptr
= NULL
;
1322 fsp
->can_lock
= True
;
1323 fsp
->can_read
= ((flags
& O_WRONLY
)==0);
1324 fsp
->can_write
= ((flags
& (O_WRONLY
|O_RDWR
))!=0);
1325 fsp
->share_mode
= 0;
1326 fsp
->print_file
= Connections
[cnum
].printer
;
1327 fsp
->modified
= False
;
1328 fsp
->granted_oplock
= False
;
1330 string_set(&fsp
->name
,dos_to_unix(fname
,False
));
1331 fsp
->wbmpx_ptr
= NULL
;
1334 * If the printer is marked as postscript output a leading
1335 * file identifier to ensure the file is treated as a raw
1337 * This has a similar effect as CtrlD=0 in WIN.INI file.
1338 * tim@fsg.com 09/06/94
1340 if (fsp
->print_file
&& POSTSCRIPT(cnum
) &&
1343 DEBUG(3,("Writing postscript line\n"));
1344 write_file(fnum
,"%!\n",3);
1347 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1348 timestring(),Connections
[cnum
].user
,fname
,
1349 BOOLSTR(fsp
->can_read
),BOOLSTR(fsp
->can_write
),
1350 Connections
[cnum
].num_files_open
,fnum
));
1355 /* mmap it if read-only */
1356 if (!fsp
->can_write
)
1358 fsp
->mmap_size
= file_size(fname
);
1359 fsp
->mmap_ptr
= (char *)mmap(NULL
,fsp
->mmap_size
,
1360 PROT_READ
,MAP_SHARED
,fsp
->fd_ptr
->fd
,0);
1362 if (fsp
->mmap_ptr
== (char *)-1 || !fsp
->mmap_ptr
)
1364 DEBUG(3,("Failed to mmap() %s - %s\n",fname
,strerror(errno
)));
1365 fsp
->mmap_ptr
= NULL
;
1371 /*******************************************************************
1373 ********************************************************************/
1374 void sync_file(int fnum
)
1377 fsync(Files
[fnum
].fd_ptr
->fd
);
1381 /****************************************************************************
1382 run a file if it is a magic script
1383 ****************************************************************************/
1384 static void check_magic(int fnum
,int cnum
)
1386 if (!*lp_magicscript(SNUM(cnum
)))
1389 DEBUG(5,("checking magic for %s\n",Files
[fnum
].name
));
1393 if (!(p
= strrchr(Files
[fnum
].name
,'/')))
1394 p
= Files
[fnum
].name
;
1398 if (!strequal(lp_magicscript(SNUM(cnum
)),p
))
1404 pstring magic_output
;
1406 pstrcpy(fname
,Files
[fnum
].name
);
1408 if (*lp_magicoutput(SNUM(cnum
)))
1409 pstrcpy(magic_output
,lp_magicoutput(SNUM(cnum
)));
1411 sprintf(magic_output
,"%s.out",fname
);
1414 ret
= smbrun(fname
,magic_output
,False
);
1415 DEBUG(3,("Invoking magic command %s gave %d\n",fname
,ret
));
1421 /****************************************************************************
1422 close a file - possibly invalidating the read prediction
1424 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1425 operation otherwise it came as the result of some other operation such as
1426 the closing of the connection. In the latter case printing and
1427 magic scripts are not run
1428 ****************************************************************************/
1429 void close_file(int fnum
, BOOL normal_close
)
1431 files_struct
*fs_p
= &Files
[fnum
];
1432 int cnum
= fs_p
->cnum
;
1433 uint32 dev
= fs_p
->fd_ptr
->dev
;
1434 uint32 inode
= fs_p
->fd_ptr
->inode
;
1437 #if USE_READ_PREDICTION
1438 invalidate_read_prediction(fs_p
->fd_ptr
->fd
);
1442 Connections
[cnum
].num_files_open
--;
1445 free((char *)fs_p
->wbmpx_ptr
);
1446 fs_p
->wbmpx_ptr
= NULL
;
1452 munmap(fs_p
->mmap_ptr
,fs_p
->mmap_size
);
1453 fs_p
->mmap_ptr
= NULL
;
1457 if (lp_share_modes(SNUM(cnum
)))
1459 lock_share_entry( cnum
, dev
, inode
, &token
);
1460 del_share_mode(token
, fnum
);
1463 fd_attempt_close(fs_p
->fd_ptr
);
1465 if (lp_share_modes(SNUM(cnum
)))
1466 unlock_share_entry( cnum
, dev
, inode
, token
);
1468 /* NT uses smbclose to start a print - weird */
1469 if (normal_close
&& fs_p
->print_file
)
1472 /* check for magic scripts */
1474 check_magic(fnum
,cnum
);
1476 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1477 timestring(),Connections
[cnum
].user
,fs_p
->name
,
1478 Connections
[cnum
].num_files_open
));
1481 enum {AFAIL
,AREAD
,AWRITE
,AALL
};
1483 /*******************************************************************
1484 reproduce the share mode access table
1485 ********************************************************************/
1486 static int access_table(int new_deny
,int old_deny
,int old_mode
,
1487 int share_pid
,char *fname
)
1489 if (new_deny
== DENY_ALL
|| old_deny
== DENY_ALL
) return(AFAIL
);
1491 if (new_deny
== DENY_DOS
|| old_deny
== DENY_DOS
) {
1493 if (old_deny
== new_deny
&& share_pid
== pid
)
1496 if (old_mode
== 0) return(AREAD
);
1498 /* the new smbpub.zip spec says that if the file extension is
1499 .com, .dll, .exe or .sym then allow the open. I will force
1500 it to read-only as this seems sensible although the spec is
1501 a little unclear on this. */
1502 if ((fname
= strrchr(fname
,'.'))) {
1503 if (strequal(fname
,".com") ||
1504 strequal(fname
,".dll") ||
1505 strequal(fname
,".exe") ||
1506 strequal(fname
,".sym"))
1516 if (old_deny
==DENY_WRITE
&& old_mode
==0) return(AREAD
);
1517 if (old_deny
==DENY_READ
&& old_mode
==0) return(AWRITE
);
1518 if (old_deny
==DENY_NONE
&& old_mode
==0) return(AALL
);
1521 if (old_deny
==DENY_WRITE
&& old_mode
==1) return(AREAD
);
1522 if (old_deny
==DENY_READ
&& old_mode
==1) return(AWRITE
);
1523 if (old_deny
==DENY_NONE
&& old_mode
==1) return(AALL
);
1526 if (old_deny
==DENY_WRITE
) return(AREAD
);
1527 if (old_deny
==DENY_READ
) return(AWRITE
);
1528 if (old_deny
==DENY_NONE
) return(AALL
);
1534 /*******************************************************************
1535 check if the share mode on a file allows it to be deleted or unlinked
1536 return True if sharing doesn't prevent the operation
1537 ********************************************************************/
1538 BOOL
check_file_sharing(int cnum
,char *fname
)
1542 share_mode_entry
*old_shares
= 0;
1543 int num_share_modes
;
1549 if(!lp_share_modes(SNUM(cnum
)))
1552 if (stat(fname
,&sbuf
) == -1) return(True
);
1554 dev
= (uint32
)sbuf
.st_dev
;
1555 inode
= (uint32
)sbuf
.st_ino
;
1557 lock_share_entry(cnum
, dev
, inode
, &token
);
1558 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1561 * Check if the share modes will give us access.
1564 if(num_share_modes
!= 0)
1571 broke_oplock
= False
;
1572 for(i
= 0; i
< num_share_modes
; i
++)
1574 share_mode_entry
*share_entry
= &old_shares
[i
];
1577 * Break oplocks before checking share modes. See comment in
1578 * open_file_shared for details.
1579 * Check if someone has an oplock on this file. If so we must
1580 * break it before continuing.
1582 if(share_entry
->op_type
& BATCH_OPLOCK
)
1585 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1586 dev = %x, inode = %x\n", share_entry
->op_type
, fname
, dev
, inode
));
1588 /* Oplock break.... */
1589 unlock_share_entry(cnum
, dev
, inode
, token
);
1590 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
1592 free((char *)old_shares
);
1593 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1594 dev = %x, inode = %x\n", old_shares
[i
].op_type
, fname
, dev
, inode
));
1597 lock_share_entry(cnum
, dev
, inode
, &token
);
1598 broke_oplock
= True
;
1602 /* someone else has a share lock on it, check to see
1604 if ((share_entry
->share_mode
!= DENY_DOS
) || (share_entry
->pid
!= pid
))
1611 free((char *)old_shares
);
1612 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1614 } while(broke_oplock
);
1617 /* XXXX exactly what share mode combinations should be allowed for
1618 deleting/renaming? */
1619 /* If we got here then either there were no share modes or
1620 all share modes were DENY_DOS and the pid == getpid() */
1625 unlock_share_entry(cnum
, dev
, inode
, token
);
1626 if(old_shares
!= NULL
)
1627 free((char *)old_shares
);
1631 /****************************************************************************
1633 Helper for open_file_shared.
1634 Truncate a file after checking locking; close file if locked.
1635 **************************************************************************/
1636 static void truncate_unless_locked(int fnum
, int cnum
, int token
,
1639 if (Files
[fnum
].can_write
){
1640 if (is_locked(fnum
,cnum
,0x3FFFFFFF,0)){
1641 /* If share modes are in force for this connection we
1642 have the share entry locked. Unlock it before closing. */
1643 if (*share_locked
&& lp_share_modes(SNUM(cnum
)))
1644 unlock_share_entry( cnum
, Files
[fnum
].fd_ptr
->dev
,
1645 Files
[fnum
].fd_ptr
->inode
, token
);
1646 close_file(fnum
,False
);
1647 /* Share mode no longer locked. */
1648 *share_locked
= False
;
1650 unix_ERR_class
= ERRDOS
;
1651 unix_ERR_code
= ERRlock
;
1654 ftruncate(Files
[fnum
].fd_ptr
->fd
,0);
1658 /****************************************************************************
1659 check if we can open a file with a share mode
1660 ****************************************************************************/
1661 int check_share_mode( share_mode_entry
*share
, int deny_mode
, char *fname
,
1662 BOOL fcbopen
, int *flags
)
1664 int old_open_mode
= share
->share_mode
&0xF;
1665 int old_deny_mode
= (share
->share_mode
>>4)&7;
1667 if (old_deny_mode
> 4 || old_open_mode
> 2)
1669 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1670 deny_mode
,old_deny_mode
,old_open_mode
,fname
));
1675 int access_allowed
= access_table(deny_mode
,old_deny_mode
,old_open_mode
,
1678 if ((access_allowed
== AFAIL
) ||
1679 (!fcbopen
&& (access_allowed
== AREAD
&& *flags
== O_RDWR
)) ||
1680 (access_allowed
== AREAD
&& *flags
== O_WRONLY
) ||
1681 (access_allowed
== AWRITE
&& *flags
== O_RDONLY
))
1683 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1684 deny_mode
,old_deny_mode
,old_open_mode
,
1685 share
->pid
,fname
, access_allowed
));
1689 if (access_allowed
== AREAD
)
1692 if (access_allowed
== AWRITE
)
1699 /****************************************************************************
1700 open a file with a share mode
1701 ****************************************************************************/
1702 void open_file_shared(int fnum
,int cnum
,char *fname
,int share_mode
,int ofun
,
1703 int mode
,int oplock_request
, int *Access
,int *action
)
1705 files_struct
*fs_p
= &Files
[fnum
];
1708 int deny_mode
= (share_mode
>>4)&7;
1710 BOOL file_existed
= file_exist(fname
,&sbuf
);
1711 BOOL share_locked
= False
;
1712 BOOL fcbopen
= False
;
1716 int num_share_modes
= 0;
1721 /* this is for OS/2 EAs - try and say we don't support them */
1722 if (strstr(fname
,".+,;=[]."))
1724 unix_ERR_class
= ERRDOS
;
1725 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1727 unix_ERR_code
= ERRcannotopen
;
1728 #else /* OS2_WPS_FIX */
1729 unix_ERR_code
= ERROR_EAS_NOT_SUPPORTED
;
1730 #endif /* OS2_WPS_FIX */
1735 if ((ofun
& 0x3) == 0 && file_existed
)
1743 if ((ofun
& 0x3) == 2)
1746 /* note that we ignore the append flag as
1747 append does not mean the same thing under dos and unix */
1749 switch (share_mode
&0xF)
1766 if (flags
!= O_RDONLY
&& file_existed
&&
1767 (!CAN_WRITE(cnum
) || IS_DOS_READONLY(dos_mode(cnum
,fname
,&sbuf
))))
1777 if (deny_mode
> DENY_NONE
&& deny_mode
!=DENY_FCB
)
1779 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode
,fname
));
1784 if (deny_mode
== DENY_FCB
) deny_mode
= DENY_DOS
;
1786 if (lp_share_modes(SNUM(cnum
)))
1789 share_mode_entry
*old_shares
= 0;
1793 dev
= (uint32
)sbuf
.st_dev
;
1794 inode
= (uint32
)sbuf
.st_ino
;
1795 lock_share_entry(cnum
, dev
, inode
, &token
);
1796 share_locked
= True
;
1797 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1801 * Check if the share modes will give us access.
1804 if(share_locked
&& (num_share_modes
!= 0))
1811 broke_oplock
= False
;
1812 for(i
= 0; i
< num_share_modes
; i
++)
1814 share_mode_entry
*share_entry
= &old_shares
[i
];
1817 * By observation of NetBench, oplocks are broken *before* share
1818 * modes are checked. This allows a file to be closed by the client
1819 * if the share mode would deny access and the client has an oplock.
1820 * Check if someone has an oplock on this file. If so we must break
1821 * it before continuing.
1823 if(share_entry
->op_type
& (EXCLUSIVE_OPLOCK
|BATCH_OPLOCK
))
1826 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1827 dev = %x, inode = %x\n", share_entry
->op_type
, fname
, dev
, inode
));
1829 /* Oplock break.... */
1830 unlock_share_entry(cnum
, dev
, inode
, token
);
1831 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
1833 free((char *)old_shares
);
1834 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1835 dev = %x, inode = %x\n", old_shares
[i
].op_type
, fname
, dev
, inode
));
1837 unix_ERR_class
= ERRDOS
;
1838 unix_ERR_code
= ERRbadshare
;
1841 lock_share_entry(cnum
, dev
, inode
, &token
);
1842 broke_oplock
= True
;
1846 /* someone else has a share lock on it, check to see
1848 if(check_share_mode(share_entry
, deny_mode
, fname
, fcbopen
, &flags
) == False
)
1850 free((char *)old_shares
);
1851 unlock_share_entry(cnum
, dev
, inode
, token
);
1853 unix_ERR_class
= ERRDOS
;
1854 unix_ERR_code
= ERRbadshare
;
1862 free((char *)old_shares
);
1863 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1865 } while(broke_oplock
);
1869 free((char *)old_shares
);
1872 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1873 flags
,flags2
,mode
));
1875 open_file(fnum
,cnum
,fname
,flags
|(flags2
&~(O_TRUNC
)),mode
,file_existed
? &sbuf
: 0);
1876 if (!fs_p
->open
&& flags
==O_RDWR
&& errno
!=ENOENT
&& fcbopen
)
1879 open_file(fnum
,cnum
,fname
,flags
,mode
,file_existed
? &sbuf
: 0 );
1886 if((share_locked
== False
) && lp_share_modes(SNUM(cnum
)))
1888 /* We created the file - thus we must now lock the share entry before creating it. */
1889 dev
= fs_p
->fd_ptr
->dev
;
1890 inode
= fs_p
->fd_ptr
->inode
;
1891 lock_share_entry(cnum
, dev
, inode
, &token
);
1892 share_locked
= True
;
1908 fs_p
->share_mode
= (deny_mode
<<4) | open_mode
;
1911 (*Access
) = open_mode
;
1915 if (file_existed
&& !(flags2
& O_TRUNC
)) *action
= 1;
1916 if (!file_existed
) *action
= 2;
1917 if (file_existed
&& (flags2
& O_TRUNC
)) *action
= 3;
1919 /* We must create the share mode entry before truncate as
1920 truncate can fail due to locking and have to close the
1921 file (which expects the share_mode_entry to be there).
1923 if (lp_share_modes(SNUM(cnum
)))
1926 /* JRA. Currently this only services Exlcusive and batch
1927 oplocks (no other opens on this file). This needs to
1928 be extended to level II oplocks (multiple reader
1931 if(oplock_request
&& (num_share_modes
== 0) && lp_oplocks(SNUM(cnum
)))
1933 fs_p
->granted_oplock
= True
;
1934 global_oplocks_open
++;
1937 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1938 dev = %x, inode = %x\n", oplock_request
, fname
, dev
, inode
));
1946 set_share_mode(token
, fnum
, port
, oplock_request
);
1949 if ((flags2
&O_TRUNC
) && file_existed
)
1950 truncate_unless_locked(fnum
,cnum
,token
,&share_locked
);
1953 if (share_locked
&& lp_share_modes(SNUM(cnum
)))
1954 unlock_share_entry( cnum
, dev
, inode
, token
);
1957 /****************************************************************************
1958 seek a file. Try to avoid the seek if possible
1959 ****************************************************************************/
1960 int seek_file(int fnum
,uint32 pos
)
1963 if (Files
[fnum
].print_file
&& POSTSCRIPT(Files
[fnum
].cnum
))
1966 Files
[fnum
].pos
= (int)(lseek(Files
[fnum
].fd_ptr
->fd
,pos
+offset
,SEEK_SET
)
1968 return(Files
[fnum
].pos
);
1971 /****************************************************************************
1973 ****************************************************************************/
1974 int read_file(int fnum
,char *data
,uint32 pos
,int n
)
1978 #if USE_READ_PREDICTION
1979 if (!Files
[fnum
].can_write
)
1981 ret
= read_predict(Files
[fnum
].fd_ptr
->fd
,pos
,data
,NULL
,n
);
1990 if (Files
[fnum
].mmap_ptr
)
1992 int num
= MIN(n
,(int)(Files
[fnum
].mmap_size
-pos
));
1995 memcpy(data
,Files
[fnum
].mmap_ptr
+pos
,num
);
2007 if (seek_file(fnum
,pos
) != pos
)
2009 DEBUG(3,("Failed to seek to %d\n",pos
));
2014 readret
= read(Files
[fnum
].fd_ptr
->fd
,data
,n
);
2015 if (readret
> 0) ret
+= readret
;
2022 /****************************************************************************
2024 ****************************************************************************/
2025 int write_file(int fnum
,char *data
,int n
)
2027 if (!Files
[fnum
].can_write
) {
2032 if (!Files
[fnum
].modified
) {
2034 Files
[fnum
].modified
= True
;
2035 if (fstat(Files
[fnum
].fd_ptr
->fd
,&st
) == 0) {
2036 int dosmode
= dos_mode(Files
[fnum
].cnum
,Files
[fnum
].name
,&st
);
2037 if (MAP_ARCHIVE(Files
[fnum
].cnum
) && !IS_DOS_ARCHIVE(dosmode
)) {
2038 dos_chmod(Files
[fnum
].cnum
,Files
[fnum
].name
,dosmode
| aARCH
,&st
);
2043 return(write_data(Files
[fnum
].fd_ptr
->fd
,data
,n
));
2047 /****************************************************************************
2048 load parameters specific to a connection/service
2049 ****************************************************************************/
2050 BOOL
become_service(int cnum
,BOOL do_chdir
)
2052 extern char magic_char
;
2053 static int last_cnum
= -1;
2056 if (!OPEN_CNUM(cnum
))
2062 Connections
[cnum
].lastused
= smb_last_time
;
2067 ChDir(Connections
[cnum
].connectpath
) != 0 &&
2068 ChDir(Connections
[cnum
].origpath
) != 0)
2070 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2071 Connections
[cnum
].connectpath
,cnum
));
2075 if (cnum
== last_cnum
)
2080 case_default
= lp_defaultcase(snum
);
2081 case_preserve
= lp_preservecase(snum
);
2082 short_case_preserve
= lp_shortpreservecase(snum
);
2083 case_mangle
= lp_casemangle(snum
);
2084 case_sensitive
= lp_casesensitive(snum
);
2085 magic_char
= lp_magicchar(snum
);
2086 use_mangled_map
= (*lp_mangled_map(snum
) ? True
:False
);
2091 /****************************************************************************
2092 find a service entry
2093 ****************************************************************************/
2094 int find_service(char *service
)
2098 string_sub(service
,"\\","/");
2100 iService
= lp_servicenumber(service
);
2102 /* now handle the special case of a home directory */
2105 char *phome_dir
= get_home_dir(service
);
2106 DEBUG(3,("checking for home directory %s gave %s\n",service
,
2107 phome_dir
?phome_dir
:"(NULL)"));
2111 if ((iHomeService
= lp_servicenumber(HOMES_NAME
)) >= 0)
2113 lp_add_home(service
,iHomeService
,phome_dir
);
2114 iService
= lp_servicenumber(service
);
2119 /* If we still don't have a service, attempt to add it as a printer. */
2122 int iPrinterService
;
2124 if ((iPrinterService
= lp_servicenumber(PRINTERS_NAME
)) >= 0)
2128 DEBUG(3,("checking whether %s is a valid printer name...\n", service
));
2130 if ((pszTemp
!= NULL
) && pcap_printername_ok(service
, pszTemp
))
2132 DEBUG(3,("%s is a valid printer name\n", service
));
2133 DEBUG(3,("adding %s as a printer service\n", service
));
2134 lp_add_printer(service
,iPrinterService
);
2135 iService
= lp_servicenumber(service
);
2137 DEBUG(0,("failed to add %s as a printer service!\n", service
));
2140 DEBUG(3,("%s is not a valid printer name\n", service
));
2144 /* just possibly it's a default service? */
2147 char *defservice
= lp_defaultservice();
2148 if (defservice
&& *defservice
&& !strequal(defservice
,service
)) {
2149 iService
= find_service(defservice
);
2150 if (iService
>= 0) {
2151 string_sub(service
,"_","/");
2152 iService
= lp_add_service(service
,iService
);
2158 if (!VALID_SNUM(iService
))
2160 DEBUG(0,("Invalid snum %d for %s\n",iService
,service
));
2165 DEBUG(3,("find_service() failed to find service %s\n", service
));
2171 /****************************************************************************
2172 create an error packet from a cached error.
2173 ****************************************************************************/
2174 int cached_error_packet(char *inbuf
,char *outbuf
,int fnum
,int line
)
2176 write_bmpx_struct
*wbmpx
= Files
[fnum
].wbmpx_ptr
;
2178 int32 eclass
= wbmpx
->wr_errclass
;
2179 int32 err
= wbmpx
->wr_error
;
2181 /* We can now delete the auxiliary struct */
2182 free((char *)wbmpx
);
2183 Files
[fnum
].wbmpx_ptr
= NULL
;
2184 return error_packet(inbuf
,outbuf
,eclass
,err
,line
);
2193 } unix_smb_errmap
[] =
2195 {EPERM
,ERRDOS
,ERRnoaccess
},
2196 {EACCES
,ERRDOS
,ERRnoaccess
},
2197 {ENOENT
,ERRDOS
,ERRbadfile
},
2198 {ENOTDIR
,ERRDOS
,ERRbadpath
},
2199 {EIO
,ERRHRD
,ERRgeneral
},
2200 {EBADF
,ERRSRV
,ERRsrverror
},
2201 {EINVAL
,ERRSRV
,ERRsrverror
},
2202 {EEXIST
,ERRDOS
,ERRfilexists
},
2203 {ENFILE
,ERRDOS
,ERRnofids
},
2204 {EMFILE
,ERRDOS
,ERRnofids
},
2205 {ENOSPC
,ERRHRD
,ERRdiskfull
},
2207 {EDQUOT
,ERRHRD
,ERRdiskfull
},
2210 {ENOTEMPTY
,ERRDOS
,ERRnoaccess
},
2213 {EXDEV
,ERRDOS
,ERRdiffdevice
},
2215 {EROFS
,ERRHRD
,ERRnowrite
},
2219 /****************************************************************************
2220 create an error packet from errno
2221 ****************************************************************************/
2222 int unix_error_packet(char *inbuf
,char *outbuf
,int def_class
,uint32 def_code
,int line
)
2224 int eclass
=def_class
;
2228 if (unix_ERR_class
!= SUCCESS
)
2230 eclass
= unix_ERR_class
;
2231 ecode
= unix_ERR_code
;
2232 unix_ERR_class
= SUCCESS
;
2237 while (unix_smb_errmap
[i
].smbclass
!= 0)
2239 if (unix_smb_errmap
[i
].unixerror
== errno
)
2241 eclass
= unix_smb_errmap
[i
].smbclass
;
2242 ecode
= unix_smb_errmap
[i
].smbcode
;
2249 return(error_packet(inbuf
,outbuf
,eclass
,ecode
,line
));
2253 /****************************************************************************
2254 create an error packet. Normally called using the ERROR() macro
2255 ****************************************************************************/
2256 int error_packet(char *inbuf
,char *outbuf
,int error_class
,uint32 error_code
,int line
)
2258 int outsize
= set_message(outbuf
,0,0,True
);
2260 cmd
= CVAL(inbuf
,smb_com
);
2262 CVAL(outbuf
,smb_rcls
) = error_class
;
2263 SSVAL(outbuf
,smb_err
,error_code
);
2265 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2268 (int)CVAL(inbuf
,smb_com
),
2269 smb_fn_name(CVAL(inbuf
,smb_com
)),
2274 DEBUG(3,("error string = %s\n",strerror(errno
)));
2280 #ifndef SIGCLD_IGNORE
2281 /****************************************************************************
2282 this prevents zombie child processes
2283 ****************************************************************************/
2284 static int sig_cld()
2286 static int depth
= 0;
2289 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2295 BlockSignals(True
,SIGCLD
);
2296 DEBUG(5,("got SIGCLD\n"));
2299 while (sys_waitpid((pid_t
)-1,(int *)NULL
, WNOHANG
) > 0);
2303 /* Stevens, Adv. Unix Prog. says that on system V you must call
2304 wait before reinstalling the signal handler, because the kernel
2305 calls the handler from within the signal-call when there is a
2306 child that has exited. This would lead to an infinite recursion
2307 if done vice versa. */
2309 #ifndef DONT_REINSTALL_SIG
2310 #ifdef SIGCLD_IGNORE
2311 signal(SIGCLD
, SIG_IGN
);
2313 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
2318 while (wait3(WAIT3_CAST1 NULL
, WNOHANG
, WAIT3_CAST2 NULL
) > 0);
2321 BlockSignals(False
,SIGCLD
);
2326 /****************************************************************************
2327 this is called when the client exits abruptly
2328 **************************************************************************/
2329 static int sig_pipe()
2331 struct cli_state
*cli
;
2332 BlockSignals(True
,SIGPIPE
);
2334 if ((cli
= server_client()) && cli
->initialised
) {
2335 DEBUG(3,("lost connection to password server\n"));
2337 #ifndef DONT_REINSTALL_SIG
2338 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2340 BlockSignals(False
,SIGPIPE
);
2344 exit_server("Got sigpipe\n");
2348 /****************************************************************************
2349 open the socket communication
2350 ****************************************************************************/
2351 static BOOL
open_sockets(BOOL is_daemon
,int port
)
2357 int num_interfaces
= iface_count();
2358 int fd_listenset
[FD_SETSIZE
];
2364 #ifdef SIGCLD_IGNORE
2365 signal(SIGCLD
, SIG_IGN
);
2367 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
2373 FD_ZERO(&listen_set
);
2375 if(lp_interfaces() && lp_bind_interfaces_only())
2377 /* We have been given an interfaces line, and been
2378 told to only bind to those interfaces. Create a
2379 socket per interface and bind to only these.
2382 if(num_interfaces
> FD_SETSIZE
)
2384 DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
2385 max can be %d\n", num_interfaces
, FD_SETSIZE
));
2389 /* Now open a listen socket for each of the interfaces. */
2390 for(i
= 0; i
< num_interfaces
; i
++)
2392 struct in_addr
*ifip
= iface_n_ip(i
);
2396 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i
));
2399 s
= fd_listenset
[i
] = open_socket_in(SOCK_STREAM
, port
, 0, ifip
->s_addr
);
2402 /* ready to listen */
2403 if (listen(s
, 5) == -1)
2405 DEBUG(0,("listen: %s\n",strerror(errno
)));
2409 FD_SET(s
,&listen_set
);
2414 /* Just bind to 0.0.0.0 - accept connections from anywhere. */
2417 /* open an incoming socket */
2418 s
= open_socket_in(SOCK_STREAM
, port
, 0,interpret_addr(lp_socket_address()));
2422 /* ready to listen */
2423 if (listen(s
, 5) == -1)
2425 DEBUG(0,("open_sockets: listen: %s\n",strerror(errno
)));
2430 fd_listenset
[0] = s
;
2431 FD_SET(s
,&listen_set
);
2434 /* now accept incoming connections - forking a new process
2435 for each incoming connection */
2436 DEBUG(2,("waiting for a connection\n"));
2442 memcpy((char *)&lfds
, (char *)&listen_set
, sizeof(listen_set
));
2444 num
= sys_select(&lfds
,NULL
);
2446 if (num
== -1 && errno
== EINTR
)
2449 /* Find the sockets that are read-ready - accept on these. */
2450 for( ; num
> 0; num
--)
2452 struct sockaddr addr
;
2453 int in_addrlen
= sizeof(addr
);
2456 for(i
= 0; i
< num_interfaces
; i
++)
2458 if(FD_ISSET(fd_listenset
[i
],&lfds
))
2460 s
= fd_listenset
[i
];
2461 /* Clear this so we don't look at it again. */
2462 FD_CLR(fd_listenset
[i
],&lfds
);
2467 Client
= accept(s
,&addr
,&in_addrlen
);
2469 if (Client
== -1 && errno
== EINTR
)
2474 DEBUG(0,("open_sockets: accept: %s\n",strerror(errno
)));
2478 #ifdef NO_FORK_DEBUG
2479 #ifndef NO_SIGNAL_TEST
2480 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2481 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2482 #endif /* NO_SIGNAL_TEST */
2484 #else /* NO_FORK_DEBUG */
2485 if (Client
!= -1 && fork()==0)
2487 /* Child code ... */
2489 #ifndef NO_SIGNAL_TEST
2490 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2491 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2492 #endif /* NO_SIGNAL_TEST */
2493 /* close the listening socket(s) */
2494 for(i
= 0; i
< num_interfaces
; i
++)
2495 close(fd_listenset
[i
]);
2497 /* close our standard file descriptors */
2501 set_socket_options(Client
,"SO_KEEPALIVE");
2502 set_socket_options(Client
,user_socket_options
);
2504 /* Reset global variables in util.c so that
2505 client substitutions will be done correctly
2508 reset_globals_after_fork();
2511 close(Client
); /* The parent doesn't need this socket */
2512 #endif /NO_FORK_DEBUG */
2515 } /* end if is_daemon */
2518 /* Started from inetd. fd 0 is the socket. */
2519 /* We will abort gracefully when the client or remote system
2521 #ifndef NO_SIGNAL_TEST
2522 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2526 /* close our standard file descriptors */
2529 set_socket_options(Client
,"SO_KEEPALIVE");
2530 set_socket_options(Client
,user_socket_options
);
2536 /****************************************************************************
2537 process an smb from the client - split out from the process() code so
2538 it can be used by the oplock break code.
2539 ****************************************************************************/
2541 static void process_smb(char *inbuf
, char *outbuf
)
2544 static int trans_num
;
2545 int msg_type
= CVAL(inbuf
,0);
2546 int32 len
= smb_len(inbuf
);
2547 int nread
= len
+ 4;
2549 if (trans_num
== 0) {
2550 /* on the first packet, check the global hosts allow/ hosts
2551 deny parameters before doing any parsing of the packet
2552 passed to us by the client. This prevents attacks on our
2553 parsing code from hosts not in the hosts allow list */
2554 if (!check_access(-1)) {
2555 /* send a negative session response "not listining on calling
2557 static unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
2558 DEBUG(1,("%s Connection denied from %s\n",
2559 timestring(),client_addr()));
2560 send_smb(Client
,(char *)buf
);
2561 exit_server("connection denied");
2565 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type
,len
));
2566 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num
,nread
));
2569 if(trans_num
== 1 && VT_Check(inbuf
))
2579 nread
= construct_reply(inbuf
,outbuf
,nread
,max_send
);
2583 if (CVAL(outbuf
,0) == 0)
2586 if (nread
!= smb_len(outbuf
) + 4)
2588 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2589 nread
, smb_len(outbuf
)));
2592 send_smb(Client
,outbuf
);
2597 /****************************************************************************
2598 open the oplock IPC socket communication
2599 ****************************************************************************/
2600 static BOOL
open_oplock_ipc()
2602 struct sockaddr_in sock_name
;
2603 int len
= sizeof(sock_name
);
2605 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2607 /* Open a lookback UDP socket on a random port. */
2608 oplock_sock
= open_socket_in(SOCK_DGRAM
, 0, 0, htonl(INADDR_LOOPBACK
));
2609 if (oplock_sock
== -1)
2611 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2612 address %x. Error was %s\n", htonl(INADDR_LOOPBACK
), strerror(errno
)));
2617 /* Find out the transient UDP port we have been allocated. */
2618 if(getsockname(oplock_sock
, (struct sockaddr
*)&sock_name
, &len
)<0)
2620 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2627 oplock_port
= ntohs(sock_name
.sin_port
);
2629 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2630 getpid(), oplock_port
));
2635 /****************************************************************************
2636 process an oplock break message.
2637 ****************************************************************************/
2638 static BOOL
process_local_message(int sock
, char *buffer
, int buf_size
)
2644 msg_len
= IVAL(buffer
,UDP_CMD_LEN_OFFSET
);
2645 from_port
= SVAL(buffer
,UDP_CMD_PORT_OFFSET
);
2647 msg_start
= &buffer
[UDP_CMD_HEADER_LEN
];
2649 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2650 msg_len
, from_port
));
2652 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2653 only valid request. */
2655 switch(SVAL(msg_start
,UDP_MESSAGE_CMD_OFFSET
))
2657 case OPLOCK_BREAK_CMD
:
2658 /* Ensure that the msg length is correct. */
2659 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
2661 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2662 should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
2666 uint32 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
2667 uint32 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
2668 uint32 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
2669 struct timeval tval
;
2670 struct sockaddr_in toaddr
;
2672 tval
.tv_sec
= IVAL(msg_start
, OPLOCK_BREAK_SEC_OFFSET
);
2673 tval
.tv_usec
= IVAL(msg_start
, OPLOCK_BREAK_USEC_OFFSET
);
2675 DEBUG(5,("process_local_message: oplock break request from \
2676 pid %d, port %d, dev = %x, inode = %x\n", remotepid
, from_port
, dev
, inode
));
2679 * If we have no record of any currently open oplocks,
2680 * it's not an error, as a close command may have
2681 * just been issued on the file that was oplocked.
2682 * Just return success in this case.
2685 if(global_oplocks_open
!= 0)
2687 if(oplock_break(dev
, inode
, &tval
) == False
)
2689 DEBUG(0,("process_local_message: oplock break failed - \
2690 not returning udp message.\n"));
2696 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2697 oplocks. Returning success.\n"));
2700 /* Send the message back after OR'ing in the 'REPLY' bit. */
2701 SSVAL(msg_start
,UDP_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
| CMD_REPLY
);
2703 bzero((char *)&toaddr
,sizeof(toaddr
));
2704 toaddr
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2705 toaddr
.sin_port
= htons(from_port
);
2706 toaddr
.sin_family
= AF_INET
;
2708 if(sendto( sock
, msg_start
, OPLOCK_BREAK_MSG_LEN
, 0,
2709 (struct sockaddr
*)&toaddr
, sizeof(toaddr
)) < 0)
2711 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2712 remotepid
, strerror(errno
)));
2716 DEBUG(5,("process_local_message: oplock break reply sent to \
2717 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid
,
2718 from_port
, dev
, inode
));
2723 * Keep this as a debug case - eventually we can remove it.
2726 DEBUG(0,("process_local_message: Received unsolicited break \
2727 reply - dumping info.\n"));
2729 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
2731 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2732 (was %d, should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
2737 uint32 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
2738 uint32 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
2739 uint32 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
2741 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2742 pid %d, port %d, dev = %x, inode = %x\n", remotepid
, from_port
, dev
, inode
));
2748 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2749 (unsigned int)SVAL(msg_start
,0)));
2755 /****************************************************************************
2756 Process an oplock break directly.
2757 ****************************************************************************/
2758 BOOL
oplock_break(uint32 dev
, uint32 inode
, struct timeval
*tval
)
2761 static char *inbuf
= NULL
;
2762 static char *outbuf
= NULL
;
2763 files_struct
*fsp
= NULL
;
2766 BOOL shutdown_server
= False
;
2768 DEBUG(3,("%s oplock_break: called for dev = %x, inode = %x. Current \
2769 global_oplocks_open = %d\n", timestring(), dev
, inode
, global_oplocks_open
));
2773 inbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
2775 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2778 outbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
2779 if(outbuf
== NULL
) {
2780 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2787 /* We need to search the file open table for the
2788 entry containing this dev and inode, and ensure
2789 we have an oplock on it. */
2790 for( fnum
= 0; fnum
< MAX_OPEN_FILES
; fnum
++)
2795 if((fsp
->fd_ptr
->dev
== dev
) && (fsp
->fd_ptr
->inode
== inode
) &&
2796 (fsp
->open_time
.tv_sec
== tval
->tv_sec
) &&
2797 (fsp
->open_time
.tv_usec
== tval
->tv_usec
))
2804 /* The file could have been closed in the meantime - return success. */
2805 DEBUG(3,("%s oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2806 allowing break to succeed.\n", timestring(), dev
, inode
, fnum
));
2810 /* Ensure we have an oplock on the file */
2812 /* There is a potential race condition in that an oplock could
2813 have been broken due to another udp request, and yet there are
2814 still oplock break messages being sent in the udp message
2815 queue for this file. So return true if we don't have an oplock,
2816 as we may have just freed it.
2819 if(!fsp
->granted_oplock
)
2821 DEBUG(3,("%s oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2822 Allowing break to succeed regardless.\n", timestring(), fsp
->name
, fnum
, dev
, inode
));
2826 /* Now comes the horrid part. We must send an oplock break to the client,
2827 and then process incoming messages until we get a close or oplock release.
2830 /* Prepare the SMBlockingX message. */
2831 bzero(outbuf
,smb_size
);
2832 set_message(outbuf
,8,0,True
);
2834 SCVAL(outbuf
,smb_com
,SMBlockingX
);
2835 SSVAL(outbuf
,smb_tid
,fsp
->cnum
);
2836 SSVAL(outbuf
,smb_pid
,0xFFFF);
2837 SSVAL(outbuf
,smb_uid
,0);
2838 SSVAL(outbuf
,smb_mid
,0xFFFF);
2839 SCVAL(outbuf
,smb_vwv0
,0xFF);
2840 SSVAL(outbuf
,smb_vwv2
,fnum
);
2841 SCVAL(outbuf
,smb_vwv3
,LOCKING_ANDX_OPLOCK_RELEASE
);
2842 /* Change this when we have level II oplocks. */
2843 SCVAL(outbuf
,smb_vwv3
+1,OPLOCKLEVEL_NONE
);
2845 send_smb(Client
, outbuf
);
2847 global_oplock_break
= True
;
2849 /* Process incoming messages. */
2851 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2852 seconds we should just die.... */
2854 start_time
= time(NULL
);
2856 while(OPEN_FNUM(fnum
) && fsp
->granted_oplock
)
2858 if(receive_smb(Client
,inbuf
,OPLOCK_BREAK_TIMEOUT
* 1000) == False
)
2861 * Die if we got an error.
2864 if (smb_read_error
== READ_EOF
)
2865 DEBUG(0,("%s oplock_break: end of file from client\n", timestring()));
2867 if (smb_read_error
== READ_ERROR
)
2868 DEBUG(0,("%s oplock_break: receive_smb error (%s)\n",
2869 timestring(), strerror(errno
)));
2871 if (smb_read_error
== READ_TIMEOUT
)
2872 DEBUG(0,("%s oplock_break: receive_smb timed out after %d seconds.\n",
2873 timestring(), OPLOCK_BREAK_TIMEOUT
));
2875 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2876 inode = %x).\n", timestring(), fsp
->name
, fnum
, dev
, inode
));
2877 shutdown_server
= True
;
2880 process_smb(inbuf
, outbuf
);
2882 /* We only need this in case a readraw crossed on the wire. */
2883 if(global_oplock_break
)
2884 global_oplock_break
= False
;
2887 * Die if we go over the time limit.
2890 if((time(NULL
) - start_time
) > OPLOCK_BREAK_TIMEOUT
)
2892 DEBUG(0,("%s oplock_break: no break received from client within \
2893 %d seconds.\n", timestring(), OPLOCK_BREAK_TIMEOUT
));
2894 DEBUG(0,("%s oplock_break failed for file %s (fnum = %d, dev = %x, \
2895 inode = %x).\n", timestring(), fsp
->name
, fnum
, dev
, inode
));
2896 shutdown_server
= True
;
2902 * If the client did not respond we must die.
2907 DEBUG(0,("%s oplock_break: client failure in break - shutting down this smbd.\n",
2911 exit_server("oplock break failure");
2916 /* The lockingX reply will have removed the oplock flag
2917 from the sharemode. */
2919 fsp
->granted_oplock
= False
;
2922 global_oplocks_open
--;
2924 /* Santity check - remove this later. JRA */
2925 if(global_oplocks_open
< 0)
2927 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2928 global_oplocks_open
));
2929 exit_server("oplock_break: global_oplocks_open < 0");
2932 DEBUG(3,("%s oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2933 global_oplocks_open = %d\n", timestring(), fnum
, dev
, inode
, global_oplocks_open
));
2938 /****************************************************************************
2939 Send an oplock break message to another smbd process. If the oplock is held
2940 by the local smbd then call the oplock break function directly.
2941 ****************************************************************************/
2943 BOOL
request_oplock_break(share_mode_entry
*share_entry
,
2944 uint32 dev
, uint32 inode
)
2946 char op_break_msg
[OPLOCK_BREAK_MSG_LEN
];
2947 struct sockaddr_in addr_out
;
2950 if(pid
== share_entry
->pid
)
2952 /* We are breaking our own oplock, make sure it's us. */
2953 if(share_entry
->op_port
!= oplock_port
)
2955 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2956 should be %d\n", pid
, share_entry
->op_port
, oplock_port
));
2960 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2962 /* Call oplock break direct. */
2963 return oplock_break(dev
, inode
, &share_entry
->time
);
2966 /* We need to send a OPLOCK_BREAK_CMD message to the
2967 port in the share mode entry. */
2969 SSVAL(op_break_msg
,UDP_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
);
2970 SIVAL(op_break_msg
,OPLOCK_BREAK_PID_OFFSET
,pid
);
2971 SIVAL(op_break_msg
,OPLOCK_BREAK_DEV_OFFSET
,dev
);
2972 SIVAL(op_break_msg
,OPLOCK_BREAK_INODE_OFFSET
,inode
);
2973 SIVAL(op_break_msg
,OPLOCK_BREAK_SEC_OFFSET
,(uint32
)share_entry
->time
.tv_sec
);
2974 SIVAL(op_break_msg
,OPLOCK_BREAK_USEC_OFFSET
,(uint32
)share_entry
->time
.tv_usec
);
2976 /* set the address and port */
2977 bzero((char *)&addr_out
,sizeof(addr_out
));
2978 addr_out
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2979 addr_out
.sin_port
= htons( share_entry
->op_port
);
2980 addr_out
.sin_family
= AF_INET
;
2982 DEBUG(3,("%s request_oplock_break: sending a oplock break message to pid %d on port %d \
2983 for dev = %x, inode = %x\n", timestring(), share_entry
->pid
, share_entry
->op_port
, dev
, inode
));
2985 if(sendto(oplock_sock
,op_break_msg
,OPLOCK_BREAK_MSG_LEN
,0,
2986 (struct sockaddr
*)&addr_out
,sizeof(addr_out
)) < 0)
2988 DEBUG(0,("%s request_oplock_break: failed when sending a oplock break message \
2989 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2990 timestring(), share_entry
->pid
, share_entry
->op_port
, dev
, inode
,
2996 * Now we must await the oplock broken message coming back
2997 * from the target smbd process. Timeout if it fails to
2998 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
2999 * While we get messages that aren't ours, loop.
3004 char op_break_reply
[UDP_CMD_HEADER_LEN
+OPLOCK_BREAK_MSG_LEN
];
3005 int32 reply_msg_len
;
3006 uint16 reply_from_port
;
3007 char *reply_msg_start
;
3009 if(receive_local_message(oplock_sock
, op_break_reply
, sizeof(op_break_reply
),
3010 (OPLOCK_BREAK_TIMEOUT
+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR
) * 1000) == False
)
3012 if(smb_read_error
== READ_TIMEOUT
)
3014 DEBUG(0,("%s request_oplock_break: no response received to oplock break request to \
3015 pid %d on port %d for dev = %x, inode = %x\n", timestring(), share_entry
->pid
,
3016 share_entry
->op_port
, dev
, inode
));
3018 * This is a hack to make handling of failing clients more robust.
3019 * If a oplock break response message is not received in the timeout
3020 * period we may assume that the smbd servicing that client holding
3021 * the oplock has died and the client changes were lost anyway, so
3022 * we should continue to try and open the file.
3027 DEBUG(0,("%s request_oplock_break: error in response received to oplock break request to \
3028 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", timestring
, share_entry
->pid
,
3029 share_entry
->op_port
, dev
, inode
, strerror(errno
)));
3034 * If the response we got was not an answer to our message, but
3035 * was a completely different request, push it onto the pending
3036 * udp message stack so that we can deal with it in the main loop.
3037 * It may be another oplock break request to us.
3041 * Local note from JRA. There exists the possibility of a denial
3042 * of service attack here by allowing non-root processes running
3043 * on a local machine sending many of these pending messages to
3044 * a smbd port. Currently I'm not sure how to restrict the messages
3045 * I will queue (although I could add a limit to the queue) to
3046 * those received by root processes only. There should be a
3047 * way to make this bulletproof....
3050 reply_msg_len
= IVAL(op_break_reply
,UDP_CMD_LEN_OFFSET
);
3051 reply_from_port
= SVAL(op_break_reply
,UDP_CMD_PORT_OFFSET
);
3053 reply_msg_start
= &op_break_reply
[UDP_CMD_HEADER_LEN
];
3055 if(reply_msg_len
!= OPLOCK_BREAK_MSG_LEN
)
3058 DEBUG(0,("%s request_oplock_break: invalid message length received. Ignoring\n",
3063 if(((SVAL(reply_msg_start
,UDP_MESSAGE_CMD_OFFSET
) & CMD_REPLY
) == 0) ||
3064 (reply_from_port
!= share_entry
->op_port
) ||
3065 (memcmp(&reply_msg_start
[OPLOCK_BREAK_PID_OFFSET
],
3066 &op_break_msg
[OPLOCK_BREAK_PID_OFFSET
],
3067 OPLOCK_BREAK_MSG_LEN
- OPLOCK_BREAK_PID_OFFSET
) != 0))
3069 DEBUG(3,("%s request_oplock_break: received other message whilst awaiting \
3070 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
3071 timestring(), share_entry
->pid
, share_entry
->op_port
, dev
, inode
));
3072 if(push_local_message(op_break_reply
, sizeof(op_break_reply
)) == False
)
3080 DEBUG(3,("%s request_oplock_break: broke oplock.\n", timestring()));
3085 /****************************************************************************
3086 check if a snum is in use
3087 ****************************************************************************/
3088 BOOL
snum_used(int snum
)
3091 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
3092 if (OPEN_CNUM(i
) && (SNUM(i
) == snum
))
3097 /****************************************************************************
3098 reload the services file
3099 **************************************************************************/
3100 BOOL
reload_services(BOOL test
)
3107 pstrcpy(fname
,lp_configfile());
3108 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
3110 pstrcpy(servicesf
,fname
);
3117 if (test
&& !lp_file_list_changed())
3120 lp_killunused(snum_used
);
3122 ret
= lp_load(servicesf
,False
);
3124 /* perhaps the config filename is now set */
3126 reload_services(True
);
3135 set_socket_options(Client
,"SO_KEEPALIVE");
3136 set_socket_options(Client
,user_socket_options
);
3140 reset_mangled_stack( lp_mangledstack() );
3142 /* this forces service parameters to be flushed */
3143 become_service(-1,True
);
3150 /****************************************************************************
3151 this prevents zombie child processes
3152 ****************************************************************************/
3153 static int sig_hup()
3155 BlockSignals(True
,SIGHUP
);
3156 DEBUG(0,("Got SIGHUP\n"));
3157 reload_services(False
);
3158 #ifndef DONT_REINSTALL_SIG
3159 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
3161 BlockSignals(False
,SIGHUP
);
3165 /****************************************************************************
3166 Setup the groups a user belongs to.
3167 ****************************************************************************/
3168 int setup_groups(char *user
, int uid
, int gid
, int *p_ngroups
,
3169 int **p_igroups
, gid_t
**p_groups
,
3172 if (-1 == initgroups(user
,gid
))
3176 DEBUG(0,("Unable to initgroups!\n"));
3177 if (gid
< 0 || gid
> 16000 || uid
< 0 || uid
> 16000)
3178 DEBUG(0,("This is probably a problem with the account %s\n",user
));
3187 ngroups
= getgroups(0,&grp
);
3190 igroups
= (int *)malloc(sizeof(int)*ngroups
);
3191 attrs
= (int *)malloc(sizeof(int)*ngroups
);
3192 for (i
=0;i
<ngroups
;i
++)
3194 attrs
[i
] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3195 igroups
[i
] = 0x42424242;
3197 ngroups
= getgroups(ngroups
,(gid_t
*)igroups
);
3199 if (igroups
[0] == 0x42424242)
3202 *p_ngroups
= ngroups
;
3205 /* The following bit of code is very strange. It is due to the
3206 fact that some OSes use int* and some use gid_t* for
3207 getgroups, and some (like SunOS) use both, one in prototypes,
3208 and one in man pages and the actual code. Thus we detect it
3209 dynamically using some very ugly code */
3212 /* does getgroups return ints or gid_t ?? */
3213 static BOOL groups_use_ints
= True
;
3215 if (groups_use_ints
&&
3217 SVAL(igroups
,2) == 0x4242)
3218 groups_use_ints
= False
;
3220 for (i
=0;groups_use_ints
&& i
<ngroups
;i
++)
3221 if (igroups
[i
] == 0x42424242)
3222 groups_use_ints
= False
;
3224 if (groups_use_ints
)
3226 *p_igroups
= igroups
;
3227 *p_groups
= (gid_t
*)igroups
;
3231 gid_t
*groups
= (gid_t
*)igroups
;
3232 igroups
= (int *)malloc(sizeof(int)*ngroups
);
3233 for (i
=0;i
<ngroups
;i
++)
3235 igroups
[i
] = groups
[i
];
3237 *p_igroups
= igroups
;
3238 *p_groups
= (gid_t
*)groups
;
3241 DEBUG(3,("%s is in %d groups\n",user
,ngroups
));
3242 for (i
=0;i
<ngroups
;i
++)
3243 DEBUG(3,("%d ",igroups
[i
]));
3249 /****************************************************************************
3250 make a connection to a service
3251 ****************************************************************************/
3252 int make_connection(char *service
,char *user
,char *password
, int pwlen
, char *dev
,uint16 vuid
)
3256 struct passwd
*pass
= NULL
;
3257 connection_struct
*pcon
;
3260 static BOOL first_connection
= True
;
3264 snum
= find_service(service
);
3267 if (strequal(service
,"IPC$"))
3269 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3273 DEBUG(0,("%s couldn't find service %s\n",timestring(),service
));
3277 if (strequal(service
,HOMES_NAME
))
3279 if (*user
&& Get_Pwnam(user
,True
))
3280 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
3282 if (validated_username(vuid
))
3284 strcpy(user
,validated_username(vuid
));
3285 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
3289 if (!lp_snum_ok(snum
) || !check_access(snum
)) {
3293 /* you can only connect to the IPC$ service as an ipc device */
3294 if (strequal(service
,"IPC$"))
3297 if (*dev
== '?' || !*dev
)
3299 if (lp_print_ok(snum
))
3300 strcpy(dev
,"LPT1:");
3305 /* if the request is as a printer and you can't print then refuse */
3307 if (!lp_print_ok(snum
) && (strncmp(dev
,"LPT",3) == 0)) {
3308 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3312 /* lowercase the user name */
3315 /* add it as a possible user name */
3316 add_session_user(service
);
3318 /* shall we let them in? */
3319 if (!authorise_login(snum
,user
,password
,pwlen
,&guest
,&force
,vuid
))
3321 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service
));
3325 cnum
= find_free_connection(str_checksum(service
) + str_checksum(user
));
3328 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3332 pcon
= &Connections
[cnum
];
3333 bzero((char *)pcon
,sizeof(*pcon
));
3335 /* find out some info about the user */
3336 pass
= Get_Pwnam(user
,True
);
3340 DEBUG(0,("%s couldn't find account %s\n",timestring(),user
));
3344 pcon
->read_only
= lp_readonly(snum
);
3348 StrnCpy(list
,lp_readlist(snum
),sizeof(pstring
)-1);
3349 string_sub(list
,"%S",service
);
3351 if (user_in_list(user
,list
))
3352 pcon
->read_only
= True
;
3354 StrnCpy(list
,lp_writelist(snum
),sizeof(pstring
)-1);
3355 string_sub(list
,"%S",service
);
3357 if (user_in_list(user
,list
))
3358 pcon
->read_only
= False
;
3361 /* admin user check */
3363 /* JRA - original code denied admin user if the share was
3364 marked read_only. Changed as I don't think this is needed,
3365 but old code left in case there is a problem here.
3367 if (user_in_list(user
,lp_admin_users(snum
))
3369 && !pcon
->read_only
)
3374 pcon
->admin_user
= True
;
3375 DEBUG(0,("%s logged in as admin user (root privileges)\n",user
));
3378 pcon
->admin_user
= False
;
3380 pcon
->force_user
= force
;
3382 pcon
->uid
= pass
->pw_uid
;
3383 pcon
->gid
= pass
->pw_gid
;
3384 pcon
->num_files_open
= 0;
3385 pcon
->lastused
= time(NULL
);
3386 pcon
->service
= snum
;
3388 pcon
->printer
= (strncmp(dev
,"LPT",3) == 0);
3389 pcon
->ipc
= (strncmp(dev
,"IPC",3) == 0);
3390 pcon
->dirptr
= NULL
;
3391 pcon
->veto_list
= NULL
;
3392 pcon
->hide_list
= NULL
;
3393 string_set(&pcon
->dirpath
,"");
3394 string_set(&pcon
->user
,user
);
3397 if (*lp_force_group(snum
))
3402 StrnCpy(gname
,lp_force_group(snum
),sizeof(pstring
)-1);
3403 /* default service may be a group name */
3404 string_sub(gname
,"%S",service
);
3405 gptr
= (struct group
*)getgrnam(gname
);
3409 pcon
->gid
= gptr
->gr_gid
;
3410 DEBUG(3,("Forced group %s\n",gname
));
3413 DEBUG(1,("Couldn't find group %s\n",gname
));
3417 if (*lp_force_user(snum
))
3419 struct passwd
*pass2
;
3421 fstrcpy(fuser
,lp_force_user(snum
));
3422 pass2
= (struct passwd
*)Get_Pwnam(fuser
,True
);
3425 pcon
->uid
= pass2
->pw_uid
;
3426 string_set(&pcon
->user
,fuser
);
3427 fstrcpy(user
,fuser
);
3428 pcon
->force_user
= True
;
3429 DEBUG(3,("Forced user %s\n",fuser
));
3432 DEBUG(1,("Couldn't find user %s\n",fuser
));
3437 pstrcpy(s
,lp_pathname(snum
));
3438 standard_sub(cnum
,s
);
3439 string_set(&pcon
->connectpath
,s
);
3440 DEBUG(3,("Connect path is %s\n",s
));
3443 /* groups stuff added by ih */
3445 pcon
->igroups
= NULL
;
3446 pcon
->groups
= NULL
;
3451 /* Find all the groups this uid is in and store them. Used by become_user() */
3452 setup_groups(pcon
->user
,pcon
->uid
,pcon
->gid
,
3453 &pcon
->ngroups
,&pcon
->igroups
,&pcon
->groups
,&pcon
->attrs
);
3455 /* check number of connections */
3456 if (!claim_connection(cnum
,
3457 lp_servicename(SNUM(cnum
)),
3458 lp_max_connections(SNUM(cnum
)),False
))
3460 DEBUG(1,("too many connections - rejected\n"));
3464 if (lp_status(SNUM(cnum
)))
3465 claim_connection(cnum
,"STATUS.",MAXSTATUS
,first_connection
);
3467 first_connection
= False
;
3472 /* execute any "root preexec = " line */
3473 if (*lp_rootpreexec(SNUM(cnum
)))
3476 pstrcpy(cmd
,lp_rootpreexec(SNUM(cnum
)));
3477 standard_sub(cnum
,cmd
);
3478 DEBUG(5,("cmd=%s\n",cmd
));
3479 smbrun(cmd
,NULL
,False
);
3482 if (!become_user(&Connections
[cnum
], cnum
,pcon
->vuid
))
3484 DEBUG(0,("Can't become connected user!\n"));
3486 if (!IS_IPC(cnum
)) {
3487 yield_connection(cnum
,
3488 lp_servicename(SNUM(cnum
)),
3489 lp_max_connections(SNUM(cnum
)));
3490 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3495 if (ChDir(pcon
->connectpath
) != 0)
3497 DEBUG(0,("Can't change directory to %s (%s)\n",
3498 pcon
->connectpath
,strerror(errno
)));
3501 if (!IS_IPC(cnum
)) {
3502 yield_connection(cnum
,
3503 lp_servicename(SNUM(cnum
)),
3504 lp_max_connections(SNUM(cnum
)));
3505 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3510 string_set(&pcon
->origpath
,pcon
->connectpath
);
3512 #if SOFTLINK_OPTIMISATION
3513 /* resolve any soft links early */
3516 pstrcpy(s
,pcon
->connectpath
);
3518 string_set(&pcon
->connectpath
,s
);
3519 ChDir(pcon
->connectpath
);
3523 num_connections_open
++;
3524 add_session_user(user
);
3526 /* execute any "preexec = " line */
3527 if (*lp_preexec(SNUM(cnum
)))
3530 pstrcpy(cmd
,lp_preexec(SNUM(cnum
)));
3531 standard_sub(cnum
,cmd
);
3532 smbrun(cmd
,NULL
,False
);
3535 /* we've finished with the sensitive stuff */
3538 /* Add veto/hide lists */
3539 if (!IS_IPC(cnum
) && !IS_PRINT(cnum
))
3541 set_namearray( &pcon
->veto_list
, lp_veto_files(SNUM(cnum
)));
3542 set_namearray( &pcon
->hide_list
, lp_hide_files(SNUM(cnum
)));
3546 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3550 lp_servicename(SNUM(cnum
)),user
,
3560 /****************************************************************************
3561 find first available file slot
3562 ****************************************************************************/
3563 int find_free_file(void )
3566 /* we start at 1 here for an obscure reason I can't now remember,
3567 but I think is important :-) */
3568 for (i
=1;i
<MAX_OPEN_FILES
;i
++)
3571 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3575 /****************************************************************************
3576 find first available connection slot, starting from a random position.
3577 The randomisation stops problems with the server dieing and clients
3578 thinking the server is still available.
3579 ****************************************************************************/
3580 static int find_free_connection(int hash
)
3584 hash
= (hash
% (MAX_CONNECTIONS
-2))+1;
3588 for (i
=hash
+1;i
!=hash
;)
3590 if (!Connections
[i
].open
&& Connections
[i
].used
== used
)
3592 DEBUG(3,("found free connection number %d\n",i
));
3596 if (i
== MAX_CONNECTIONS
)
3606 DEBUG(1,("ERROR! Out of connection structures\n"));
3611 /****************************************************************************
3612 reply for the core protocol
3613 ****************************************************************************/
3614 int reply_corep(char *outbuf
)
3616 int outsize
= set_message(outbuf
,1,0,True
);
3618 Protocol
= PROTOCOL_CORE
;
3624 /****************************************************************************
3625 reply for the coreplus protocol
3626 ****************************************************************************/
3627 int reply_coreplus(char *outbuf
)
3629 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3630 int outsize
= set_message(outbuf
,13,0,True
);
3631 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
3632 readbraw and writebraw (possibly) */
3633 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3634 SSVAL(outbuf
,smb_vwv1
,0x1); /* user level security, don't encrypt */
3636 Protocol
= PROTOCOL_COREPLUS
;
3642 /****************************************************************************
3643 reply for the lanman 1.0 protocol
3644 ****************************************************************************/
3645 int reply_lanman1(char *outbuf
)
3647 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3649 BOOL doencrypt
= SMBENCRYPT();
3650 time_t t
= time(NULL
);
3652 if (lp_security()>=SEC_USER
) secword
|= 1;
3653 if (doencrypt
) secword
|= 2;
3655 set_message(outbuf
,13,doencrypt
?8:0,True
);
3656 SSVAL(outbuf
,smb_vwv1
,secword
);
3657 /* Create a token value and add it to the outgoing packet. */
3659 generate_next_challenge(smb_buf(outbuf
));
3661 Protocol
= PROTOCOL_LANMAN1
;
3663 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3664 SSVAL(outbuf
,smb_vwv2
,max_recv
);
3665 SSVAL(outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
3666 SSVAL(outbuf
,smb_vwv4
,1);
3667 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
3668 readbraw writebraw (possibly) */
3669 SIVAL(outbuf
,smb_vwv6
,getpid());
3670 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
3672 put_dos_date(outbuf
,smb_vwv8
,t
);
3674 return (smb_len(outbuf
)+4);
3678 /****************************************************************************
3679 reply for the lanman 2.0 protocol
3680 ****************************************************************************/
3681 int reply_lanman2(char *outbuf
)
3683 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3685 BOOL doencrypt
= SMBENCRYPT();
3686 time_t t
= time(NULL
);
3687 struct cli_state
*cli
= NULL
;
3691 if (lp_security() == SEC_SERVER
) {
3692 cli
= server_cryptkey();
3696 DEBUG(3,("using password server validation\n"));
3697 doencrypt
= ((cli
->sec_mode
& 2) != 0);
3700 if (lp_security()>=SEC_USER
) secword
|= 1;
3701 if (doencrypt
) secword
|= 2;
3706 generate_next_challenge(cryptkey
);
3708 memcpy(cryptkey
, cli
->cryptkey
, 8);
3709 set_challenge(cli
->cryptkey
);
3713 set_message(outbuf
,13,crypt_len
,True
);
3714 SSVAL(outbuf
,smb_vwv1
,secword
);
3715 SIVAL(outbuf
,smb_vwv6
,getpid());
3717 memcpy(smb_buf(outbuf
), cryptkey
, 8);
3719 Protocol
= PROTOCOL_LANMAN2
;
3721 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3722 SSVAL(outbuf
,smb_vwv2
,max_recv
);
3723 SSVAL(outbuf
,smb_vwv3
,lp_maxmux());
3724 SSVAL(outbuf
,smb_vwv4
,1);
3725 SSVAL(outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
3726 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
3727 put_dos_date(outbuf
,smb_vwv8
,t
);
3729 return (smb_len(outbuf
)+4);
3733 /****************************************************************************
3734 reply for the nt protocol
3735 ****************************************************************************/
3736 int reply_nt1(char *outbuf
)
3738 /* dual names + lock_and_read + nt SMBs + remote API calls */
3739 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
;
3741 other valid capabilities which we may support at some time...
3742 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3743 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3747 BOOL doencrypt
= SMBENCRYPT();
3748 time_t t
= time(NULL
);
3750 struct cli_state
*cli
= NULL
;
3754 if (lp_security() == SEC_SERVER
) {
3755 cli
= server_cryptkey();
3759 DEBUG(3,("using password server validation\n"));
3760 doencrypt
= ((cli
->sec_mode
& 2) != 0);
3766 generate_next_challenge(cryptkey
);
3768 memcpy(cryptkey
, cli
->cryptkey
, 8);
3769 set_challenge(cli
->cryptkey
);
3773 if (lp_readraw() && lp_writeraw()) {
3774 capabilities
|= CAP_RAW_MODE
;
3777 if (lp_security() >= SEC_USER
) secword
|= 1;
3778 if (doencrypt
) secword
|= 2;
3780 /* decide where (if) to put the encryption challenge, and
3781 follow it with the OEM'd domain name
3783 data_len
= crypt_len
+ strlen(myworkgroup
) + 1;
3785 set_message(outbuf
,17,data_len
,True
);
3786 strcpy(smb_buf(outbuf
)+crypt_len
, myworkgroup
);
3788 CVAL(outbuf
,smb_vwv1
) = secword
;
3789 SSVALS(outbuf
,smb_vwv16
+1,crypt_len
);
3791 memcpy(smb_buf(outbuf
), cryptkey
, 8);
3793 Protocol
= PROTOCOL_NT1
;
3795 SSVAL(outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
3796 SSVAL(outbuf
,smb_vwv2
+1,1); /* num vcs */
3797 SIVAL(outbuf
,smb_vwv3
+1,0xffff); /* max buffer. LOTS! */
3798 SIVAL(outbuf
,smb_vwv5
+1,0xffff); /* raw size. LOTS! */
3799 SIVAL(outbuf
,smb_vwv7
+1,getpid()); /* session key */
3800 SIVAL(outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
3801 put_long_date(outbuf
+smb_vwv11
+1,t
);
3802 SSVALS(outbuf
,smb_vwv15
+1,TimeDiff(t
)/60);
3803 SSVAL(outbuf
,smb_vwv17
,data_len
); /* length of challenge+domain strings */
3805 return (smb_len(outbuf
)+4);
3808 /* these are the protocol lists used for auto architecture detection:
3811 protocol [PC NETWORK PROGRAM 1.0]
3812 protocol [XENIX CORE]
3813 protocol [MICROSOFT NETWORKS 1.03]
3814 protocol [LANMAN1.0]
3815 protocol [Windows for Workgroups 3.1a]
3816 protocol [LM1.2X002]
3817 protocol [LANMAN2.1]
3818 protocol [NT LM 0.12]
3821 protocol [PC NETWORK PROGRAM 1.0]
3822 protocol [XENIX CORE]
3823 protocol [MICROSOFT NETWORKS 1.03]
3824 protocol [LANMAN1.0]
3825 protocol [Windows for Workgroups 3.1a]
3826 protocol [LM1.2X002]
3827 protocol [LANMAN2.1]
3828 protocol [NT LM 0.12]
3831 protocol [PC NETWORK PROGRAM 1.0]
3832 protocol [XENIX CORE]
3833 protocol [LANMAN1.0]
3834 protocol [LM1.2X002]
3835 protocol [LANMAN2.1]
3839 * Modified to recognize the architecture of the remote machine better.
3841 * This appears to be the matrix of which protocol is used by which
3843 Protocol WfWg Win95 WinNT OS/2
3844 PC NETWORK PROGRAM 1.0 1 1 1 1
3846 MICROSOFT NETWORKS 3.0 2 2
3848 MICROSOFT NETWORKS 1.03 3
3851 Windows for Workgroups 3.1a 5 5 5
3856 * tim@fsg.com 09/29/95
3859 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3860 #define ARCH_WIN95 0x2
3861 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3862 #define ARCH_WINNT 0x8
3863 #define ARCH_SAMBA 0x10
3865 #define ARCH_ALL 0x1F
3867 /* List of supported protocols, most desired first */
3871 int (*proto_reply_fn
)(char *);
3873 } supported_protocols
[] = {
3874 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
3875 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
3876 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3877 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3878 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3879 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
3880 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
3881 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
3882 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
3887 /****************************************************************************
3889 ****************************************************************************/
3890 static int reply_negprot(char *inbuf
,char *outbuf
)
3892 int outsize
= set_message(outbuf
,1,0,True
);
3897 int bcc
= SVAL(smb_buf(inbuf
),-2);
3898 int arch
= ARCH_ALL
;
3900 p
= smb_buf(inbuf
)+1;
3901 while (p
< (smb_buf(inbuf
) + bcc
))
3904 DEBUG(3,("Requested protocol [%s]\n",p
));
3905 if (strcsequal(p
,"Windows for Workgroups 3.1a"))
3906 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
);
3907 else if (strcsequal(p
,"DOS LM1.2X002"))
3908 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
3909 else if (strcsequal(p
,"DOS LANMAN2.1"))
3910 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
3911 else if (strcsequal(p
,"NT LM 0.12"))
3912 arch
&= ( ARCH_WIN95
| ARCH_WINNT
);
3913 else if (strcsequal(p
,"LANMAN2.1"))
3914 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3915 else if (strcsequal(p
,"LM1.2X002"))
3916 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3917 else if (strcsequal(p
,"MICROSOFT NETWORKS 1.03"))
3919 else if (strcsequal(p
,"XENIX CORE"))
3920 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3921 else if (strcsequal(p
,"Samba")) {
3931 set_remote_arch(RA_SAMBA
);
3934 set_remote_arch(RA_WFWG
);
3937 set_remote_arch(RA_WIN95
);
3940 set_remote_arch(RA_WINNT
);
3943 set_remote_arch(RA_OS2
);
3946 set_remote_arch(RA_UNKNOWN
);
3950 /* possibly reload - change of architecture */
3951 reload_services(True
);
3953 /* a special case to stop password server loops */
3954 if (Index
== 1 && strequal(remote_machine
,myhostname
) &&
3955 lp_security()==SEC_SERVER
)
3956 exit_server("Password server loop!");
3958 /* Check for protocols, most desirable first */
3959 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++)
3961 p
= smb_buf(inbuf
)+1;
3963 if (lp_maxprotocol() >= supported_protocols
[protocol
].protocol_level
)
3964 while (p
< (smb_buf(inbuf
) + bcc
))
3966 if (strequal(p
,supported_protocols
[protocol
].proto_name
))
3975 SSVAL(outbuf
,smb_vwv0
,choice
);
3977 extern fstring remote_proto
;
3978 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
3979 reload_services(True
);
3980 outsize
= supported_protocols
[protocol
].proto_reply_fn(outbuf
);
3981 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
3984 DEBUG(0,("No protocol supported !\n"));
3986 SSVAL(outbuf
,smb_vwv0
,choice
);
3988 DEBUG(5,("%s negprot index=%d\n",timestring(),choice
));
3994 /****************************************************************************
3995 close all open files for a connection
3996 ****************************************************************************/
3997 static void close_open_files(int cnum
)
4000 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
4001 if( Files
[i
].cnum
== cnum
&& Files
[i
].open
) {
4002 close_file(i
,False
);
4008 /****************************************************************************
4010 ****************************************************************************/
4011 void close_cnum(int cnum
, uint16 vuid
)
4013 DirCacheFlush(SNUM(cnum
));
4017 if (!OPEN_CNUM(cnum
))
4019 DEBUG(0,("Can't close cnum %d\n",cnum
));
4023 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) closed connection to service %s\n",
4025 remote_machine
,client_addr(),
4026 lp_servicename(SNUM(cnum
))));
4028 yield_connection(cnum
,
4029 lp_servicename(SNUM(cnum
)),
4030 lp_max_connections(SNUM(cnum
)));
4032 if (lp_status(SNUM(cnum
)))
4033 yield_connection(cnum
,"STATUS.",MAXSTATUS
);
4035 close_open_files(cnum
);
4036 dptr_closecnum(cnum
);
4038 /* execute any "postexec = " line */
4039 if (*lp_postexec(SNUM(cnum
)) && become_user(&Connections
[cnum
], cnum
,vuid
))
4042 strcpy(cmd
,lp_postexec(SNUM(cnum
)));
4043 standard_sub(cnum
,cmd
);
4044 smbrun(cmd
,NULL
,False
);
4049 /* execute any "root postexec = " line */
4050 if (*lp_rootpostexec(SNUM(cnum
)))
4053 strcpy(cmd
,lp_rootpostexec(SNUM(cnum
)));
4054 standard_sub(cnum
,cmd
);
4055 smbrun(cmd
,NULL
,False
);
4058 Connections
[cnum
].open
= False
;
4059 num_connections_open
--;
4060 if (Connections
[cnum
].ngroups
&& Connections
[cnum
].groups
)
4062 if (Connections
[cnum
].igroups
!= (int *)Connections
[cnum
].groups
)
4063 free(Connections
[cnum
].groups
);
4064 free(Connections
[cnum
].igroups
);
4065 Connections
[cnum
].groups
= NULL
;
4066 Connections
[cnum
].igroups
= NULL
;
4067 Connections
[cnum
].ngroups
= 0;
4070 free_namearray(Connections
[cnum
].veto_list
);
4071 free_namearray(Connections
[cnum
].hide_list
);
4073 string_set(&Connections
[cnum
].user
,"");
4074 string_set(&Connections
[cnum
].dirpath
,"");
4075 string_set(&Connections
[cnum
].connectpath
,"");
4079 /****************************************************************************
4080 simple routines to do connection counting
4081 ****************************************************************************/
4082 BOOL
yield_connection(int cnum
,char *name
,int max_connections
)
4084 struct connect_record crec
;
4087 int mypid
= getpid();
4090 DEBUG(3,("Yielding connection to %d %s\n",cnum
,name
));
4092 if (max_connections
<= 0)
4095 bzero(&crec
,sizeof(crec
));
4097 pstrcpy(fname
,lp_lockdir());
4098 standard_sub(cnum
,fname
);
4099 trim_string(fname
,"","/");
4103 strcat(fname
,".LCK");
4105 f
= fopen(fname
,"r+");
4108 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname
,strerror(errno
)));
4112 fseek(f
,0,SEEK_SET
);
4114 /* find a free spot */
4115 for (i
=0;i
<max_connections
;i
++)
4117 if (fread(&crec
,sizeof(crec
),1,f
) != 1)
4119 DEBUG(2,("Entry not found in lock file %s\n",fname
));
4123 if (crec
.pid
== mypid
&& crec
.cnum
== cnum
)
4127 if (crec
.pid
!= mypid
|| crec
.cnum
!= cnum
)
4130 DEBUG(2,("Entry not found in lock file %s\n",fname
));
4134 bzero((void *)&crec
,sizeof(crec
));
4136 /* remove our mark */
4137 if (fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
4138 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
4140 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname
,strerror(errno
)));
4145 DEBUG(3,("Yield successful\n"));
4152 /****************************************************************************
4153 simple routines to do connection counting
4154 ****************************************************************************/
4155 BOOL
claim_connection(int cnum
,char *name
,int max_connections
,BOOL Clear
)
4157 struct connect_record crec
;
4160 int snum
= SNUM(cnum
);
4164 if (max_connections
<= 0)
4167 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name
,max_connections
));
4169 pstrcpy(fname
,lp_lockdir());
4170 standard_sub(cnum
,fname
);
4171 trim_string(fname
,"","/");
4173 if (!directory_exist(fname
,NULL
))
4178 strcat(fname
,".LCK");
4180 if (!file_exist(fname
,NULL
))
4182 int oldmask
= umask(022);
4183 f
= fopen(fname
,"w");
4188 total_recs
= file_size(fname
) / sizeof(crec
);
4190 f
= fopen(fname
,"r+");
4194 DEBUG(1,("couldn't open lock file %s\n",fname
));
4198 /* find a free spot */
4199 for (i
=0;i
<max_connections
;i
++)
4202 if (i
>=total_recs
||
4203 fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
4204 fread(&crec
,sizeof(crec
),1,f
) != 1)
4206 if (foundi
< 0) foundi
= i
;
4210 if (Clear
&& crec
.pid
&& !process_exists(crec
.pid
))
4212 fseek(f
,i
*sizeof(crec
),SEEK_SET
);
4213 bzero((void *)&crec
,sizeof(crec
));
4214 fwrite(&crec
,sizeof(crec
),1,f
);
4215 if (foundi
< 0) foundi
= i
;
4218 if (foundi
< 0 && (!crec
.pid
|| !process_exists(crec
.pid
)))
4227 DEBUG(3,("no free locks in %s\n",fname
));
4232 /* fill in the crec */
4233 bzero((void *)&crec
,sizeof(crec
));
4234 crec
.magic
= 0x280267;
4235 crec
.pid
= getpid();
4237 crec
.uid
= Connections
[cnum
].uid
;
4238 crec
.gid
= Connections
[cnum
].gid
;
4239 StrnCpy(crec
.name
,lp_servicename(snum
),sizeof(crec
.name
)-1);
4240 crec
.start
= time(NULL
);
4242 StrnCpy(crec
.machine
,remote_machine
,sizeof(crec
.machine
)-1);
4243 StrnCpy(crec
.addr
,client_addr(),sizeof(crec
.addr
)-1);
4246 if (fseek(f
,foundi
*sizeof(crec
),SEEK_SET
) != 0 ||
4247 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
4258 /*******************************************************************
4259 prepare to dump a core file - carefully!
4260 ********************************************************************/
4261 static BOOL
dump_core(void)
4265 pstrcpy(dname
,debugf
);
4266 if ((p
=strrchr(dname
,'/'))) *p
=0;
4267 strcat(dname
,"/corefiles");
4269 sys_chown(dname
,getuid(),getgid());
4271 if (chdir(dname
)) return(False
);
4274 #ifndef NO_GETRLIMIT
4278 getrlimit(RLIMIT_CORE
, &rlp
);
4279 rlp
.rlim_cur
= MAX(4*1024*1024,rlp
.rlim_cur
);
4280 setrlimit(RLIMIT_CORE
, &rlp
);
4281 getrlimit(RLIMIT_CORE
, &rlp
);
4282 DEBUG(3,("Core limits now %d %d\n",rlp
.rlim_cur
,rlp
.rlim_max
));
4288 DEBUG(0,("Dumping core in %s\n",dname
));
4293 /****************************************************************************
4295 ****************************************************************************/
4296 void exit_server(char *reason
)
4298 static int firsttime
=1;
4301 if (!firsttime
) exit(0);
4305 DEBUG(2,("Closing connections\n"));
4306 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4307 if (Connections
[i
].open
)
4308 close_cnum(i
,(uint16
)-1);
4310 if (dcelogin_atmost_once
)
4314 int oldlevel
= DEBUGLEVEL
;
4316 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message
)));
4318 show_msg(last_inbuf
);
4319 DEBUGLEVEL
= oldlevel
;
4320 DEBUG(0,("===============================================================\n"));
4322 if (dump_core()) return;
4328 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason
?reason
:""));
4332 /****************************************************************************
4333 do some standard substitutions in a string
4334 ****************************************************************************/
4335 void standard_sub(int cnum
,char *str
)
4337 if (VALID_CNUM(cnum
)) {
4340 for ( s
=str
; (p
=strchr(s
, '%')) != NULL
; s
=p
) {
4342 case 'H' : if ((home
= get_home_dir(Connections
[cnum
].user
))!=NULL
)
4343 string_sub(p
,"%H",home
);
4347 case 'P' : string_sub(p
,"%P",Connections
[cnum
].connectpath
); break;
4348 case 'S' : string_sub(p
,"%S",lp_servicename(Connections
[cnum
].service
)); break;
4349 case 'g' : string_sub(p
,"%g",gidtoname(Connections
[cnum
].gid
)); break;
4350 case 'u' : string_sub(p
,"%u",Connections
[cnum
].user
); break;
4351 case '\0' : p
++; break; /* don't run off the end of the string */
4352 default : p
+=2; break;
4356 standard_sub_basic(str
);
4360 These flags determine some of the permissions required to do an operation
4362 Note that I don't set NEED_WRITE on some write operations because they
4363 are used by some brain-dead clients when printing, and I don't want to
4364 force write permissions on print services.
4366 #define AS_USER (1<<0)
4367 #define NEED_WRITE (1<<1)
4368 #define TIME_INIT (1<<2)
4369 #define CAN_IPC (1<<3)
4370 #define AS_GUEST (1<<5)
4374 define a list of possible SMB messages and their corresponding
4375 functions. Any message that has a NULL function is unimplemented -
4376 please feel free to contribute implementations!
4378 struct smb_message_struct
4392 {SMBnegprot
,"SMBnegprot",reply_negprot
,0},
4393 {SMBtcon
,"SMBtcon",reply_tcon
,0},
4394 {SMBtdis
,"SMBtdis",reply_tdis
,0},
4395 {SMBexit
,"SMBexit",reply_exit
,0},
4396 {SMBioctl
,"SMBioctl",reply_ioctl
,0},
4397 {SMBecho
,"SMBecho",reply_echo
,0},
4398 {SMBsesssetupX
,"SMBsesssetupX",reply_sesssetup_and_X
,0},
4399 {SMBtconX
,"SMBtconX",reply_tcon_and_X
,0},
4400 {SMBulogoffX
, "SMBulogoffX", reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
4401 {SMBgetatr
,"SMBgetatr",reply_getatr
,AS_USER
},
4402 {SMBsetatr
,"SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
4403 {SMBchkpth
,"SMBchkpth",reply_chkpth
,AS_USER
},
4404 {SMBsearch
,"SMBsearch",reply_search
,AS_USER
},
4405 {SMBopen
,"SMBopen",reply_open
,AS_USER
},
4407 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4408 {SMBcreate
,"SMBcreate",reply_mknew
,AS_USER
},
4409 {SMBmknew
,"SMBmknew",reply_mknew
,AS_USER
},
4411 {SMBunlink
,"SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
4412 {SMBread
,"SMBread",reply_read
,AS_USER
},
4413 {SMBwrite
,"SMBwrite",reply_write
,AS_USER
},
4414 {SMBclose
,"SMBclose",reply_close
,AS_USER
| CAN_IPC
},
4415 {SMBmkdir
,"SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
4416 {SMBrmdir
,"SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
4417 {SMBdskattr
,"SMBdskattr",reply_dskattr
,AS_USER
},
4418 {SMBmv
,"SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
4420 /* this is a Pathworks specific call, allowing the
4421 changing of the root path */
4422 {pSETDIR
,"pSETDIR",reply_setdir
,AS_USER
},
4424 {SMBlseek
,"SMBlseek",reply_lseek
,AS_USER
},
4425 {SMBflush
,"SMBflush",reply_flush
,AS_USER
},
4426 {SMBctemp
,"SMBctemp",reply_ctemp
,AS_USER
},
4427 {SMBsplopen
,"SMBsplopen",reply_printopen
,AS_USER
},
4428 {SMBsplclose
,"SMBsplclose",reply_printclose
,AS_USER
},
4429 {SMBsplretq
,"SMBsplretq",reply_printqueue
,AS_USER
|AS_GUEST
},
4430 {SMBsplwr
,"SMBsplwr",reply_printwrite
,AS_USER
},
4431 {SMBlock
,"SMBlock",reply_lock
,AS_USER
},
4432 {SMBunlock
,"SMBunlock",reply_unlock
,AS_USER
},
4434 /* CORE+ PROTOCOL FOLLOWS */
4436 {SMBreadbraw
,"SMBreadbraw",reply_readbraw
,AS_USER
},
4437 {SMBwritebraw
,"SMBwritebraw",reply_writebraw
,AS_USER
},
4438 {SMBwriteclose
,"SMBwriteclose",reply_writeclose
,AS_USER
},
4439 {SMBlockread
,"SMBlockread",reply_lockread
,AS_USER
},
4440 {SMBwriteunlock
,"SMBwriteunlock",reply_writeunlock
,AS_USER
},
4442 /* LANMAN1.0 PROTOCOL FOLLOWS */
4444 {SMBreadBmpx
,"SMBreadBmpx",reply_readbmpx
,AS_USER
},
4445 {SMBreadBs
,"SMBreadBs",NULL
,AS_USER
},
4446 {SMBwriteBmpx
,"SMBwriteBmpx",reply_writebmpx
,AS_USER
},
4447 {SMBwriteBs
,"SMBwriteBs",reply_writebs
,AS_USER
},
4448 {SMBwritec
,"SMBwritec",NULL
,AS_USER
},
4449 {SMBsetattrE
,"SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
4450 {SMBgetattrE
,"SMBgetattrE",reply_getattrE
,AS_USER
},
4451 {SMBtrans
,"SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
4452 {SMBtranss
,"SMBtranss",NULL
,AS_USER
| CAN_IPC
},
4453 {SMBioctls
,"SMBioctls",NULL
,AS_USER
},
4454 {SMBcopy
,"SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
4455 {SMBmove
,"SMBmove",NULL
,AS_USER
| NEED_WRITE
},
4457 {SMBopenX
,"SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
4458 {SMBreadX
,"SMBreadX",reply_read_and_X
,AS_USER
},
4459 {SMBwriteX
,"SMBwriteX",reply_write_and_X
,AS_USER
},
4460 {SMBlockingX
,"SMBlockingX",reply_lockingX
,AS_USER
},
4462 {SMBffirst
,"SMBffirst",reply_search
,AS_USER
},
4463 {SMBfunique
,"SMBfunique",reply_search
,AS_USER
},
4464 {SMBfclose
,"SMBfclose",reply_fclose
,AS_USER
},
4466 /* LANMAN2.0 PROTOCOL FOLLOWS */
4467 {SMBfindnclose
, "SMBfindnclose", reply_findnclose
, AS_USER
},
4468 {SMBfindclose
, "SMBfindclose", reply_findclose
,AS_USER
},
4469 {SMBtrans2
, "SMBtrans2", reply_trans2
, AS_USER
},
4470 {SMBtranss2
, "SMBtranss2", reply_transs2
, AS_USER
},
4472 /* messaging routines */
4473 {SMBsends
,"SMBsends",reply_sends
,AS_GUEST
},
4474 {SMBsendstrt
,"SMBsendstrt",reply_sendstrt
,AS_GUEST
},
4475 {SMBsendend
,"SMBsendend",reply_sendend
,AS_GUEST
},
4476 {SMBsendtxt
,"SMBsendtxt",reply_sendtxt
,AS_GUEST
},
4478 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4480 {SMBsendb
,"SMBsendb",NULL
,AS_GUEST
},
4481 {SMBfwdname
,"SMBfwdname",NULL
,AS_GUEST
},
4482 {SMBcancelf
,"SMBcancelf",NULL
,AS_GUEST
},
4483 {SMBgetmac
,"SMBgetmac",NULL
,AS_GUEST
}
4486 /****************************************************************************
4487 return a string containing the function name of a SMB command
4488 ****************************************************************************/
4489 char *smb_fn_name(int type
)
4491 static char *unknown_name
= "SMBunknown";
4492 static int num_smb_messages
=
4493 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
4496 for (match
=0;match
<num_smb_messages
;match
++)
4497 if (smb_messages
[match
].code
== type
)
4500 if (match
== num_smb_messages
)
4501 return(unknown_name
);
4503 return(smb_messages
[match
].name
);
4507 /****************************************************************************
4508 do a switch on the message type, and return the response size
4509 ****************************************************************************/
4510 static int switch_message(int type
,char *inbuf
,char *outbuf
,int size
,int bufsize
)
4514 static int num_smb_messages
=
4515 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
4519 struct timeval msg_start_time
;
4520 struct timeval msg_end_time
;
4521 static unsigned long total_time
= 0;
4523 GetTimeOfDay(&msg_start_time
);
4530 last_message
= type
;
4532 /* make sure this is an SMB packet */
4533 if (strncmp(smb_base(inbuf
),"\377SMB",4) != 0)
4535 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf
)));
4539 for (match
=0;match
<num_smb_messages
;match
++)
4540 if (smb_messages
[match
].code
== type
)
4543 if (match
== num_smb_messages
)
4545 DEBUG(0,("Unknown message type %d!\n",type
));
4546 outsize
= reply_unknown(inbuf
,outbuf
);
4550 DEBUG(3,("switch message %s (pid %d)\n",smb_messages
[match
].name
,pid
));
4551 if (smb_messages
[match
].fn
)
4553 int cnum
= SVAL(inbuf
,smb_tid
);
4554 int flags
= smb_messages
[match
].flags
;
4555 uint16 session_tag
= SVAL(inbuf
,smb_uid
);
4557 /* does this protocol need to be run as root? */
4558 if (!(flags
& AS_USER
))
4561 /* does this protocol need to be run as the connected user? */
4562 if ((flags
& AS_USER
) && !become_user(&Connections
[cnum
], cnum
,session_tag
)) {
4563 if (flags
& AS_GUEST
)
4566 return(ERROR(ERRSRV
,ERRinvnid
));
4568 /* this code is to work around a bug is MS client 3 without
4569 introducing a security hole - it needs to be able to do
4570 print queue checks as guest if it isn't logged in properly */
4571 if (flags
& AS_USER
)
4574 /* does it need write permission? */
4575 if ((flags
& NEED_WRITE
) && !CAN_WRITE(cnum
))
4576 return(ERROR(ERRSRV
,ERRaccess
));
4578 /* ipc services are limited */
4579 if (IS_IPC(cnum
) && (flags
& AS_USER
) && !(flags
& CAN_IPC
))
4580 return(ERROR(ERRSRV
,ERRaccess
));
4582 /* load service specific parameters */
4583 if (OPEN_CNUM(cnum
) && !become_service(cnum
,(flags
& AS_USER
)?True
:False
))
4584 return(ERROR(ERRSRV
,ERRaccess
));
4586 /* does this protocol need to be run as guest? */
4587 if ((flags
& AS_GUEST
) && (!become_guest() || !check_access(-1)))
4588 return(ERROR(ERRSRV
,ERRaccess
));
4592 outsize
= smb_messages
[match
].fn(inbuf
,outbuf
,size
,bufsize
);
4596 outsize
= reply_unknown(inbuf
,outbuf
);
4601 GetTimeOfDay(&msg_end_time
);
4602 if (!(smb_messages
[match
].flags
& TIME_INIT
))
4604 smb_messages
[match
].time
= 0;
4605 smb_messages
[match
].flags
|= TIME_INIT
;
4608 unsigned long this_time
=
4609 (msg_end_time
.tv_sec
- msg_start_time
.tv_sec
)*1e6
+
4610 (msg_end_time
.tv_usec
- msg_start_time
.tv_usec
);
4611 smb_messages
[match
].time
+= this_time
;
4612 total_time
+= this_time
;
4614 DEBUG(2,("TIME %s %d usecs %g pct\n",
4615 smb_fn_name(type
),smb_messages
[match
].time
,
4616 (100.0*smb_messages
[match
].time
) / total_time
));
4623 /****************************************************************************
4624 construct a chained reply and add it to the already made reply
4625 **************************************************************************/
4626 int chain_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
4628 static char *orig_inbuf
;
4629 static char *orig_outbuf
;
4630 int smb_com1
, smb_com2
= CVAL(inbuf
,smb_vwv0
);
4631 unsigned smb_off2
= SVAL(inbuf
,smb_vwv1
);
4632 char *inbuf2
, *outbuf2
;
4634 char inbuf_saved
[smb_wct
];
4635 char outbuf_saved
[smb_wct
];
4636 extern int chain_size
;
4637 int wct
= CVAL(outbuf
,smb_wct
);
4638 int outsize
= smb_size
+ 2*wct
+ SVAL(outbuf
,smb_vwv0
+2*wct
);
4640 /* maybe its not chained */
4641 if (smb_com2
== 0xFF) {
4642 CVAL(outbuf
,smb_vwv0
) = 0xFF;
4646 if (chain_size
== 0) {
4647 /* this is the first part of the chain */
4649 orig_outbuf
= outbuf
;
4652 /* we need to tell the client where the next part of the reply will be */
4653 SSVAL(outbuf
,smb_vwv1
,smb_offset(outbuf
+outsize
,outbuf
));
4654 CVAL(outbuf
,smb_vwv0
) = smb_com2
;
4656 /* remember how much the caller added to the chain, only counting stuff
4657 after the parameter words */
4658 chain_size
+= outsize
- smb_wct
;
4660 /* work out pointers into the original packets. The
4661 headers on these need to be filled in */
4662 inbuf2
= orig_inbuf
+ smb_off2
+ 4 - smb_wct
;
4663 outbuf2
= orig_outbuf
+ SVAL(outbuf
,smb_vwv1
) + 4 - smb_wct
;
4665 /* remember the original command type */
4666 smb_com1
= CVAL(orig_inbuf
,smb_com
);
4668 /* save the data which will be overwritten by the new headers */
4669 memcpy(inbuf_saved
,inbuf2
,smb_wct
);
4670 memcpy(outbuf_saved
,outbuf2
,smb_wct
);
4672 /* give the new packet the same header as the last part of the SMB */
4673 memmove(inbuf2
,inbuf
,smb_wct
);
4675 /* create the in buffer */
4676 CVAL(inbuf2
,smb_com
) = smb_com2
;
4678 /* create the out buffer */
4679 bzero(outbuf2
,smb_size
);
4680 set_message(outbuf2
,0,0,True
);
4681 CVAL(outbuf2
,smb_com
) = CVAL(inbuf2
,smb_com
);
4683 memcpy(outbuf2
+4,inbuf2
+4,4);
4684 CVAL(outbuf2
,smb_rcls
) = SUCCESS
;
4685 CVAL(outbuf2
,smb_reh
) = 0;
4686 CVAL(outbuf2
,smb_flg
) = 0x80 | (CVAL(inbuf2
,smb_flg
) & 0x8); /* bit 7 set
4688 SSVAL(outbuf2
,smb_flg2
,1); /* say we support long filenames */
4689 SSVAL(outbuf2
,smb_err
,SUCCESS
);
4690 SSVAL(outbuf2
,smb_tid
,SVAL(inbuf2
,smb_tid
));
4691 SSVAL(outbuf2
,smb_pid
,SVAL(inbuf2
,smb_pid
));
4692 SSVAL(outbuf2
,smb_uid
,SVAL(inbuf2
,smb_uid
));
4693 SSVAL(outbuf2
,smb_mid
,SVAL(inbuf2
,smb_mid
));
4695 DEBUG(3,("Chained message\n"));
4698 /* process the request */
4699 outsize2
= switch_message(smb_com2
,inbuf2
,outbuf2
,size
-chain_size
,
4700 bufsize
-chain_size
);
4702 /* copy the new reply and request headers over the old ones, but
4703 preserve the smb_com field */
4704 memmove(orig_outbuf
,outbuf2
,smb_wct
);
4705 CVAL(orig_outbuf
,smb_com
) = smb_com1
;
4707 /* restore the saved data, being careful not to overwrite any
4708 data from the reply header */
4709 memcpy(inbuf2
,inbuf_saved
,smb_wct
);
4711 int ofs
= smb_wct
- PTR_DIFF(outbuf2
,orig_outbuf
);
4712 if (ofs
< 0) ofs
= 0;
4713 memmove(outbuf2
+ofs
,outbuf_saved
+ofs
,smb_wct
-ofs
);
4721 /****************************************************************************
4722 construct a reply to the incoming packet
4723 ****************************************************************************/
4724 int construct_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
4726 int type
= CVAL(inbuf
,smb_com
);
4728 int msg_type
= CVAL(inbuf
,0);
4729 extern int chain_size
;
4731 smb_last_time
= time(NULL
);
4737 bzero(outbuf
,smb_size
);
4740 return(reply_special(inbuf
,outbuf
));
4742 CVAL(outbuf
,smb_com
) = CVAL(inbuf
,smb_com
);
4743 set_message(outbuf
,0,0,True
);
4745 memcpy(outbuf
+4,inbuf
+4,4);
4746 CVAL(outbuf
,smb_rcls
) = SUCCESS
;
4747 CVAL(outbuf
,smb_reh
) = 0;
4748 CVAL(outbuf
,smb_flg
) = 0x80 | (CVAL(inbuf
,smb_flg
) & 0x8); /* bit 7 set
4750 SSVAL(outbuf
,smb_flg2
,1); /* say we support long filenames */
4751 SSVAL(outbuf
,smb_err
,SUCCESS
);
4752 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
4753 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
4754 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
4755 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
4757 outsize
= switch_message(type
,inbuf
,outbuf
,size
,bufsize
);
4759 outsize
+= chain_size
;
4762 smb_setlen(outbuf
,outsize
- 4);
4766 /****************************************************************************
4767 process commands from the client
4768 ****************************************************************************/
4769 static void process(void)
4773 InBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
4774 OutBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
4775 if ((InBuffer
== NULL
) || (OutBuffer
== NULL
))
4778 InBuffer
+= SMB_ALIGNMENT
;
4779 OutBuffer
+= SMB_ALIGNMENT
;
4782 DEBUG(3,("priming nmbd\n"));
4785 ip
= *interpret_addr2("localhost");
4786 if (zero_ip(ip
)) ip
= *interpret_addr2("127.0.0.1");
4788 send_one_packet(OutBuffer
,1,ip
,NMB_PORT
,SOCK_DGRAM
);
4792 /* re-initialise the timezone */
4797 int deadtime
= lp_deadtime()*60;
4799 int last_keepalive
=0;
4800 int service_load_counter
= 0;
4801 BOOL got_smb
= False
;
4804 deadtime
= DEFAULT_SMBD_TIMEOUT
;
4806 #if USE_READ_PREDICTION
4807 if (lp_readprediction())
4808 do_read_prediction();
4813 for (counter
=SMBD_SELECT_LOOP
;
4814 !receive_message_or_smb(Client
,oplock_sock
,
4815 InBuffer
,BUFFER_SIZE
,SMBD_SELECT_LOOP
*1000,&got_smb
);
4816 counter
+= SMBD_SELECT_LOOP
)
4820 BOOL allidle
= True
;
4821 extern int keepalive
;
4823 if (counter
> 365 * 3600) /* big number of seconds. */
4826 service_load_counter
= 0;
4829 if (smb_read_error
== READ_EOF
)
4831 DEBUG(3,("end of file from client\n"));
4835 if (smb_read_error
== READ_ERROR
)
4837 DEBUG(3,("receive_smb error (%s) exiting\n",
4844 /* become root again if waiting */
4847 /* check for smb.conf reload */
4848 if (counter
>= service_load_counter
+ SMBD_RELOAD_CHECK
)
4850 service_load_counter
= counter
;
4852 /* reload services, if files have changed. */
4853 reload_services(True
);
4856 /* automatic timeout if all connections are closed */
4857 if (num_connections_open
==0 && counter
>= IDLE_CLOSED_TIMEOUT
)
4859 DEBUG(2,("%s Closing idle connection\n",timestring()));
4863 if (keepalive
&& (counter
-last_keepalive
)>keepalive
)
4865 struct cli_state
*cli
= server_client();
4866 if (!send_keepalive(Client
)) {
4867 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4870 /* also send a keepalive to the password server if its still
4872 if (cli
&& cli
->initialised
)
4873 send_keepalive(cli
->fd
);
4874 last_keepalive
= counter
;
4877 /* check for connection timeouts */
4878 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4879 if (Connections
[i
].open
)
4881 /* close dirptrs on connections that are idle */
4882 if ((t
-Connections
[i
].lastused
)>DPTR_IDLE_TIMEOUT
)
4885 if (Connections
[i
].num_files_open
> 0 ||
4886 (t
-Connections
[i
].lastused
)<deadtime
)
4890 if (allidle
&& num_connections_open
>0)
4892 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4898 process_smb(InBuffer
, OutBuffer
);
4900 process_local_message(oplock_sock
, InBuffer
, BUFFER_SIZE
);
4905 /****************************************************************************
4906 initialise connect, service and file structs
4907 ****************************************************************************/
4908 static void init_structs(void )
4911 get_myname(myhostname
,NULL
);
4913 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4915 Connections
[i
].open
= False
;
4916 Connections
[i
].num_files_open
=0;
4917 Connections
[i
].lastused
=0;
4918 Connections
[i
].used
=False
;
4919 string_init(&Connections
[i
].user
,"");
4920 string_init(&Connections
[i
].dirpath
,"");
4921 string_init(&Connections
[i
].connectpath
,"");
4922 string_init(&Connections
[i
].origpath
,"");
4925 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
4927 Files
[i
].open
= False
;
4928 string_init(&Files
[i
].name
,"");
4932 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
4934 file_fd_struct
*fd_ptr
= &FileFd
[i
];
4935 fd_ptr
->ref_count
= 0;
4936 fd_ptr
->dev
= (int32
)-1;
4937 fd_ptr
->inode
= (int32
)-1;
4939 fd_ptr
->fd_readonly
= -1;
4940 fd_ptr
->fd_writeonly
= -1;
4941 fd_ptr
->real_open_flags
= -1;
4945 init_rpc_pipe_hnd();
4948 /* for LSA handles */
4949 init_lsa_policy_hnd();
4955 /****************************************************************************
4956 usage on the program
4957 ****************************************************************************/
4958 static void usage(char *pname
)
4960 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4962 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname
);
4963 printf("Version %s\n",VERSION
);
4964 printf("\t-D become a daemon\n");
4965 printf("\t-p port listen on the specified port\n");
4966 printf("\t-d debuglevel set the debuglevel\n");
4967 printf("\t-l log basename. Basename for log/debug files\n");
4968 printf("\t-s services file. Filename of services file\n");
4969 printf("\t-P passive only\n");
4970 printf("\t-a overwrite log file, don't append\n");
4975 /****************************************************************************
4977 ****************************************************************************/
4978 int main(int argc
,char *argv
[])
4980 extern BOOL append_log
;
4981 /* shall I run as a daemon */
4982 BOOL is_daemon
= False
;
4983 int port
= SMB_PORT
;
4985 extern char *optarg
;
4986 char pidFile
[100] = { 0 };
4988 #ifdef NEED_AUTH_PARAMETERS
4989 set_auth_parameters(argc
,argv
);
5000 strcpy(debugf
,SMBLOGFILE
);
5002 setup_logging(argv
[0],False
);
5004 charset_initialise();
5006 /* make absolutely sure we run as root - to handle cases whre people
5007 are crazy enough to have it setuid */
5017 fault_setup(exit_server
);
5018 signal(SIGTERM
, SIGNAL_CAST dflt_sig
);
5020 /* we want total control over the permissions on created files,
5021 so set our umask to 0 */
5028 /* this is for people who can't start the program correctly */
5029 while (argc
> 1 && (*argv
[1] != '-'))
5035 while ((opt
= getopt(argc
, argv
, "O:i:l:s:d:Dp:hPaf:")) != EOF
)
5039 strncpy(pidFile
, optarg
, sizeof(pidFile
));
5042 strcpy(user_socket_options
,optarg
);
5045 strcpy(scope
,optarg
);
5049 extern BOOL passive
;
5054 strcpy(servicesf
,optarg
);
5057 strcpy(debugf
,optarg
);
5061 extern BOOL append_log
;
5062 append_log
= !append_log
;
5072 DEBUGLEVEL
= atoi(optarg
);
5075 port
= atoi(optarg
);
5088 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION
));
5089 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
5091 #ifndef NO_GETRLIMIT
5092 #ifdef RLIMIT_NOFILE
5095 getrlimit(RLIMIT_NOFILE
, &rlp
);
5096 rlp
.rlim_cur
= (MAX_OPEN_FILES
>rlp
.rlim_max
)? rlp
.rlim_max
:MAX_OPEN_FILES
;
5097 setrlimit(RLIMIT_NOFILE
, &rlp
);
5098 getrlimit(RLIMIT_NOFILE
, &rlp
);
5099 DEBUG(3,("Maximum number of open files per session is %d\n",rlp
.rlim_cur
));
5105 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
5106 getuid(),getgid(),geteuid(),getegid()));
5108 if (sizeof(uint16
) < 2 || sizeof(uint32
) < 4)
5110 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5116 if (!reload_services(False
))
5119 codepage_initialise(lp_client_code_page());
5121 strcpy(myworkgroup
, lp_workgroup());
5123 #ifndef NO_SIGNAL_TEST
5124 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
5127 DEBUG(3,("%s loaded services\n",timestring()));
5129 if (!is_daemon
&& !is_a_socket(0))
5131 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5137 DEBUG(3,("%s becoming a daemon\n",timestring()));
5141 if (!directory_exist(lp_lockdir(), NULL
)) {
5142 mkdir(lp_lockdir(), 0755);
5150 if ((fd
= open(pidFile
,
5154 O_CREAT
| O_WRONLY
| O_TRUNC
, 0644)) < 0)
5156 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile
, strerror(errno
)));
5159 if(fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)==False
)
5161 DEBUG(0,("ERROR: smbd is already running\n"));
5164 sprintf(buf
, "%u\n", (unsigned int) getpid());
5165 if (write(fd
, buf
, strlen(buf
)) < 0)
5167 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile
, strerror(errno
)));
5170 /* Leave pid file open & locked for the duration... */
5173 if (!open_sockets(is_daemon
,port
))
5176 if (!locking_init(0))
5179 /* possibly reload the services file. */
5180 reload_services(True
);
5182 max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
5186 if (sys_chroot(lp_rootdir()) == 0)
5187 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5190 /* Setup the oplock IPC socket. */
5191 if(!open_oplock_ipc())
5197 exit_server("normal exit");