2 Unix SMB/Netbios implementation.
4 Main SMB server routines
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 pstring servicesf
= CONFIGFILE
;
26 extern pstring debugf
;
27 extern pstring sesssetup_user
;
28 extern fstring myworkgroup
;
30 char *InBuffer
= NULL
;
31 char *OutBuffer
= NULL
;
32 char *last_inbuf
= NULL
;
37 /* the last message the was processed */
38 int last_message
= -1;
40 /* a useful macro to debug the last message processed */
41 #define LAST_MESSAGE() smb_fn_name(last_message)
44 extern int DEBUGLEVEL
;
45 extern int case_default
;
46 extern BOOL case_sensitive
;
47 extern BOOL case_preserve
;
48 extern BOOL use_mangled_map
;
49 extern BOOL short_case_preserve
;
50 extern BOOL case_mangle
;
51 extern time_t smb_last_time
;
53 extern int smb_read_error
;
55 extern pstring user_socket_options
;
57 connection_struct Connections
[MAX_CONNECTIONS
];
58 files_struct Files
[MAX_OPEN_FILES
];
61 * Indirection for file fd's. Needed as POSIX locking
62 * is based on file/process, not fd/process.
64 file_fd_struct FileFd
[MAX_OPEN_FILES
];
65 int max_file_fd_used
= 0;
70 * Size of data we can send to client. Set
71 * by the client for all protocols above CORE.
72 * Set by us for CORE protocol.
74 int max_send
= BUFFER_SIZE
;
76 * Size of the data we can receive. Set by us.
77 * Can be modified by the max xmit parameter.
79 int max_recv
= BUFFER_SIZE
;
81 /* a fnum to use when chaining */
84 /* number of open connections */
85 static int num_connections_open
= 0;
87 /* 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
;
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
;
321 if(sys_utime(fname
, times
) == 0)
324 if((errno
!= EPERM
) || !lp_dos_filetimes(SNUM(cnum
)))
327 /* We have permission (given by the Samba admin) to
328 break POSIX semantics and allow a user to change
329 the time on a file they don't own but can write to
333 if(sys_stat(fname
,&sb
) != 0)
336 /* Check if we have write access. */
337 if (CAN_WRITE(cnum
) && !lp_alternate_permissions(SNUM(cnum
)))
339 if (((sb
.st_mode
& S_IWOTH
) ||
340 Connections
[cnum
].admin_user
||
341 ((sb
.st_mode
& S_IWUSR
) && current_user
.uid
==sb
.st_uid
) ||
342 ((sb
.st_mode
& S_IWGRP
) &&
343 in_group(sb
.st_gid
,current_user
.gid
,
344 current_user
.ngroups
,current_user
.igroups
))))
346 /* We are allowed to become root and change the filetime. */
348 ret
= sys_utime(fname
, times
);
349 unbecome_root(False
);
356 /*******************************************************************
357 Change a filetime - possibly allowing DOS semantics.
358 *******************************************************************/
360 BOOL
set_filetime(int cnum
, char *fname
, time_t mtime
)
362 struct utimbuf times
;
364 if (null_mtime(mtime
)) return(True
);
366 times
.modtime
= times
.actime
= mtime
;
368 if (file_utime(cnum
, fname
, ×
)) {
369 DEBUG(4,("set_filetime(%s) failed: %s\n",fname
,strerror(errno
)));
375 /****************************************************************************
376 check if two filenames are equal
378 this needs to be careful about whether we are case sensitive
379 ****************************************************************************/
380 static BOOL
fname_equal(char *name1
, char *name2
)
382 int l1
= strlen(name1
);
383 int l2
= strlen(name2
);
385 /* handle filenames ending in a single dot */
386 if (l1
-l2
== 1 && name1
[l1
-1] == '.' && lp_strip_dot())
390 ret
= fname_equal(name1
,name2
);
395 if (l2
-l1
== 1 && name2
[l2
-1] == '.' && lp_strip_dot())
399 ret
= fname_equal(name1
,name2
);
404 /* now normal filename handling */
406 return(strcmp(name1
,name2
) == 0);
408 return(strequal(name1
,name2
));
412 /****************************************************************************
413 mangle the 2nd name and check if it is then equal to the first name
414 ****************************************************************************/
415 static BOOL
mangled_equal(char *name1
, char *name2
)
419 if (is_8_3(name2
, True
))
422 strcpy(tmpname
,name2
);
423 mangle_name_83(tmpname
);
425 return(strequal(name1
,tmpname
));
429 /****************************************************************************
430 scan a directory to find a filename, matching without case sensitivity
432 If the name looks like a mangled name then try via the mangling functions
433 ****************************************************************************/
434 static BOOL
scan_directory(char *path
, char *name
,int cnum
,BOOL docache
)
441 mangled
= is_mangled(name
);
443 /* handle null paths */
447 if (docache
&& (dname
= DirCacheCheck(path
,name
,SNUM(cnum
)))) {
453 check_mangled_stack(name
);
455 /* open the directory */
456 if (!(cur_dir
= OpenDir(cnum
, path
, True
)))
458 DEBUG(3,("scan dir didn't open dir [%s]\n",path
));
462 /* now scan for matching names */
463 while ((dname
= ReadDirName(cur_dir
)))
466 (strequal(dname
,".") || strequal(dname
,"..")))
469 pstrcpy(name2
,dname
);
470 if (!name_map_mangle(name2
,False
,SNUM(cnum
))) continue;
472 if ((mangled
&& mangled_equal(name
,name2
))
473 || fname_equal(name
, name2
)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
475 /* we've found the file, change it's name and return */
476 if (docache
) DirCacheAdd(path
,name
,dname
,SNUM(cnum
));
487 /****************************************************************************
488 This routine is called to convert names from the dos namespace to unix
489 namespace. It needs to handle any case conversions, mangling, format
492 We assume that we have already done a chdir() to the right "root" directory
495 The function will return False if some part of the name except for the last
496 part cannot be resolved
498 If the saved_last_component != 0, then the unmodified last component
499 of the pathname is returned there. This is used in an exceptional
500 case in reply_mv (so far). If saved_last_component == 0 then nothing
503 The bad_path arg is set to True if the filename walk failed. This is
504 used to pick the correct error code to return between ENOENT and ENOTDIR
505 as Windows applications depend on ERRbadpath being returned if a component
506 of a pathname does not exist.
507 ****************************************************************************/
508 BOOL
unix_convert(char *name
,int cnum
,pstring saved_last_component
, BOOL
*bad_path
)
518 if(saved_last_component
)
519 *saved_last_component
= 0;
521 /* convert to basic unix format - removing \ chars and cleaning it up */
523 unix_clean_name(name
);
525 /* names must be relative to the root of the service - trim any leading /.
526 also trim trailing /'s */
527 trim_string(name
,"/","/");
530 * Ensure saved_last_component is valid even if file exists.
532 if(saved_last_component
) {
533 end
= strrchr(name
, '/');
535 strcpy(saved_last_component
, end
+ 1);
537 strcpy(saved_last_component
, name
);
540 if (!case_sensitive
&&
541 (!case_preserve
|| (is_8_3(name
, False
) && !short_case_preserve
)))
544 /* check if it's a printer file */
545 if (Connections
[cnum
].printer
)
547 if ((! *name
) || strchr(name
,'/') || !is_8_3(name
, True
))
551 sprintf(name2
,"%.6s.XXXXXX",remote_machine
);
552 /* sanitise the name */
553 for (s
=name2
; *s
; s
++)
554 if (!issafe(*s
)) *s
= '_';
555 strcpy(name
,(char *)mktemp(name2
));
560 /* stat the name - if it exists then we are all done! */
561 if (sys_stat(name
,&st
) == 0)
566 DEBUG(5,("unix_convert(%s,%d)\n",name
,cnum
));
568 /* a special case - if we don't have any mangling chars and are case
569 sensitive then searching won't help */
570 if (case_sensitive
&& !is_mangled(name
) &&
571 !lp_strip_dot() && !use_mangled_map
&& (saved_errno
!= ENOENT
))
574 /* now we need to recursively match the name against the real
575 directory structure */
578 while (strncmp(start
,"./",2) == 0)
581 /* now match each part of the path name separately, trying the names
582 as is first, then trying to scan the directory for matching names */
583 for (;start
;start
= (end
?end
+1:(char *)NULL
))
585 /* pinpoint the end of this section of the filename */
586 end
= strchr(start
, '/');
588 /* chop the name at this point */
591 if(saved_last_component
!= 0)
592 strcpy(saved_last_component
, end
? end
+ 1 : start
);
594 /* check if the name exists up to this point */
595 if (sys_stat(name
, &st
) == 0)
597 /* it exists. it must either be a directory or this must be
598 the last part of the path for it to be OK */
599 if (end
&& !(st
.st_mode
& S_IFDIR
))
601 /* an intermediate part of the name isn't a directory */
602 DEBUG(5,("Not a dir %s\n",start
));
613 /* remember the rest of the pathname so it can be restored
615 if (end
) pstrcpy(rest
,end
+1);
617 /* try to find this part of the path in the directory */
618 if (strchr(start
,'?') || strchr(start
,'*') ||
619 !scan_directory(dirpath
, start
, cnum
, end
?True
:False
))
623 /* an intermediate part of the name can't be found */
624 DEBUG(5,("Intermediate not found %s\n",start
));
626 /* We need to return the fact that the intermediate
627 name resolution failed. This is used to return an
628 error of ERRbadpath rather than ERRbadfile. Some
629 Windows applications depend on the difference between
636 /* just the last part of the name doesn't exist */
637 /* we may need to strupper() or strlower() it in case
638 this conversion is being used for file creation
640 /* if the filename is of mixed case then don't normalise it */
641 if (!case_preserve
&&
642 (!strhasupper(start
) || !strhaslower(start
)))
645 /* check on the mangled stack to see if we can recover the
646 base of the filename */
647 if (is_mangled(start
))
648 check_mangled_stack(start
);
650 DEBUG(5,("New file %s\n",start
));
654 /* restore the rest of the string */
657 strcpy(start
+strlen(start
)+1,rest
);
658 end
= start
+ strlen(start
);
662 /* add to the dirpath that we have resolved so far */
663 if (*dirpath
) strcat(dirpath
,"/");
664 strcat(dirpath
,start
);
666 /* restore the / that we wiped out earlier */
670 /* the name has been resolved */
671 DEBUG(5,("conversion finished %s\n",name
));
676 /****************************************************************************
677 normalise for DOS usage
678 ****************************************************************************/
679 static void disk_norm(int *bsize
,int *dfree
,int *dsize
)
681 /* check if the disk is beyond the max disk size */
682 int maxdisksize
= lp_maxdisksize();
684 /* convert to blocks - and don't overflow */
685 maxdisksize
= ((maxdisksize
*1024)/(*bsize
))*1024;
686 if (*dsize
> maxdisksize
) *dsize
= maxdisksize
;
687 if (*dfree
> maxdisksize
) *dfree
= maxdisksize
-1; /* the -1 should stop
692 while (*dfree
> WORDMAX
|| *dsize
> WORDMAX
|| *bsize
< 512)
697 if (*bsize
> WORDMAX
)
700 if (*dsize
> WORDMAX
)
702 if (*dfree
> WORDMAX
)
709 /****************************************************************************
710 return number of 1K blocks available on a path and total number
711 ****************************************************************************/
712 int disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
714 char *df_command
= lp_dfree_command();
735 /* possibly use system() to get the result */
736 if (df_command
&& *df_command
)
742 sprintf(outfile
,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
743 sprintf(syscmd
,"%s %s",df_command
,path
);
744 standard_sub_basic(syscmd
);
746 ret
= smbrun(syscmd
,outfile
,False
);
747 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
750 FILE *f
= fopen(outfile
,"r");
756 fscanf(f
,"%d %d %d",dsize
,dfree
,bsize
);
760 DEBUG(0,("Can't open %s\n",outfile
));
764 disk_norm(bsize
,dfree
,dsize
);
765 dfree_retval
= ((*bsize
)/1024)*(*dfree
);
767 /* Ensure we return the min value between the users quota and
768 what's free on the disk. Thanks to Albrecht Gebhardt
769 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
771 if (disk_quotas(path
, &bsizeq
, &dfreeq
, &dsizeq
))
773 disk_norm(&bsizeq
, &dfreeq
, &dsizeq
);
774 dfreeq_retval
= ((bsizeq
)/1024)*(dfreeq
);
775 dfree_retval
= ( dfree_retval
< dfreeq_retval
) ?
776 dfree_retval
: dfreeq_retval
;
777 /* maybe dfree and dfreeq are calculated using different bsizes
778 so convert dfree from bsize into bsizeq */
779 /* avoid overflows due to multiplication, so do not:
780 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
781 bsize and bsizeq are powers of 2 so its better to
782 to divide them getting a multiplication or division factor
783 for dfree. Rene Nieuwenhuizen (07-10-1997) */
784 if (*bsize
>= bsizeq
)
785 *dfree
= *dfree
* (*bsize
/ bsizeq
);
787 *dfree
= *dfree
/ (bsizeq
/ *bsize
);
788 *dfree
= ( *dfree
< dfreeq
) ? *dfree
: dfreeq
;
793 return(dfree_retval
);
797 DEBUG(1,("Warning - no statfs function\n"));
801 if (statfs(path
,&fs
,sizeof(fs
),0) != 0)
804 if (statvfs(path
, &fs
))
807 if (statfs(path
,&fs
,sizeof(fs
)) == -1)
809 if (statfs(path
,&fs
) == -1)
811 #endif /* USE_STATVFS */
814 DEBUG(3,("dfree call failed code errno=%d\n",errno
));
818 return(((*bsize
)/1024)*(*dfree
));
823 *dfree
= fs
.fd_req
.bfree
;
824 *dsize
= fs
.fd_req
.btot
;
827 *bsize
= fs
.f_frsize
;
830 /* eg: osf1 has f_fsize = fundamental filesystem block size,
831 f_bsize = optimal transfer block size (MX: 94-04-19) */
836 #endif /* USE_STATVFS */
841 *dfree
= fs
.f_bavail
;
843 *dsize
= fs
.f_blocks
;
846 #if defined(SCO) || defined(ISC) || defined(MIPS)
850 /* handle rediculous bsize values - some OSes are broken */
851 if ((*bsize
) < 512 || (*bsize
)>0xFFFF) *bsize
= 1024;
853 disk_norm(bsize
,dfree
,dsize
);
859 DEBUG(0,("dfree seems to be broken on your system\n"));
860 *dsize
= 20*1024*1024/(*bsize
);
861 *dfree
= MAX(1,*dfree
);
863 dfree_retval
= ((*bsize
)/1024)*(*dfree
);
865 /* Ensure we return the min value between the users quota and
866 what's free on the disk. Thanks to Albrecht Gebhardt
867 <albrecht.gebhardt@uni-klu.ac.at> for this fix.
869 if (disk_quotas(path
, &bsizeq
, &dfreeq
, &dsizeq
))
871 disk_norm(&bsizeq
, &dfreeq
, &dsizeq
);
872 dfreeq_retval
= ((bsizeq
)/1024)*(dfreeq
);
873 dfree_retval
= ( dfree_retval
< dfreeq_retval
) ?
874 dfree_retval
: dfreeq_retval
;
875 /* maybe dfree and dfreeq are calculated using different bsizes
876 so convert dfree from bsize into bsizeq */
877 /* avoid overflows due to multiplication, so do not:
878 *dfree = ((*dfree) * (*bsize)) / (bsizeq);
879 bsize and bsizeq are powers of 2 so its better to
880 to divide them getting a multiplication or division factor
881 for dfree. Rene Nieuwenhuizen (07-10-1997) */
882 if (*bsize
>= bsizeq
)
883 *dfree
= *dfree
* (*bsize
/ bsizeq
);
885 *dfree
= *dfree
/ (bsizeq
/ *bsize
);
886 *dfree
= ( *dfree
< dfreeq
) ? *dfree
: dfreeq
;
891 return(dfree_retval
);
896 /****************************************************************************
897 wrap it to get filenames right
898 ****************************************************************************/
899 int sys_disk_free(char *path
,int *bsize
,int *dfree
,int *dsize
)
901 return(disk_free(dos_to_unix(path
,False
),bsize
,dfree
,dsize
));
906 /****************************************************************************
907 check a filename - possibly caling reducename
909 This is called by every routine before it allows an operation on a filename.
910 It does any final confirmation necessary to ensure that the filename is
911 a valid one for the user to access.
912 ****************************************************************************/
913 BOOL
check_name(char *name
,int cnum
)
919 if( IS_VETO_PATH(cnum
, name
))
921 DEBUG(5,("file path name %s vetoed\n",name
));
925 ret
= reduce_name(name
,Connections
[cnum
].connectpath
,lp_widelinks(SNUM(cnum
)));
927 /* Check if we are allowing users to follow symlinks */
928 /* Patch from David Clerc <David.Clerc@cui.unige.ch>
929 University of Geneva */
932 if (!lp_symlinks(SNUM(cnum
)))
935 if ( (sys_lstat(name
,&statbuf
) != -1) &&
936 (S_ISLNK(statbuf
.st_mode
)) )
938 DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name
));
945 DEBUG(5,("check_name on %s failed\n",name
));
950 /****************************************************************************
951 check a filename - possibly caling reducename
952 ****************************************************************************/
953 static void check_for_pipe(char *fname
)
955 /* special case of pipe opens */
959 if (strstr(s
,"pipe/"))
961 DEBUG(3,("Rejecting named pipe open for %s\n",fname
));
962 unix_ERR_class
= ERRSRV
;
963 unix_ERR_code
= ERRaccess
;
967 /****************************************************************************
968 fd support routines - attempt to do a sys_open
969 ****************************************************************************/
970 static int fd_attempt_open(char *fname
, int flags
, int mode
)
972 int fd
= sys_open(fname
,flags
,mode
);
974 /* Fix for files ending in '.' */
975 if((fd
== -1) && (errno
== ENOENT
) &&
976 (strchr(fname
,'.')==NULL
))
979 fd
= sys_open(fname
,flags
,mode
);
982 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
983 if ((fd
== -1) && (errno
== ENAMETOOLONG
))
986 char *p
= strrchr(fname
, '/');
988 if (p
== fname
) /* name is "/xxx" */
990 max_len
= pathconf("/", _PC_NAME_MAX
);
993 else if ((p
== NULL
) || (p
== fname
))
996 max_len
= pathconf(".", _PC_NAME_MAX
);
1001 max_len
= pathconf(fname
, _PC_NAME_MAX
);
1005 if (strlen(p
) > max_len
)
1007 char tmp
= p
[max_len
];
1010 if ((fd
= sys_open(fname
,flags
,mode
)) == -1)
1018 /****************************************************************************
1019 fd support routines - attempt to find an already open file by dev
1020 and inode - increments the ref_count of the returned file_fd_struct *.
1021 ****************************************************************************/
1022 static file_fd_struct
*fd_get_already_open(struct stat
*sbuf
)
1025 file_fd_struct
*fd_ptr
;
1030 for(i
= 0; i
<= max_file_fd_used
; i
++) {
1031 fd_ptr
= &FileFd
[i
];
1032 if((fd_ptr
->ref_count
> 0) &&
1033 (((uint32
)sbuf
->st_dev
) == fd_ptr
->dev
) &&
1034 (((uint32
)sbuf
->st_ino
) == fd_ptr
->inode
)) {
1035 fd_ptr
->ref_count
++;
1037 ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
1038 i
, fd_ptr
->dev
, fd_ptr
->inode
, fd_ptr
->ref_count
));
1045 /****************************************************************************
1046 fd support routines - attempt to find a empty slot in the FileFd array.
1047 Increments the ref_count of the returned entry.
1048 ****************************************************************************/
1049 static file_fd_struct
*fd_get_new()
1052 file_fd_struct
*fd_ptr
;
1054 for(i
= 0; i
< MAX_OPEN_FILES
; i
++) {
1055 fd_ptr
= &FileFd
[i
];
1056 if(fd_ptr
->ref_count
== 0) {
1057 fd_ptr
->dev
= (uint32
)-1;
1058 fd_ptr
->inode
= (uint32
)-1;
1060 fd_ptr
->fd_readonly
= -1;
1061 fd_ptr
->fd_writeonly
= -1;
1062 fd_ptr
->real_open_flags
= -1;
1063 fd_ptr
->ref_count
++;
1064 /* Increment max used counter if neccessary, cuts down
1065 on search time when re-using */
1066 if(i
> max_file_fd_used
)
1067 max_file_fd_used
= i
;
1068 DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
1069 i
, fd_ptr
->dev
, fd_ptr
->inode
));
1073 DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
1078 /****************************************************************************
1079 fd support routines - attempt to re-open an already open fd as O_RDWR.
1080 Save the already open fd (we cannot close due to POSIX file locking braindamage.
1081 ****************************************************************************/
1082 static void fd_attempt_reopen(char *fname
, int mode
, file_fd_struct
*fd_ptr
)
1084 int fd
= sys_open( fname
, O_RDWR
, mode
);
1089 if(fd_ptr
->real_open_flags
== O_RDONLY
)
1090 fd_ptr
->fd_readonly
= fd_ptr
->fd
;
1091 if(fd_ptr
->real_open_flags
== O_WRONLY
)
1092 fd_ptr
->fd_writeonly
= fd_ptr
->fd
;
1095 fd_ptr
->real_open_flags
= O_RDWR
;
1098 /****************************************************************************
1099 fd support routines - attempt to close the file referenced by this fd.
1100 Decrements the ref_count and returns it.
1101 ****************************************************************************/
1102 static int fd_attempt_close(file_fd_struct
*fd_ptr
)
1104 DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
1105 fd_ptr
- &FileFd
[0],
1106 fd_ptr
->fd
, fd_ptr
->dev
, fd_ptr
->inode
,
1107 fd_ptr
->real_open_flags
,
1108 fd_ptr
->ref_count
));
1109 if(fd_ptr
->ref_count
> 0) {
1110 fd_ptr
->ref_count
--;
1111 if(fd_ptr
->ref_count
== 0) {
1112 if(fd_ptr
->fd
!= -1)
1114 if(fd_ptr
->fd_readonly
!= -1)
1115 close(fd_ptr
->fd_readonly
);
1116 if(fd_ptr
->fd_writeonly
!= -1)
1117 close(fd_ptr
->fd_writeonly
);
1119 fd_ptr
->fd_readonly
= -1;
1120 fd_ptr
->fd_writeonly
= -1;
1121 fd_ptr
->real_open_flags
= -1;
1122 fd_ptr
->dev
= (uint32
)-1;
1123 fd_ptr
->inode
= (uint32
)-1;
1126 return fd_ptr
->ref_count
;
1129 /****************************************************************************
1131 ****************************************************************************/
1132 static void open_file(int fnum
,int cnum
,char *fname1
,int flags
,int mode
, struct stat
*sbuf
)
1134 extern struct current_user current_user
;
1136 struct stat statbuf
;
1137 file_fd_struct
*fd_ptr
;
1138 files_struct
*fsp
= &Files
[fnum
];
1142 fsp
->granted_oplock
= False
;
1145 pstrcpy(fname
,fname1
);
1147 /* check permissions */
1148 if ((flags
!= O_RDONLY
) && !CAN_WRITE(cnum
) && !Connections
[cnum
].printer
)
1150 DEBUG(3,("Permission denied opening %s\n",fname
));
1151 check_for_pipe(fname
);
1155 /* this handles a bug in Win95 - it doesn't say to create the file when it
1157 if (Connections
[cnum
].printer
)
1161 if (flags == O_WRONLY)
1162 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
1166 * Ensure we have a valid struct stat so we can search the
1170 if(stat(fname
, &statbuf
) < 0) {
1171 if(errno
!= ENOENT
) {
1172 DEBUG(3,("Error doing stat on file %s (%s)\n",
1173 fname
,strerror(errno
)));
1175 check_for_pipe(fname
);
1185 * Check to see if we have this file already
1186 * open. If we do, just use the already open fd and increment the
1187 * reference count (fd_get_already_open increments the ref_count).
1189 if((fd_ptr
= fd_get_already_open(sbuf
))!= 0) {
1191 int accmode
= (flags
& (O_RDONLY
| O_WRONLY
| O_RDWR
));
1193 /* File was already open. */
1194 if((flags
& O_CREAT
) && (flags
& O_EXCL
)) {
1195 fd_ptr
->ref_count
--;
1201 * If not opened O_RDWR try
1202 * and do that here - a chmod may have been done
1203 * between the last open and now.
1205 if(fd_ptr
->real_open_flags
!= O_RDWR
)
1206 fd_attempt_reopen(fname
, mode
, fd_ptr
);
1209 * Ensure that if we wanted write access
1210 * it has been opened for write, and if we wanted read it
1211 * was open for read.
1213 if(((accmode
== O_WRONLY
) && (fd_ptr
->real_open_flags
== O_RDONLY
)) ||
1214 ((accmode
== O_RDONLY
) && (fd_ptr
->real_open_flags
== O_WRONLY
)) ||
1215 ((accmode
== O_RDWR
) && (fd_ptr
->real_open_flags
!= O_RDWR
))) {
1216 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
1217 fd_ptr
->real_open_flags
, fname
,strerror(EACCES
),flags
));
1218 check_for_pipe(fname
);
1219 fd_ptr
->ref_count
--;
1225 /* We need to allocate a new file_fd_struct (this increments the
1227 if((fd_ptr
= fd_get_new()) == 0)
1230 * Whatever the requested flags, attempt read/write access,
1231 * as we don't know what flags future file opens may require.
1232 * If this fails, try again with the required flags.
1233 * Even if we open read/write when only read access was
1234 * requested the setting of the can_write flag in
1235 * the file_struct will protect us from errant
1236 * write requests. We never need to worry about O_APPEND
1237 * as this is not set anywhere in Samba.
1239 fd_ptr
->real_open_flags
= O_RDWR
;
1240 /* Set the flags as needed without the read/write modes. */
1241 open_flags
= flags
& ~(O_RDWR
|O_WRONLY
|O_RDONLY
);
1242 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDWR
, mode
);
1244 * On some systems opening a file for R/W access on a read only
1245 * filesystems sets errno to EROFS.
1248 if((fd_ptr
->fd
== -1) && ((errno
== EACCES
) || (errno
== EROFS
))) {
1249 #else /* No EROFS */
1250 if((fd_ptr
->fd
== -1) && (errno
== EACCES
)) {
1252 if(flags
& O_WRONLY
) {
1253 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_WRONLY
, mode
);
1254 fd_ptr
->real_open_flags
= O_WRONLY
;
1256 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDONLY
, mode
);
1257 fd_ptr
->real_open_flags
= O_RDONLY
;
1262 if ((fd_ptr
->fd
>=0) &&
1263 Connections
[cnum
].printer
&& lp_minprintspace(SNUM(cnum
))) {
1267 pstrcpy(dname
,fname
);
1268 p
= strrchr(dname
,'/');
1270 if (sys_disk_free(dname
,&dum1
,&dum2
,&dum3
) <
1271 lp_minprintspace(SNUM(cnum
))) {
1272 fd_attempt_close(fd_ptr
);
1274 if(fd_ptr
->ref_count
== 0)
1283 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
1284 fname
,strerror(errno
),flags
));
1285 /* Ensure the ref_count is decremented. */
1286 fd_attempt_close(fd_ptr
);
1287 check_for_pipe(fname
);
1291 if (fd_ptr
->fd
>= 0)
1295 if(fstat(fd_ptr
->fd
, &statbuf
) == -1) {
1296 /* Error - backout !! */
1297 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
1298 fd_ptr
->fd
, fname
,strerror(errno
)));
1299 /* Ensure the ref_count is decremented. */
1300 fd_attempt_close(fd_ptr
);
1305 /* Set the correct entries in fd_ptr. */
1306 fd_ptr
->dev
= (uint32
)sbuf
->st_dev
;
1307 fd_ptr
->inode
= (uint32
)sbuf
->st_ino
;
1309 fsp
->fd_ptr
= fd_ptr
;
1310 Connections
[cnum
].num_files_open
++;
1311 fsp
->mode
= sbuf
->st_mode
;
1312 GetTimeOfDay(&fsp
->open_time
);
1313 fsp
->uid
= current_user
.id
;
1317 fsp
->mmap_ptr
= NULL
;
1319 fsp
->can_lock
= True
;
1320 fsp
->can_read
= ((flags
& O_WRONLY
)==0);
1321 fsp
->can_write
= ((flags
& (O_WRONLY
|O_RDWR
))!=0);
1322 fsp
->share_mode
= 0;
1323 fsp
->print_file
= Connections
[cnum
].printer
;
1324 fsp
->modified
= False
;
1325 fsp
->granted_oplock
= False
;
1327 string_set(&fsp
->name
,dos_to_unix(fname
,False
));
1328 fsp
->wbmpx_ptr
= NULL
;
1331 * If the printer is marked as postscript output a leading
1332 * file identifier to ensure the file is treated as a raw
1334 * This has a similar effect as CtrlD=0 in WIN.INI file.
1335 * tim@fsg.com 09/06/94
1337 if (fsp
->print_file
&& POSTSCRIPT(cnum
) &&
1340 DEBUG(3,("Writing postscript line\n"));
1341 write_file(fnum
,"%!\n",3);
1344 DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
1345 timestring(),Connections
[cnum
].user
,fname
,
1346 BOOLSTR(fsp
->can_read
),BOOLSTR(fsp
->can_write
),
1347 Connections
[cnum
].num_files_open
,fnum
));
1352 /* mmap it if read-only */
1353 if (!fsp
->can_write
)
1355 fsp
->mmap_size
= file_size(fname
);
1356 fsp
->mmap_ptr
= (char *)mmap(NULL
,fsp
->mmap_size
,
1357 PROT_READ
,MAP_SHARED
,fsp
->fd_ptr
->fd
,0);
1359 if (fsp
->mmap_ptr
== (char *)-1 || !fsp
->mmap_ptr
)
1361 DEBUG(3,("Failed to mmap() %s - %s\n",fname
,strerror(errno
)));
1362 fsp
->mmap_ptr
= NULL
;
1368 /*******************************************************************
1370 ********************************************************************/
1371 void sync_file(int fnum
)
1374 fsync(Files
[fnum
].fd_ptr
->fd
);
1378 /****************************************************************************
1379 run a file if it is a magic script
1380 ****************************************************************************/
1381 static void check_magic(int fnum
,int cnum
)
1383 if (!*lp_magicscript(SNUM(cnum
)))
1386 DEBUG(5,("checking magic for %s\n",Files
[fnum
].name
));
1390 if (!(p
= strrchr(Files
[fnum
].name
,'/')))
1391 p
= Files
[fnum
].name
;
1395 if (!strequal(lp_magicscript(SNUM(cnum
)),p
))
1401 pstring magic_output
;
1403 pstrcpy(fname
,Files
[fnum
].name
);
1405 if (*lp_magicoutput(SNUM(cnum
)))
1406 pstrcpy(magic_output
,lp_magicoutput(SNUM(cnum
)));
1408 sprintf(magic_output
,"%s.out",fname
);
1411 ret
= smbrun(fname
,magic_output
,False
);
1412 DEBUG(3,("Invoking magic command %s gave %d\n",fname
,ret
));
1418 /****************************************************************************
1419 close a file - possibly invalidating the read prediction
1421 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
1422 operation otherwise it came as the result of some other operation such as
1423 the closing of the connection. In the latter case printing and
1424 magic scripts are not run
1425 ****************************************************************************/
1426 void close_file(int fnum
, BOOL normal_close
)
1428 files_struct
*fs_p
= &Files
[fnum
];
1429 int cnum
= fs_p
->cnum
;
1430 uint32 dev
= fs_p
->fd_ptr
->dev
;
1431 uint32 inode
= fs_p
->fd_ptr
->inode
;
1434 invalidate_read_prediction(fs_p
->fd_ptr
->fd
);
1436 Connections
[cnum
].num_files_open
--;
1439 free((char *)fs_p
->wbmpx_ptr
);
1440 fs_p
->wbmpx_ptr
= NULL
;
1446 munmap(fs_p
->mmap_ptr
,fs_p
->mmap_size
);
1447 fs_p
->mmap_ptr
= NULL
;
1451 if (lp_share_modes(SNUM(cnum
)))
1453 lock_share_entry( cnum
, dev
, inode
, &token
);
1454 del_share_mode(token
, fnum
);
1457 fd_attempt_close(fs_p
->fd_ptr
);
1459 if (lp_share_modes(SNUM(cnum
)))
1460 unlock_share_entry( cnum
, dev
, inode
, token
);
1462 /* NT uses smbclose to start a print - weird */
1463 if (normal_close
&& fs_p
->print_file
)
1466 /* check for magic scripts */
1468 check_magic(fnum
,cnum
);
1470 DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
1471 timestring(),Connections
[cnum
].user
,fs_p
->name
,
1472 Connections
[cnum
].num_files_open
));
1475 enum {AFAIL
,AREAD
,AWRITE
,AALL
};
1477 /*******************************************************************
1478 reproduce the share mode access table
1479 ********************************************************************/
1480 static int access_table(int new_deny
,int old_deny
,int old_mode
,
1481 int share_pid
,char *fname
)
1483 if (new_deny
== DENY_ALL
|| old_deny
== DENY_ALL
) return(AFAIL
);
1485 if (new_deny
== DENY_DOS
|| old_deny
== DENY_DOS
) {
1487 if (old_deny
== new_deny
&& share_pid
== pid
)
1490 if (old_mode
== 0) return(AREAD
);
1492 /* the new smbpub.zip spec says that if the file extension is
1493 .com, .dll, .exe or .sym then allow the open. I will force
1494 it to read-only as this seems sensible although the spec is
1495 a little unclear on this. */
1496 if ((fname
= strrchr(fname
,'.'))) {
1497 if (strequal(fname
,".com") ||
1498 strequal(fname
,".dll") ||
1499 strequal(fname
,".exe") ||
1500 strequal(fname
,".sym"))
1510 if (old_deny
==DENY_WRITE
&& old_mode
==0) return(AREAD
);
1511 if (old_deny
==DENY_READ
&& old_mode
==0) return(AWRITE
);
1512 if (old_deny
==DENY_NONE
&& old_mode
==0) return(AALL
);
1515 if (old_deny
==DENY_WRITE
&& old_mode
==1) return(AREAD
);
1516 if (old_deny
==DENY_READ
&& old_mode
==1) return(AWRITE
);
1517 if (old_deny
==DENY_NONE
&& old_mode
==1) return(AALL
);
1520 if (old_deny
==DENY_WRITE
) return(AREAD
);
1521 if (old_deny
==DENY_READ
) return(AWRITE
);
1522 if (old_deny
==DENY_NONE
) return(AALL
);
1528 /*******************************************************************
1529 check if the share mode on a file allows it to be deleted or unlinked
1530 return True if sharing doesn't prevent the operation
1531 ********************************************************************/
1532 BOOL
check_file_sharing(int cnum
,char *fname
)
1536 share_mode_entry
*old_shares
= 0;
1537 int num_share_modes
;
1543 if(!lp_share_modes(SNUM(cnum
)))
1546 if (stat(fname
,&sbuf
) == -1) return(True
);
1548 dev
= (uint32
)sbuf
.st_dev
;
1549 inode
= (uint32
)sbuf
.st_ino
;
1551 lock_share_entry(cnum
, dev
, inode
, &token
);
1552 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1555 * Check if the share modes will give us access.
1558 if(num_share_modes
!= 0)
1565 broke_oplock
= False
;
1566 for(i
= 0; i
< num_share_modes
; i
++)
1568 share_mode_entry
*share_entry
= &old_shares
[i
];
1571 * Break oplocks before checking share modes. See comment in
1572 * open_file_shared for details.
1573 * Check if someone has an oplock on this file. If so we must
1574 * break it before continuing.
1576 if(share_entry
->op_type
& BATCH_OPLOCK
)
1579 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1580 dev = %x, inode = %x\n", share_entry
->op_type
, fname
, dev
, inode
));
1582 /* Oplock break.... */
1583 unlock_share_entry(cnum
, dev
, inode
, token
);
1584 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
1586 free((char *)old_shares
);
1587 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1588 dev = %x, inode = %x\n", old_shares
[i
].op_type
, fname
, dev
, inode
));
1591 lock_share_entry(cnum
, dev
, inode
, &token
);
1592 broke_oplock
= True
;
1596 /* someone else has a share lock on it, check to see
1598 if ((share_entry
->share_mode
!= DENY_DOS
) || (share_entry
->pid
!= pid
))
1605 free((char *)old_shares
);
1606 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1608 } while(broke_oplock
);
1611 /* XXXX exactly what share mode combinations should be allowed for
1612 deleting/renaming? */
1613 /* If we got here then either there were no share modes or
1614 all share modes were DENY_DOS and the pid == getpid() */
1619 unlock_share_entry(cnum
, dev
, inode
, token
);
1620 if(old_shares
!= NULL
)
1621 free((char *)old_shares
);
1625 /****************************************************************************
1627 Helper for open_file_shared.
1628 Truncate a file after checking locking; close file if locked.
1629 **************************************************************************/
1630 static void truncate_unless_locked(int fnum
, int cnum
, int token
,
1633 if (Files
[fnum
].can_write
){
1634 if (is_locked(fnum
,cnum
,0x3FFFFFFF,0)){
1635 /* If share modes are in force for this connection we
1636 have the share entry locked. Unlock it before closing. */
1637 if (*share_locked
&& lp_share_modes(SNUM(cnum
)))
1638 unlock_share_entry( cnum
, Files
[fnum
].fd_ptr
->dev
,
1639 Files
[fnum
].fd_ptr
->inode
, token
);
1640 close_file(fnum
,False
);
1641 /* Share mode no longer locked. */
1642 *share_locked
= False
;
1644 unix_ERR_class
= ERRDOS
;
1645 unix_ERR_code
= ERRlock
;
1648 ftruncate(Files
[fnum
].fd_ptr
->fd
,0);
1652 /****************************************************************************
1653 check if we can open a file with a share mode
1654 ****************************************************************************/
1655 int check_share_mode( share_mode_entry
*share
, int deny_mode
, char *fname
,
1656 BOOL fcbopen
, int *flags
)
1658 int old_open_mode
= share
->share_mode
&0xF;
1659 int old_deny_mode
= (share
->share_mode
>>4)&7;
1661 if (old_deny_mode
> 4 || old_open_mode
> 2)
1663 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1664 deny_mode
,old_deny_mode
,old_open_mode
,fname
));
1669 int access_allowed
= access_table(deny_mode
,old_deny_mode
,old_open_mode
,
1672 if ((access_allowed
== AFAIL
) ||
1673 (!fcbopen
&& (access_allowed
== AREAD
&& *flags
== O_RDWR
)) ||
1674 (access_allowed
== AREAD
&& *flags
== O_WRONLY
) ||
1675 (access_allowed
== AWRITE
&& *flags
== O_RDONLY
))
1677 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
1678 deny_mode
,old_deny_mode
,old_open_mode
,
1679 share
->pid
,fname
, access_allowed
));
1683 if (access_allowed
== AREAD
)
1686 if (access_allowed
== AWRITE
)
1693 /****************************************************************************
1694 open a file with a share mode
1695 ****************************************************************************/
1696 void open_file_shared(int fnum
,int cnum
,char *fname
,int share_mode
,int ofun
,
1697 int mode
,int oplock_request
, int *Access
,int *action
)
1699 files_struct
*fs_p
= &Files
[fnum
];
1702 int deny_mode
= (share_mode
>>4)&7;
1704 BOOL file_existed
= file_exist(fname
,&sbuf
);
1705 BOOL share_locked
= False
;
1706 BOOL fcbopen
= False
;
1710 int num_share_modes
= 0;
1715 /* this is for OS/2 EAs - try and say we don't support them */
1716 if (strstr(fname
,".+,;=[]."))
1718 unix_ERR_class
= ERRDOS
;
1719 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1721 unix_ERR_code
= ERRcannotopen
;
1722 #else /* OS2_WPS_FIX */
1723 unix_ERR_code
= ERROR_EAS_NOT_SUPPORTED
;
1724 #endif /* OS2_WPS_FIX */
1729 if ((ofun
& 0x3) == 0 && file_existed
)
1737 if ((ofun
& 0x3) == 2)
1740 /* note that we ignore the append flag as
1741 append does not mean the same thing under dos and unix */
1743 switch (share_mode
&0xF)
1760 if (flags
!= O_RDONLY
&& file_existed
&&
1761 (!CAN_WRITE(cnum
) || IS_DOS_READONLY(dos_mode(cnum
,fname
,&sbuf
))))
1771 if (deny_mode
> DENY_NONE
&& deny_mode
!=DENY_FCB
)
1773 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode
,fname
));
1778 if (deny_mode
== DENY_FCB
) deny_mode
= DENY_DOS
;
1780 if (lp_share_modes(SNUM(cnum
)))
1783 share_mode_entry
*old_shares
= 0;
1787 dev
= (uint32
)sbuf
.st_dev
;
1788 inode
= (uint32
)sbuf
.st_ino
;
1789 lock_share_entry(cnum
, dev
, inode
, &token
);
1790 share_locked
= True
;
1791 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1795 * Check if the share modes will give us access.
1798 if(share_locked
&& (num_share_modes
!= 0))
1805 broke_oplock
= False
;
1806 for(i
= 0; i
< num_share_modes
; i
++)
1808 share_mode_entry
*share_entry
= &old_shares
[i
];
1811 * By observation of NetBench, oplocks are broken *before* share
1812 * modes are checked. This allows a file to be closed by the client
1813 * if the share mode would deny access and the client has an oplock.
1814 * Check if someone has an oplock on this file. If so we must break
1815 * it before continuing.
1817 if(share_entry
->op_type
& (EXCLUSIVE_OPLOCK
|BATCH_OPLOCK
))
1820 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
1821 dev = %x, inode = %x\n", share_entry
->op_type
, fname
, dev
, inode
));
1823 /* Oplock break.... */
1824 unlock_share_entry(cnum
, dev
, inode
, token
);
1825 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
1827 free((char *)old_shares
);
1828 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
1829 dev = %x, inode = %x\n", old_shares
[i
].op_type
, fname
, dev
, inode
));
1831 unix_ERR_class
= ERRDOS
;
1832 unix_ERR_code
= ERRbadshare
;
1835 lock_share_entry(cnum
, dev
, inode
, &token
);
1836 broke_oplock
= True
;
1840 /* someone else has a share lock on it, check to see
1842 if(check_share_mode(share_entry
, deny_mode
, fname
, fcbopen
, &flags
) == False
)
1844 free((char *)old_shares
);
1845 unlock_share_entry(cnum
, dev
, inode
, token
);
1847 unix_ERR_class
= ERRDOS
;
1848 unix_ERR_code
= ERRbadshare
;
1856 free((char *)old_shares
);
1857 num_share_modes
= get_share_modes(cnum
, token
, dev
, inode
, &old_shares
);
1859 } while(broke_oplock
);
1863 free((char *)old_shares
);
1866 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1867 flags
,flags2
,mode
));
1869 open_file(fnum
,cnum
,fname
,flags
|(flags2
&~(O_TRUNC
)),mode
,file_existed
? &sbuf
: 0);
1870 if (!fs_p
->open
&& flags
==O_RDWR
&& errno
!=ENOENT
&& fcbopen
)
1873 open_file(fnum
,cnum
,fname
,flags
,mode
,file_existed
? &sbuf
: 0 );
1880 if((share_locked
== False
) && lp_share_modes(SNUM(cnum
)))
1882 /* We created the file - thus we must now lock the share entry before creating it. */
1883 dev
= fs_p
->fd_ptr
->dev
;
1884 inode
= fs_p
->fd_ptr
->inode
;
1885 lock_share_entry(cnum
, dev
, inode
, &token
);
1886 share_locked
= True
;
1902 fs_p
->share_mode
= (deny_mode
<<4) | open_mode
;
1905 (*Access
) = open_mode
;
1909 if (file_existed
&& !(flags2
& O_TRUNC
)) *action
= 1;
1910 if (!file_existed
) *action
= 2;
1911 if (file_existed
&& (flags2
& O_TRUNC
)) *action
= 3;
1913 /* We must create the share mode entry before truncate as
1914 truncate can fail due to locking and have to close the
1915 file (which expects the share_mode_entry to be there).
1917 if (lp_share_modes(SNUM(cnum
)))
1920 /* JRA. Currently this only services Exlcusive and batch
1921 oplocks (no other opens on this file). This needs to
1922 be extended to level II oplocks (multiple reader
1925 if(oplock_request
&& (num_share_modes
== 0) && lp_oplocks(SNUM(cnum
)))
1927 fs_p
->granted_oplock
= True
;
1928 global_oplocks_open
++;
1931 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
1932 dev = %x, inode = %x\n", oplock_request
, fname
, dev
, inode
));
1940 set_share_mode(token
, fnum
, port
, oplock_request
);
1943 if ((flags2
&O_TRUNC
) && file_existed
)
1944 truncate_unless_locked(fnum
,cnum
,token
,&share_locked
);
1947 if (share_locked
&& lp_share_modes(SNUM(cnum
)))
1948 unlock_share_entry( cnum
, dev
, inode
, token
);
1951 /****************************************************************************
1952 seek a file. Try to avoid the seek if possible
1953 ****************************************************************************/
1954 int seek_file(int fnum
,uint32 pos
)
1957 if (Files
[fnum
].print_file
&& POSTSCRIPT(Files
[fnum
].cnum
))
1960 Files
[fnum
].pos
= (int)(lseek(Files
[fnum
].fd_ptr
->fd
,pos
+offset
,SEEK_SET
)
1962 return(Files
[fnum
].pos
);
1965 /****************************************************************************
1967 ****************************************************************************/
1968 int read_file(int fnum
,char *data
,uint32 pos
,int n
)
1972 if (!Files
[fnum
].can_write
)
1974 ret
= read_predict(Files
[fnum
].fd_ptr
->fd
,pos
,data
,NULL
,n
);
1982 if (Files
[fnum
].mmap_ptr
)
1984 int num
= MIN(n
,(int)(Files
[fnum
].mmap_size
-pos
));
1987 memcpy(data
,Files
[fnum
].mmap_ptr
+pos
,num
);
1999 if (seek_file(fnum
,pos
) != pos
)
2001 DEBUG(3,("Failed to seek to %d\n",pos
));
2006 readret
= read(Files
[fnum
].fd_ptr
->fd
,data
,n
);
2007 if (readret
> 0) ret
+= readret
;
2014 /****************************************************************************
2016 ****************************************************************************/
2017 int write_file(int fnum
,char *data
,int n
)
2019 if (!Files
[fnum
].can_write
) {
2024 if (!Files
[fnum
].modified
) {
2026 Files
[fnum
].modified
= True
;
2027 if (fstat(Files
[fnum
].fd_ptr
->fd
,&st
) == 0) {
2028 int dosmode
= dos_mode(Files
[fnum
].cnum
,Files
[fnum
].name
,&st
);
2029 if (MAP_ARCHIVE(Files
[fnum
].cnum
) && !IS_DOS_ARCHIVE(dosmode
)) {
2030 dos_chmod(Files
[fnum
].cnum
,Files
[fnum
].name
,dosmode
| aARCH
,&st
);
2035 return(write_data(Files
[fnum
].fd_ptr
->fd
,data
,n
));
2039 /****************************************************************************
2040 load parameters specific to a connection/service
2041 ****************************************************************************/
2042 BOOL
become_service(int cnum
,BOOL do_chdir
)
2044 extern char magic_char
;
2045 static int last_cnum
= -1;
2048 if (!OPEN_CNUM(cnum
))
2054 Connections
[cnum
].lastused
= smb_last_time
;
2059 ChDir(Connections
[cnum
].connectpath
) != 0 &&
2060 ChDir(Connections
[cnum
].origpath
) != 0)
2062 DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
2063 Connections
[cnum
].connectpath
,cnum
));
2067 if (cnum
== last_cnum
)
2072 case_default
= lp_defaultcase(snum
);
2073 case_preserve
= lp_preservecase(snum
);
2074 short_case_preserve
= lp_shortpreservecase(snum
);
2075 case_mangle
= lp_casemangle(snum
);
2076 case_sensitive
= lp_casesensitive(snum
);
2077 magic_char
= lp_magicchar(snum
);
2078 use_mangled_map
= (*lp_mangled_map(snum
) ? True
:False
);
2083 /****************************************************************************
2084 find a service entry
2085 ****************************************************************************/
2086 int find_service(char *service
)
2090 string_sub(service
,"\\","/");
2092 iService
= lp_servicenumber(service
);
2094 /* now handle the special case of a home directory */
2097 char *phome_dir
= get_home_dir(service
);
2098 DEBUG(3,("checking for home directory %s gave %s\n",service
,
2099 phome_dir
?phome_dir
:"(NULL)"));
2103 if ((iHomeService
= lp_servicenumber(HOMES_NAME
)) >= 0)
2105 lp_add_home(service
,iHomeService
,phome_dir
);
2106 iService
= lp_servicenumber(service
);
2111 /* If we still don't have a service, attempt to add it as a printer. */
2114 int iPrinterService
;
2116 if ((iPrinterService
= lp_servicenumber(PRINTERS_NAME
)) >= 0)
2120 DEBUG(3,("checking whether %s is a valid printer name...\n", service
));
2122 if ((pszTemp
!= NULL
) && pcap_printername_ok(service
, pszTemp
))
2124 DEBUG(3,("%s is a valid printer name\n", service
));
2125 DEBUG(3,("adding %s as a printer service\n", service
));
2126 lp_add_printer(service
,iPrinterService
);
2127 iService
= lp_servicenumber(service
);
2129 DEBUG(0,("failed to add %s as a printer service!\n", service
));
2132 DEBUG(3,("%s is not a valid printer name\n", service
));
2136 /* just possibly it's a default service? */
2139 char *defservice
= lp_defaultservice();
2140 if (defservice
&& *defservice
&& !strequal(defservice
,service
)) {
2141 iService
= find_service(defservice
);
2142 if (iService
>= 0) {
2143 string_sub(service
,"_","/");
2144 iService
= lp_add_service(service
,iService
);
2150 if (!VALID_SNUM(iService
))
2152 DEBUG(0,("Invalid snum %d for %s\n",iService
,service
));
2157 DEBUG(3,("find_service() failed to find service %s\n", service
));
2163 /****************************************************************************
2164 create an error packet from a cached error.
2165 ****************************************************************************/
2166 int cached_error_packet(char *inbuf
,char *outbuf
,int fnum
,int line
)
2168 write_bmpx_struct
*wbmpx
= Files
[fnum
].wbmpx_ptr
;
2170 int32 eclass
= wbmpx
->wr_errclass
;
2171 int32 err
= wbmpx
->wr_error
;
2173 /* We can now delete the auxiliary struct */
2174 free((char *)wbmpx
);
2175 Files
[fnum
].wbmpx_ptr
= NULL
;
2176 return error_packet(inbuf
,outbuf
,eclass
,err
,line
);
2185 } unix_smb_errmap
[] =
2187 {EPERM
,ERRDOS
,ERRnoaccess
},
2188 {EACCES
,ERRDOS
,ERRnoaccess
},
2189 {ENOENT
,ERRDOS
,ERRbadfile
},
2190 {ENOTDIR
,ERRDOS
,ERRbadpath
},
2191 {EIO
,ERRHRD
,ERRgeneral
},
2192 {EBADF
,ERRSRV
,ERRsrverror
},
2193 {EINVAL
,ERRSRV
,ERRsrverror
},
2194 {EEXIST
,ERRDOS
,ERRfilexists
},
2195 {ENFILE
,ERRDOS
,ERRnofids
},
2196 {EMFILE
,ERRDOS
,ERRnofids
},
2197 {ENOSPC
,ERRHRD
,ERRdiskfull
},
2199 {EDQUOT
,ERRHRD
,ERRdiskfull
},
2202 {ENOTEMPTY
,ERRDOS
,ERRnoaccess
},
2205 {EXDEV
,ERRDOS
,ERRdiffdevice
},
2207 {EROFS
,ERRHRD
,ERRnowrite
},
2211 /****************************************************************************
2212 create an error packet from errno
2213 ****************************************************************************/
2214 int unix_error_packet(char *inbuf
,char *outbuf
,int def_class
,uint32 def_code
,int line
)
2216 int eclass
=def_class
;
2220 if (unix_ERR_class
!= SUCCESS
)
2222 eclass
= unix_ERR_class
;
2223 ecode
= unix_ERR_code
;
2224 unix_ERR_class
= SUCCESS
;
2229 while (unix_smb_errmap
[i
].smbclass
!= 0)
2231 if (unix_smb_errmap
[i
].unixerror
== errno
)
2233 eclass
= unix_smb_errmap
[i
].smbclass
;
2234 ecode
= unix_smb_errmap
[i
].smbcode
;
2241 return(error_packet(inbuf
,outbuf
,eclass
,ecode
,line
));
2245 /****************************************************************************
2246 create an error packet. Normally called using the ERROR() macro
2247 ****************************************************************************/
2248 int error_packet(char *inbuf
,char *outbuf
,int error_class
,uint32 error_code
,int line
)
2250 int outsize
= set_message(outbuf
,0,0,True
);
2252 cmd
= CVAL(inbuf
,smb_com
);
2254 CVAL(outbuf
,smb_rcls
) = error_class
;
2255 SSVAL(outbuf
,smb_err
,error_code
);
2257 DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
2260 (int)CVAL(inbuf
,smb_com
),
2261 smb_fn_name(CVAL(inbuf
,smb_com
)),
2266 DEBUG(3,("error string = %s\n",strerror(errno
)));
2272 #ifndef SIGCLD_IGNORE
2273 /****************************************************************************
2274 this prevents zombie child processes
2275 ****************************************************************************/
2276 static int sig_cld()
2278 static int depth
= 0;
2281 DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
2287 BlockSignals(True
,SIGCLD
);
2288 DEBUG(5,("got SIGCLD\n"));
2291 while (sys_waitpid((pid_t
)-1,(int *)NULL
, WNOHANG
) > 0);
2295 /* Stevens, Adv. Unix Prog. says that on system V you must call
2296 wait before reinstalling the signal handler, because the kernel
2297 calls the handler from within the signal-call when there is a
2298 child that has exited. This would lead to an infinite recursion
2299 if done vice versa. */
2301 #ifndef DONT_REINSTALL_SIG
2302 #ifdef SIGCLD_IGNORE
2303 signal(SIGCLD
, SIG_IGN
);
2305 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
2310 while (wait3(WAIT3_CAST1 NULL
, WNOHANG
, WAIT3_CAST2 NULL
) > 0);
2313 BlockSignals(False
,SIGCLD
);
2318 /****************************************************************************
2319 this is called when the client exits abruptly
2320 **************************************************************************/
2321 static int sig_pipe()
2323 struct cli_state
*cli
;
2324 BlockSignals(True
,SIGPIPE
);
2326 if ((cli
= server_client()) && cli
->initialised
) {
2327 DEBUG(3,("lost connection to password server\n"));
2329 #ifndef DONT_REINSTALL_SIG
2330 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2332 BlockSignals(False
,SIGPIPE
);
2336 exit_server("Got sigpipe\n");
2340 /****************************************************************************
2341 open the socket communication
2342 ****************************************************************************/
2343 static BOOL
open_sockets(BOOL is_daemon
,int port
)
2350 struct sockaddr addr
;
2351 int in_addrlen
= sizeof(addr
);
2354 #ifdef SIGCLD_IGNORE
2355 signal(SIGCLD
, SIG_IGN
);
2357 signal(SIGCLD
, SIGNAL_CAST sig_cld
);
2360 /* open an incoming socket */
2361 s
= open_socket_in(SOCK_STREAM
, port
, 0,interpret_addr(lp_socket_address()));
2365 /* ready to listen */
2366 if (listen(s
, 5) == -1)
2368 DEBUG(0,("listen: %s\n",strerror(errno
)));
2376 /* now accept incoming connections - forking a new process
2377 for each incoming connection */
2378 DEBUG(2,("waiting for a connection\n"));
2381 Client
= accept(s
,&addr
,&in_addrlen
);
2383 if (Client
== -1 && errno
== EINTR
)
2388 DEBUG(0,("accept: %s\n",strerror(errno
)));
2392 #ifdef NO_FORK_DEBUG
2393 #ifndef NO_SIGNAL_TEST
2394 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2395 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2399 if (Client
!= -1 && fork()==0)
2401 /* Child code ... */
2402 #ifndef NO_SIGNAL_TEST
2403 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2404 signal(SIGCLD
, SIGNAL_CAST SIG_DFL
);
2406 /* close the listening socket */
2409 /* close our standard file descriptors */
2413 set_socket_options(Client
,"SO_KEEPALIVE");
2414 set_socket_options(Client
,user_socket_options
);
2416 /* Reset global variables in util.c so that
2417 client substitutions will be done correctly
2420 reset_globals_after_fork();
2423 close(Client
); /* The parent doesn't need this socket */
2429 /* We will abort gracefully when the client or remote system
2431 #ifndef NO_SIGNAL_TEST
2432 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
2436 /* close our standard file descriptors */
2439 set_socket_options(Client
,"SO_KEEPALIVE");
2440 set_socket_options(Client
,user_socket_options
);
2446 /****************************************************************************
2447 process an smb from the client - split out from the process() code so
2448 it can be used by the oplock break code.
2449 ****************************************************************************/
2451 static void process_smb(char *inbuf
, char *outbuf
)
2454 static int trans_num
;
2455 int msg_type
= CVAL(inbuf
,0);
2456 int32 len
= smb_len(inbuf
);
2457 int nread
= len
+ 4;
2459 if (trans_num
== 0) {
2460 /* on the first packet, check the global hosts allow/ hosts
2461 deny parameters before doing any parsing of the packet
2462 passed to us by the client. This prevents attacks on our
2463 parsing code from hosts not in the hosts allow list */
2464 if (!check_access(-1)) {
2465 /* send a negative session response "not listining on calling
2467 static unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
2468 DEBUG(1,("%s Connection denied from %s\n",
2469 timestring(),client_addr()));
2470 send_smb(Client
,(char *)buf
);
2471 exit_server("connection denied");
2475 DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type
,len
));
2476 DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num
,nread
));
2479 if(trans_num
== 1 && VT_Check(inbuf
))
2489 nread
= construct_reply(inbuf
,outbuf
,nread
,max_send
);
2493 if (CVAL(outbuf
,0) == 0)
2496 if (nread
!= smb_len(outbuf
) + 4)
2498 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
2499 nread
, smb_len(outbuf
)));
2502 send_smb(Client
,outbuf
);
2507 /****************************************************************************
2508 open the oplock IPC socket communication
2509 ****************************************************************************/
2510 static BOOL
open_oplock_ipc()
2512 struct sockaddr_in sock_name
;
2513 int len
= sizeof(sock_name
);
2515 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
2517 /* Open a lookback UDP socket on a random port. */
2518 oplock_sock
= open_socket_in(SOCK_DGRAM
, 0, 0, htonl(INADDR_LOOPBACK
));
2519 if (oplock_sock
== -1)
2521 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
2522 address %x. Error was %s\n", htonl(INADDR_LOOPBACK
), strerror(errno
)));
2527 /* Find out the transient UDP port we have been allocated. */
2528 if(getsockname(oplock_sock
, (struct sockaddr
*)&sock_name
, &len
)<0)
2530 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
2537 oplock_port
= ntohs(sock_name
.sin_port
);
2539 DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
2540 getpid(), oplock_port
));
2545 /****************************************************************************
2546 process an oplock break message.
2547 ****************************************************************************/
2548 static BOOL
process_local_message(int sock
, char *buffer
, int buf_size
)
2554 msg_len
= IVAL(buffer
,UDP_CMD_LEN_OFFSET
);
2555 from_port
= SVAL(buffer
,UDP_CMD_PORT_OFFSET
);
2557 msg_start
= &buffer
[UDP_CMD_HEADER_LEN
];
2559 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
2560 msg_len
, from_port
));
2562 /* Switch on message command - currently OPLOCK_BREAK_CMD is the
2563 only valid request. */
2565 switch(SVAL(msg_start
,UDP_MESSAGE_CMD_OFFSET
))
2567 case OPLOCK_BREAK_CMD
:
2568 /* Ensure that the msg length is correct. */
2569 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
2571 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
2572 should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
2576 uint32 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
2577 uint32 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
2578 uint32 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
2579 struct timeval tval
;
2580 struct sockaddr_in toaddr
;
2582 tval
.tv_sec
= IVAL(msg_start
, OPLOCK_BREAK_SEC_OFFSET
);
2583 tval
.tv_usec
= IVAL(msg_start
, OPLOCK_BREAK_USEC_OFFSET
);
2585 DEBUG(5,("process_local_message: oplock break request from \
2586 pid %d, port %d, dev = %x, inode = %x\n", remotepid
, from_port
, dev
, inode
));
2589 * If we have no record of any currently open oplocks,
2590 * it's not an error, as a close command may have
2591 * just been issued on the file that was oplocked.
2592 * Just return success in this case.
2595 if(global_oplocks_open
!= 0)
2597 if(oplock_break(dev
, inode
, &tval
) == False
)
2599 DEBUG(0,("process_local_message: oplock break failed - \
2600 not returning udp message.\n"));
2606 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
2607 oplocks. Returning success.\n"));
2610 /* Send the message back after OR'ing in the 'REPLY' bit. */
2611 SSVAL(msg_start
,UDP_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
| CMD_REPLY
);
2613 bzero((char *)&toaddr
,sizeof(toaddr
));
2614 toaddr
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2615 toaddr
.sin_port
= htons(from_port
);
2616 toaddr
.sin_family
= AF_INET
;
2618 if(sendto( sock
, msg_start
, OPLOCK_BREAK_MSG_LEN
, 0,
2619 (struct sockaddr
*)&toaddr
, sizeof(toaddr
)) < 0)
2621 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
2622 remotepid
, strerror(errno
)));
2626 DEBUG(5,("process_local_message: oplock break reply sent to \
2627 pid %d, port %d, for file dev = %x, inode = %x\n", remotepid
,
2628 from_port
, dev
, inode
));
2633 * Keep this as a debug case - eventually we can remove it.
2636 DEBUG(0,("process_local_message: Received unsolicited break \
2637 reply - dumping info.\n"));
2639 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
2641 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
2642 (was %d, should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
2647 uint32 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
2648 uint32 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
2649 uint32 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
2651 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
2652 pid %d, port %d, dev = %x, inode = %x\n", remotepid
, from_port
, dev
, inode
));
2658 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
2659 (unsigned int)SVAL(msg_start
,0)));
2665 /****************************************************************************
2666 Process an oplock break directly.
2667 ****************************************************************************/
2668 BOOL
oplock_break(uint32 dev
, uint32 inode
, struct timeval
*tval
)
2671 static char *inbuf
= NULL
;
2672 static char *outbuf
= NULL
;
2673 files_struct
*fsp
= NULL
;
2676 BOOL shutdown_server
= False
;
2678 DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \
2679 global_oplocks_open = %d\n", dev
, inode
, global_oplocks_open
));
2683 inbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
2685 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
2688 outbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
2689 if(outbuf
== NULL
) {
2690 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
2697 /* We need to search the file open table for the
2698 entry containing this dev and inode, and ensure
2699 we have an oplock on it. */
2700 for( fnum
= 0; fnum
< MAX_OPEN_FILES
; fnum
++)
2705 if((fsp
->fd_ptr
->dev
== dev
) && (fsp
->fd_ptr
->inode
== inode
) &&
2706 (fsp
->open_time
.tv_sec
== tval
->tv_sec
) &&
2707 (fsp
->open_time
.tv_usec
== tval
->tv_usec
))
2714 /* The file could have been closed in the meantime - return success. */
2715 DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
2716 allowing break to succeed.\n", dev
, inode
, fnum
));
2720 /* Ensure we have an oplock on the file */
2722 /* There is a potential race condition in that an oplock could
2723 have been broken due to another udp request, and yet there are
2724 still oplock break messages being sent in the udp message
2725 queue for this file. So return true if we don't have an oplock,
2726 as we may have just freed it.
2729 if(!fsp
->granted_oplock
)
2731 DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
2732 Allowing break to succeed regardless.\n", fsp
->name
, fnum
, dev
, inode
));
2736 /* Now comes the horrid part. We must send an oplock break to the client,
2737 and then process incoming messages until we get a close or oplock release.
2740 /* Prepare the SMBlockingX message. */
2741 bzero(outbuf
,smb_size
);
2742 set_message(outbuf
,8,0,True
);
2744 SCVAL(outbuf
,smb_com
,SMBlockingX
);
2745 SSVAL(outbuf
,smb_tid
,fsp
->cnum
);
2746 SSVAL(outbuf
,smb_pid
,0xFFFF);
2747 SSVAL(outbuf
,smb_uid
,0);
2748 SSVAL(outbuf
,smb_mid
,0xFFFF);
2749 SCVAL(outbuf
,smb_vwv0
,0xFF);
2750 SSVAL(outbuf
,smb_vwv2
,fnum
);
2751 SCVAL(outbuf
,smb_vwv3
,LOCKING_ANDX_OPLOCK_RELEASE
);
2752 /* Change this when we have level II oplocks. */
2753 SCVAL(outbuf
,smb_vwv3
+1,OPLOCKLEVEL_NONE
);
2755 send_smb(Client
, outbuf
);
2757 global_oplock_break
= True
;
2759 /* Process incoming messages. */
2761 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
2762 seconds we should just die.... */
2764 start_time
= time(NULL
);
2766 while(OPEN_FNUM(fnum
) && fsp
->granted_oplock
)
2768 if(receive_smb(Client
,inbuf
,OPLOCK_BREAK_TIMEOUT
* 1000) == False
)
2771 * Die if we got an error.
2774 if (smb_read_error
== READ_EOF
)
2775 DEBUG(0,("oplock_break: end of file from client\n"));
2777 if (smb_read_error
== READ_ERROR
)
2778 DEBUG(0,("oplock_break: receive_smb error (%s)\n",
2781 if (smb_read_error
== READ_TIMEOUT
)
2782 DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n",
2783 OPLOCK_BREAK_TIMEOUT
));
2785 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2786 inode = %x).\n", fsp
->name
, fnum
, dev
, inode
));
2787 shutdown_server
= True
;
2790 process_smb(inbuf
, outbuf
);
2792 /* We only need this in case a readraw crossed on the wire. */
2793 if(global_oplock_break
)
2794 global_oplock_break
= False
;
2797 * Die if we go over the time limit.
2800 if((time(NULL
) - start_time
) > OPLOCK_BREAK_TIMEOUT
)
2802 DEBUG(0,("oplock_break: no break received from client within \
2803 %d seconds.\n", OPLOCK_BREAK_TIMEOUT
));
2804 DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
2805 inode = %x).\n", fsp
->name
, fnum
, dev
, inode
));
2806 shutdown_server
= True
;
2812 * If the client did not respond we must die.
2817 DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n"));
2820 exit_server("oplock break failure");
2825 /* The lockingX reply will have removed the oplock flag
2826 from the sharemode. */
2828 fsp
->granted_oplock
= False
;
2831 global_oplocks_open
--;
2833 /* Santity check - remove this later. JRA */
2834 if(global_oplocks_open
< 0)
2836 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
2837 global_oplocks_open
));
2838 exit_server("oplock_break: global_oplocks_open < 0");
2841 DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
2842 global_oplocks_open = %d\n", fnum
, dev
, inode
, global_oplocks_open
));
2847 /****************************************************************************
2848 Send an oplock break message to another smbd process. If the oplock is held
2849 by the local smbd then call the oplock break function directly.
2850 ****************************************************************************/
2852 BOOL
request_oplock_break(share_mode_entry
*share_entry
,
2853 uint32 dev
, uint32 inode
)
2855 char op_break_msg
[OPLOCK_BREAK_MSG_LEN
];
2856 struct sockaddr_in addr_out
;
2859 if(pid
== share_entry
->pid
)
2861 /* We are breaking our own oplock, make sure it's us. */
2862 if(share_entry
->op_port
!= oplock_port
)
2864 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
2865 should be %d\n", pid
, share_entry
->op_port
, oplock_port
));
2869 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
2871 /* Call oplock break direct. */
2872 return oplock_break(dev
, inode
, &share_entry
->time
);
2875 /* We need to send a OPLOCK_BREAK_CMD message to the
2876 port in the share mode entry. */
2878 SSVAL(op_break_msg
,UDP_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
);
2879 SIVAL(op_break_msg
,OPLOCK_BREAK_PID_OFFSET
,pid
);
2880 SIVAL(op_break_msg
,OPLOCK_BREAK_DEV_OFFSET
,dev
);
2881 SIVAL(op_break_msg
,OPLOCK_BREAK_INODE_OFFSET
,inode
);
2882 SIVAL(op_break_msg
,OPLOCK_BREAK_SEC_OFFSET
,(uint32
)share_entry
->time
.tv_sec
);
2883 SIVAL(op_break_msg
,OPLOCK_BREAK_USEC_OFFSET
,(uint32
)share_entry
->time
.tv_usec
);
2885 /* set the address and port */
2886 bzero((char *)&addr_out
,sizeof(addr_out
));
2887 addr_out
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2888 addr_out
.sin_port
= htons( share_entry
->op_port
);
2889 addr_out
.sin_family
= AF_INET
;
2891 DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \
2892 for dev = %x, inode = %x\n", share_entry
->pid
, share_entry
->op_port
, dev
, inode
));
2894 if(sendto(oplock_sock
,op_break_msg
,OPLOCK_BREAK_MSG_LEN
,0,
2895 (struct sockaddr
*)&addr_out
,sizeof(addr_out
)) < 0)
2897 DEBUG(0,("request_oplock_break: failed when sending a oplock break message \
2898 to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
2899 share_entry
->pid
, share_entry
->op_port
, dev
, inode
,
2905 * Now we must await the oplock broken message coming back
2906 * from the target smbd process. Timeout if it fails to
2907 * return in OPLOCK_BREAK_TIMEOUT seconds.
2908 * While we get messages that aren't ours, loop.
2913 char op_break_reply
[UDP_CMD_HEADER_LEN
+OPLOCK_BREAK_MSG_LEN
];
2914 int32 reply_msg_len
;
2915 int16 reply_from_port
;
2916 char *reply_msg_start
;
2918 if(receive_local_message(oplock_sock
, op_break_reply
, sizeof(op_break_reply
),
2919 OPLOCK_BREAK_TIMEOUT
* 1000) == False
)
2921 if(smb_read_error
== READ_TIMEOUT
)
2922 DEBUG(0,("request_oplock_break: no response received to oplock break request to \
2923 pid %d on port %d for dev = %x, inode = %x\n", share_entry
->pid
,
2924 share_entry
->op_port
, dev
, inode
));
2926 DEBUG(0,("request_oplock_break: error in response received to oplock break request to \
2927 pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry
->pid
,
2928 share_entry
->op_port
, dev
, inode
, strerror(errno
)));
2933 * If the response we got was not an answer to our message, but
2934 * was a completely different request, push it onto the pending
2935 * udp message stack so that we can deal with it in the main loop.
2936 * It may be another oplock break request to us.
2940 * Local note from JRA. There exists the possibility of a denial
2941 * of service attack here by allowing non-root processes running
2942 * on a local machine sending many of these pending messages to
2943 * a smbd port. Currently I'm not sure how to restrict the messages
2944 * I will queue (although I could add a limit to the queue) to
2945 * those received by root processes only. There should be a
2946 * way to make this bulletproof....
2949 reply_msg_len
= IVAL(op_break_reply
,UDP_CMD_LEN_OFFSET
);
2950 reply_from_port
= SVAL(op_break_reply
,UDP_CMD_PORT_OFFSET
);
2952 reply_msg_start
= &op_break_reply
[UDP_CMD_HEADER_LEN
];
2954 if(reply_msg_len
!= OPLOCK_BREAK_MSG_LEN
)
2957 DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n"));
2961 if(((SVAL(reply_msg_start
,UDP_MESSAGE_CMD_OFFSET
) & CMD_REPLY
) == 0) ||
2962 (reply_from_port
!= share_entry
->op_port
) ||
2963 (memcmp(&reply_msg_start
[OPLOCK_BREAK_PID_OFFSET
],
2964 &op_break_msg
[OPLOCK_BREAK_PID_OFFSET
],
2965 OPLOCK_BREAK_MSG_LEN
- OPLOCK_BREAK_PID_OFFSET
) != 0))
2967 DEBUG(3,("request_oplock_break: received other message whilst awaiting \
2968 oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
2969 share_entry
->pid
, share_entry
->op_port
, dev
, inode
));
2970 if(push_local_message(op_break_reply
, sizeof(op_break_reply
)) == False
)
2978 DEBUG(3,("request_oplock_break: broke oplock.\n"));
2983 /****************************************************************************
2984 check if a snum is in use
2985 ****************************************************************************/
2986 BOOL
snum_used(int snum
)
2989 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
2990 if (OPEN_CNUM(i
) && (SNUM(i
) == snum
))
2995 /****************************************************************************
2996 reload the services file
2997 **************************************************************************/
2998 BOOL
reload_services(BOOL test
)
3005 pstrcpy(fname
,lp_configfile());
3006 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
3008 pstrcpy(servicesf
,fname
);
3015 if (test
&& !lp_file_list_changed())
3018 lp_killunused(snum_used
);
3020 ret
= lp_load(servicesf
,False
);
3022 /* perhaps the config filename is now set */
3024 reload_services(True
);
3033 set_socket_options(Client
,"SO_KEEPALIVE");
3034 set_socket_options(Client
,user_socket_options
);
3038 create_mangled_stack(lp_mangledstack());
3040 /* this forces service parameters to be flushed */
3041 become_service(-1,True
);
3048 /****************************************************************************
3049 this prevents zombie child processes
3050 ****************************************************************************/
3051 static int sig_hup()
3053 BlockSignals(True
,SIGHUP
);
3054 DEBUG(0,("Got SIGHUP\n"));
3055 reload_services(False
);
3056 #ifndef DONT_REINSTALL_SIG
3057 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
3059 BlockSignals(False
,SIGHUP
);
3063 /****************************************************************************
3064 Setup the groups a user belongs to.
3065 ****************************************************************************/
3066 int setup_groups(char *user
, int uid
, int gid
, int *p_ngroups
,
3067 int **p_igroups
, gid_t
**p_groups
,
3070 if (-1 == initgroups(user
,gid
))
3074 DEBUG(0,("Unable to initgroups!\n"));
3075 if (gid
< 0 || gid
> 16000 || uid
< 0 || uid
> 16000)
3076 DEBUG(0,("This is probably a problem with the account %s\n",user
));
3085 ngroups
= getgroups(0,&grp
);
3088 igroups
= (int *)malloc(sizeof(int)*ngroups
);
3089 attrs
= (int *)malloc(sizeof(int)*ngroups
);
3090 for (i
=0;i
<ngroups
;i
++)
3092 attrs
[i
] = 0x7; /* XXXX don't know what NT user attributes are yet! */
3093 igroups
[i
] = 0x42424242;
3095 ngroups
= getgroups(ngroups
,(gid_t
*)igroups
);
3097 if (igroups
[0] == 0x42424242)
3100 *p_ngroups
= ngroups
;
3103 /* The following bit of code is very strange. It is due to the
3104 fact that some OSes use int* and some use gid_t* for
3105 getgroups, and some (like SunOS) use both, one in prototypes,
3106 and one in man pages and the actual code. Thus we detect it
3107 dynamically using some very ugly code */
3110 /* does getgroups return ints or gid_t ?? */
3111 static BOOL groups_use_ints
= True
;
3113 if (groups_use_ints
&&
3115 SVAL(igroups
,2) == 0x4242)
3116 groups_use_ints
= False
;
3118 for (i
=0;groups_use_ints
&& i
<ngroups
;i
++)
3119 if (igroups
[i
] == 0x42424242)
3120 groups_use_ints
= False
;
3122 if (groups_use_ints
)
3124 *p_igroups
= igroups
;
3125 *p_groups
= (gid_t
*)igroups
;
3129 gid_t
*groups
= (gid_t
*)igroups
;
3130 igroups
= (int *)malloc(sizeof(int)*ngroups
);
3131 for (i
=0;i
<ngroups
;i
++)
3133 igroups
[i
] = groups
[i
];
3135 *p_igroups
= igroups
;
3136 *p_groups
= (gid_t
*)groups
;
3139 DEBUG(3,("%s is in %d groups\n",user
,ngroups
));
3140 for (i
=0;i
<ngroups
;i
++)
3141 DEBUG(3,("%d ",igroups
[i
]));
3147 /****************************************************************************
3148 make a connection to a service
3149 ****************************************************************************/
3150 int make_connection(char *service
,char *user
,char *password
, int pwlen
, char *dev
,uint16 vuid
)
3154 struct passwd
*pass
= NULL
;
3155 connection_struct
*pcon
;
3158 static BOOL first_connection
= True
;
3162 snum
= find_service(service
);
3165 if (strequal(service
,"IPC$"))
3167 DEBUG(3,("%s refusing IPC connection\n",timestring()));
3171 DEBUG(0,("%s couldn't find service %s\n",timestring(),service
));
3175 if (strequal(service
,HOMES_NAME
))
3177 if (*user
&& Get_Pwnam(user
,True
))
3178 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
3180 if (validated_username(vuid
))
3182 strcpy(user
,validated_username(vuid
));
3183 return(make_connection(user
,user
,password
,pwlen
,dev
,vuid
));
3187 if (!lp_snum_ok(snum
) || !check_access(snum
)) {
3191 /* you can only connect to the IPC$ service as an ipc device */
3192 if (strequal(service
,"IPC$"))
3195 if (*dev
== '?' || !*dev
)
3197 if (lp_print_ok(snum
))
3198 strcpy(dev
,"LPT1:");
3203 /* if the request is as a printer and you can't print then refuse */
3205 if (!lp_print_ok(snum
) && (strncmp(dev
,"LPT",3) == 0)) {
3206 DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
3210 /* lowercase the user name */
3213 /* add it as a possible user name */
3214 add_session_user(service
);
3216 /* shall we let them in? */
3217 if (!authorise_login(snum
,user
,password
,pwlen
,&guest
,&force
,vuid
))
3219 DEBUG(2,("%s invalid username/password for %s\n",timestring(),service
));
3223 cnum
= find_free_connection(str_checksum(service
) + str_checksum(user
));
3226 DEBUG(0,("%s couldn't find free connection\n",timestring()));
3230 pcon
= &Connections
[cnum
];
3231 bzero((char *)pcon
,sizeof(*pcon
));
3233 /* find out some info about the user */
3234 pass
= Get_Pwnam(user
,True
);
3238 DEBUG(0,("%s couldn't find account %s\n",timestring(),user
));
3242 pcon
->read_only
= lp_readonly(snum
);
3246 StrnCpy(list
,lp_readlist(snum
),sizeof(pstring
)-1);
3247 string_sub(list
,"%S",service
);
3249 if (user_in_list(user
,list
))
3250 pcon
->read_only
= True
;
3252 StrnCpy(list
,lp_writelist(snum
),sizeof(pstring
)-1);
3253 string_sub(list
,"%S",service
);
3255 if (user_in_list(user
,list
))
3256 pcon
->read_only
= False
;
3259 /* admin user check */
3261 /* JRA - original code denied admin user if the share was
3262 marked read_only. Changed as I don't think this is needed,
3263 but old code left in case there is a problem here.
3265 if (user_in_list(user
,lp_admin_users(snum
))
3267 && !pcon
->read_only
)
3272 pcon
->admin_user
= True
;
3273 DEBUG(0,("%s logged in as admin user (root privileges)\n",user
));
3276 pcon
->admin_user
= False
;
3278 pcon
->force_user
= force
;
3280 pcon
->uid
= pass
->pw_uid
;
3281 pcon
->gid
= pass
->pw_gid
;
3282 pcon
->num_files_open
= 0;
3283 pcon
->lastused
= time(NULL
);
3284 pcon
->service
= snum
;
3286 pcon
->printer
= (strncmp(dev
,"LPT",3) == 0);
3287 pcon
->ipc
= (strncmp(dev
,"IPC",3) == 0);
3288 pcon
->dirptr
= NULL
;
3289 pcon
->veto_list
= NULL
;
3290 pcon
->hide_list
= NULL
;
3291 string_set(&pcon
->dirpath
,"");
3292 string_set(&pcon
->user
,user
);
3295 if (*lp_force_group(snum
))
3300 StrnCpy(gname
,lp_force_group(snum
),sizeof(pstring
)-1);
3301 /* default service may be a group name */
3302 string_sub(gname
,"%S",service
);
3303 gptr
= (struct group
*)getgrnam(gname
);
3307 pcon
->gid
= gptr
->gr_gid
;
3308 DEBUG(3,("Forced group %s\n",gname
));
3311 DEBUG(1,("Couldn't find group %s\n",gname
));
3315 if (*lp_force_user(snum
))
3317 struct passwd
*pass2
;
3319 fstrcpy(fuser
,lp_force_user(snum
));
3320 pass2
= (struct passwd
*)Get_Pwnam(fuser
,True
);
3323 pcon
->uid
= pass2
->pw_uid
;
3324 string_set(&pcon
->user
,fuser
);
3325 fstrcpy(user
,fuser
);
3326 pcon
->force_user
= True
;
3327 DEBUG(3,("Forced user %s\n",fuser
));
3330 DEBUG(1,("Couldn't find user %s\n",fuser
));
3335 pstrcpy(s
,lp_pathname(snum
));
3336 standard_sub(cnum
,s
);
3337 string_set(&pcon
->connectpath
,s
);
3338 DEBUG(3,("Connect path is %s\n",s
));
3341 /* groups stuff added by ih */
3343 pcon
->igroups
= NULL
;
3344 pcon
->groups
= NULL
;
3349 /* Find all the groups this uid is in and store them. Used by become_user() */
3350 setup_groups(pcon
->user
,pcon
->uid
,pcon
->gid
,
3351 &pcon
->ngroups
,&pcon
->igroups
,&pcon
->groups
,&pcon
->attrs
);
3353 /* check number of connections */
3354 if (!claim_connection(cnum
,
3355 lp_servicename(SNUM(cnum
)),
3356 lp_max_connections(SNUM(cnum
)),False
))
3358 DEBUG(1,("too many connections - rejected\n"));
3362 if (lp_status(SNUM(cnum
)))
3363 claim_connection(cnum
,"STATUS.",MAXSTATUS
,first_connection
);
3365 first_connection
= False
;
3370 /* execute any "root preexec = " line */
3371 if (*lp_rootpreexec(SNUM(cnum
)))
3374 pstrcpy(cmd
,lp_rootpreexec(SNUM(cnum
)));
3375 standard_sub(cnum
,cmd
);
3376 DEBUG(5,("cmd=%s\n",cmd
));
3377 smbrun(cmd
,NULL
,False
);
3380 if (!become_user(cnum
,pcon
->vuid
))
3382 DEBUG(0,("Can't become connected user!\n"));
3384 if (!IS_IPC(cnum
)) {
3385 yield_connection(cnum
,
3386 lp_servicename(SNUM(cnum
)),
3387 lp_max_connections(SNUM(cnum
)));
3388 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3393 if (ChDir(pcon
->connectpath
) != 0)
3395 DEBUG(0,("Can't change directory to %s (%s)\n",
3396 pcon
->connectpath
,strerror(errno
)));
3399 if (!IS_IPC(cnum
)) {
3400 yield_connection(cnum
,
3401 lp_servicename(SNUM(cnum
)),
3402 lp_max_connections(SNUM(cnum
)));
3403 if (lp_status(SNUM(cnum
))) yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3408 string_set(&pcon
->origpath
,pcon
->connectpath
);
3410 #if SOFTLINK_OPTIMISATION
3411 /* resolve any soft links early */
3414 pstrcpy(s
,pcon
->connectpath
);
3416 string_set(&pcon
->connectpath
,s
);
3417 ChDir(pcon
->connectpath
);
3421 num_connections_open
++;
3422 add_session_user(user
);
3424 /* execute any "preexec = " line */
3425 if (*lp_preexec(SNUM(cnum
)))
3428 pstrcpy(cmd
,lp_preexec(SNUM(cnum
)));
3429 standard_sub(cnum
,cmd
);
3430 smbrun(cmd
,NULL
,False
);
3433 /* we've finished with the sensitive stuff */
3436 /* Add veto/hide lists */
3437 if (!IS_IPC(cnum
) && !IS_PRINT(cnum
))
3439 set_namearray( &pcon
->veto_list
, lp_veto_files(SNUM(cnum
)));
3440 set_namearray( &pcon
->hide_list
, lp_hide_files(SNUM(cnum
)));
3444 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
3448 lp_servicename(SNUM(cnum
)),user
,
3458 /****************************************************************************
3459 find first available file slot
3460 ****************************************************************************/
3461 int find_free_file(void )
3464 /* we start at 1 here for an obscure reason I can't now remember,
3465 but I think is important :-) */
3466 for (i
=1;i
<MAX_OPEN_FILES
;i
++)
3469 DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
3473 /****************************************************************************
3474 find first available connection slot, starting from a random position.
3475 The randomisation stops problems with the server dieing and clients
3476 thinking the server is still available.
3477 ****************************************************************************/
3478 static int find_free_connection(int hash
)
3482 hash
= (hash
% (MAX_CONNECTIONS
-2))+1;
3486 for (i
=hash
+1;i
!=hash
;)
3488 if (!Connections
[i
].open
&& Connections
[i
].used
== used
)
3490 DEBUG(3,("found free connection number %d\n",i
));
3494 if (i
== MAX_CONNECTIONS
)
3504 DEBUG(1,("ERROR! Out of connection structures\n"));
3509 /****************************************************************************
3510 reply for the core protocol
3511 ****************************************************************************/
3512 int reply_corep(char *outbuf
)
3514 int outsize
= set_message(outbuf
,1,0,True
);
3516 Protocol
= PROTOCOL_CORE
;
3522 /****************************************************************************
3523 reply for the coreplus protocol
3524 ****************************************************************************/
3525 int reply_coreplus(char *outbuf
)
3527 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3528 int outsize
= set_message(outbuf
,13,0,True
);
3529 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
3530 readbraw and writebraw (possibly) */
3531 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3532 SSVAL(outbuf
,smb_vwv1
,0x1); /* user level security, don't encrypt */
3534 Protocol
= PROTOCOL_COREPLUS
;
3540 /****************************************************************************
3541 reply for the lanman 1.0 protocol
3542 ****************************************************************************/
3543 int reply_lanman1(char *outbuf
)
3545 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3547 BOOL doencrypt
= SMBENCRYPT();
3548 time_t t
= time(NULL
);
3549 /* We need to save and restore this as it can be destroyed
3550 if we call another server if security=server
3551 Thanks to Paul Nelson @ Thursby for pointing this out.
3553 uint16 mid
= SVAL(outbuf
, smb_mid
);
3555 if (lp_security()>=SEC_USER
) secword
|= 1;
3556 if (doencrypt
) secword
|= 2;
3558 set_message(outbuf
,13,doencrypt
?8:0,True
);
3559 SSVAL(outbuf
,smb_vwv1
,secword
);
3560 /* Create a token value and add it to the outgoing packet. */
3562 generate_next_challenge(smb_buf(outbuf
));
3564 Protocol
= PROTOCOL_LANMAN1
;
3566 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3567 SSVAL(outbuf
,smb_mid
,mid
); /* Restore possibly corrupted mid */
3568 SSVAL(outbuf
,smb_vwv2
,max_recv
);
3569 SSVAL(outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
3570 SSVAL(outbuf
,smb_vwv4
,1);
3571 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
3572 readbraw writebraw (possibly) */
3573 SIVAL(outbuf
,smb_vwv6
,getpid());
3574 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
3576 put_dos_date(outbuf
,smb_vwv8
,t
);
3578 return (smb_len(outbuf
)+4);
3582 /****************************************************************************
3583 reply for the lanman 2.0 protocol
3584 ****************************************************************************/
3585 int reply_lanman2(char *outbuf
)
3587 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
3589 BOOL doencrypt
= SMBENCRYPT();
3590 time_t t
= time(NULL
);
3591 struct cli_state
*cli
= NULL
;
3595 if (lp_security() == SEC_SERVER
) {
3596 cli
= server_cryptkey();
3600 DEBUG(3,("using password server validation\n"));
3601 doencrypt
= ((cli
->sec_mode
& 2) != 0);
3604 if (lp_security()>=SEC_USER
) secword
|= 1;
3605 if (doencrypt
) secword
|= 2;
3610 generate_next_challenge(cryptkey
);
3612 memcpy(cryptkey
, cli
->cryptkey
, 8);
3613 set_challenge(cli
->cryptkey
);
3617 set_message(outbuf
,13,crypt_len
,True
);
3618 SSVAL(outbuf
,smb_vwv1
,secword
);
3620 memcpy(smb_buf(outbuf
), cryptkey
, 8);
3622 SIVAL(outbuf
,smb_vwv6
,getpid());
3624 Protocol
= PROTOCOL_LANMAN2
;
3626 CVAL(outbuf
,smb_flg
) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
3627 SSVAL(outbuf
,smb_vwv2
,max_recv
);
3628 SSVAL(outbuf
,smb_vwv3
,lp_maxmux());
3629 SSVAL(outbuf
,smb_vwv4
,1);
3630 SSVAL(outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
3631 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
3632 put_dos_date(outbuf
,smb_vwv8
,t
);
3634 return (smb_len(outbuf
)+4);
3638 /****************************************************************************
3639 reply for the nt protocol
3640 ****************************************************************************/
3641 int reply_nt1(char *outbuf
)
3643 /* dual names + lock_and_read + nt SMBs + remote API calls */
3644 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
;
3646 other valid capabilities which we may support at some time...
3647 CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
3648 CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
3652 BOOL doencrypt
= SMBENCRYPT();
3653 time_t t
= time(NULL
);
3655 struct cli_state
*cli
= NULL
;
3659 if (lp_security() == SEC_SERVER
) {
3660 cli
= server_cryptkey();
3664 DEBUG(3,("using password server validation\n"));
3665 doencrypt
= ((cli
->sec_mode
& 2) != 0);
3671 generate_next_challenge(cryptkey
);
3673 memcpy(cryptkey
, cli
->cryptkey
, 8);
3674 set_challenge(cli
->cryptkey
);
3678 if (lp_readraw() && lp_writeraw()) {
3679 capabilities
|= CAP_RAW_MODE
;
3682 if (lp_security() >= SEC_USER
) secword
|= 1;
3683 if (doencrypt
) secword
|= 2;
3685 /* decide where (if) to put the encryption challenge, and
3686 follow it with the OEM'd domain name
3688 data_len
= crypt_len
+ strlen(myworkgroup
) + 1;
3690 set_message(outbuf
,17,data_len
,True
);
3691 strcpy(smb_buf(outbuf
)+crypt_len
, myworkgroup
);
3693 CVAL(outbuf
,smb_vwv1
) = secword
;
3694 SSVALS(outbuf
,smb_vwv16
+1,crypt_len
);
3696 memcpy(smb_buf(outbuf
), cryptkey
, 8);
3698 Protocol
= PROTOCOL_NT1
;
3700 SSVAL(outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
3701 SSVAL(outbuf
,smb_vwv2
+1,1); /* num vcs */
3702 SIVAL(outbuf
,smb_vwv3
+1,0xffff); /* max buffer. LOTS! */
3703 SIVAL(outbuf
,smb_vwv5
+1,0xffff); /* raw size. LOTS! */
3704 SIVAL(outbuf
,smb_vwv7
+1,getpid()); /* session key */
3705 SIVAL(outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
3706 put_long_date(outbuf
+smb_vwv11
+1,t
);
3707 SSVALS(outbuf
,smb_vwv15
+1,TimeDiff(t
)/60);
3708 SSVAL(outbuf
,smb_vwv17
,data_len
); /* length of challenge+domain strings */
3710 return (smb_len(outbuf
)+4);
3713 /* these are the protocol lists used for auto architecture detection:
3716 protocol [PC NETWORK PROGRAM 1.0]
3717 protocol [XENIX CORE]
3718 protocol [MICROSOFT NETWORKS 1.03]
3719 protocol [LANMAN1.0]
3720 protocol [Windows for Workgroups 3.1a]
3721 protocol [LM1.2X002]
3722 protocol [LANMAN2.1]
3723 protocol [NT LM 0.12]
3726 protocol [PC NETWORK PROGRAM 1.0]
3727 protocol [XENIX CORE]
3728 protocol [MICROSOFT NETWORKS 1.03]
3729 protocol [LANMAN1.0]
3730 protocol [Windows for Workgroups 3.1a]
3731 protocol [LM1.2X002]
3732 protocol [LANMAN2.1]
3733 protocol [NT LM 0.12]
3736 protocol [PC NETWORK PROGRAM 1.0]
3737 protocol [XENIX CORE]
3738 protocol [LANMAN1.0]
3739 protocol [LM1.2X002]
3740 protocol [LANMAN2.1]
3744 * Modified to recognize the architecture of the remote machine better.
3746 * This appears to be the matrix of which protocol is used by which
3748 Protocol WfWg Win95 WinNT OS/2
3749 PC NETWORK PROGRAM 1.0 1 1 1 1
3751 MICROSOFT NETWORKS 3.0 2 2
3753 MICROSOFT NETWORKS 1.03 3
3756 Windows for Workgroups 3.1a 5 5 5
3761 * tim@fsg.com 09/29/95
3764 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
3765 #define ARCH_WIN95 0x2
3766 #define ARCH_OS2 0xC /* Again OS/2 is like NT */
3767 #define ARCH_WINNT 0x8
3768 #define ARCH_SAMBA 0x10
3770 #define ARCH_ALL 0x1F
3772 /* List of supported protocols, most desired first */
3776 int (*proto_reply_fn
)(char *);
3778 } supported_protocols
[] = {
3779 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
3780 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
3781 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3782 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3783 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
3784 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
3785 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
3786 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
3787 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
3792 /****************************************************************************
3794 ****************************************************************************/
3795 static int reply_negprot(char *inbuf
,char *outbuf
)
3797 int outsize
= set_message(outbuf
,1,0,True
);
3802 int bcc
= SVAL(smb_buf(inbuf
),-2);
3803 int arch
= ARCH_ALL
;
3805 p
= smb_buf(inbuf
)+1;
3806 while (p
< (smb_buf(inbuf
) + bcc
))
3809 DEBUG(3,("Requested protocol [%s]\n",p
));
3810 if (strcsequal(p
,"Windows for Workgroups 3.1a"))
3811 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
);
3812 else if (strcsequal(p
,"DOS LM1.2X002"))
3813 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
3814 else if (strcsequal(p
,"DOS LANMAN2.1"))
3815 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
3816 else if (strcsequal(p
,"NT LM 0.12"))
3817 arch
&= ( ARCH_WIN95
| ARCH_WINNT
);
3818 else if (strcsequal(p
,"LANMAN2.1"))
3819 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3820 else if (strcsequal(p
,"LM1.2X002"))
3821 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3822 else if (strcsequal(p
,"MICROSOFT NETWORKS 1.03"))
3824 else if (strcsequal(p
,"XENIX CORE"))
3825 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
3826 else if (strcsequal(p
,"Samba")) {
3836 set_remote_arch(RA_SAMBA
);
3839 set_remote_arch(RA_WFWG
);
3842 set_remote_arch(RA_WIN95
);
3845 set_remote_arch(RA_WINNT
);
3848 set_remote_arch(RA_OS2
);
3851 set_remote_arch(RA_UNKNOWN
);
3855 /* possibly reload - change of architecture */
3856 reload_services(True
);
3858 /* a special case to stop password server loops */
3859 if (Index
== 1 && strequal(remote_machine
,myhostname
) &&
3860 lp_security()==SEC_SERVER
)
3861 exit_server("Password server loop!");
3863 /* Check for protocols, most desirable first */
3864 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++)
3866 p
= smb_buf(inbuf
)+1;
3868 if (lp_maxprotocol() >= supported_protocols
[protocol
].protocol_level
)
3869 while (p
< (smb_buf(inbuf
) + bcc
))
3871 if (strequal(p
,supported_protocols
[protocol
].proto_name
))
3880 SSVAL(outbuf
,smb_vwv0
,choice
);
3882 extern fstring remote_proto
;
3883 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
3884 reload_services(True
);
3885 outsize
= supported_protocols
[protocol
].proto_reply_fn(outbuf
);
3886 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
3889 DEBUG(0,("No protocol supported !\n"));
3891 SSVAL(outbuf
,smb_vwv0
,choice
);
3893 DEBUG(5,("%s negprot index=%d\n",timestring(),choice
));
3899 /****************************************************************************
3900 close all open files for a connection
3901 ****************************************************************************/
3902 static void close_open_files(int cnum
)
3905 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
3906 if( Files
[i
].cnum
== cnum
&& Files
[i
].open
) {
3907 close_file(i
,False
);
3913 /****************************************************************************
3915 ****************************************************************************/
3916 void close_cnum(int cnum
, uint16 vuid
)
3918 DirCacheFlush(SNUM(cnum
));
3922 if (!OPEN_CNUM(cnum
))
3924 DEBUG(0,("Can't close cnum %d\n",cnum
));
3928 DEBUG(IS_IPC(cnum
)?3:1,("%s %s (%s) closed connection to service %s\n",
3930 remote_machine
,client_addr(),
3931 lp_servicename(SNUM(cnum
))));
3933 yield_connection(cnum
,
3934 lp_servicename(SNUM(cnum
)),
3935 lp_max_connections(SNUM(cnum
)));
3937 if (lp_status(SNUM(cnum
)))
3938 yield_connection(cnum
,"STATUS.",MAXSTATUS
);
3940 close_open_files(cnum
);
3941 dptr_closecnum(cnum
);
3943 /* execute any "postexec = " line */
3944 if (*lp_postexec(SNUM(cnum
)) && become_user(cnum
,vuid
))
3947 strcpy(cmd
,lp_postexec(SNUM(cnum
)));
3948 standard_sub(cnum
,cmd
);
3949 smbrun(cmd
,NULL
,False
);
3954 /* execute any "root postexec = " line */
3955 if (*lp_rootpostexec(SNUM(cnum
)))
3958 strcpy(cmd
,lp_rootpostexec(SNUM(cnum
)));
3959 standard_sub(cnum
,cmd
);
3960 smbrun(cmd
,NULL
,False
);
3963 Connections
[cnum
].open
= False
;
3964 num_connections_open
--;
3965 if (Connections
[cnum
].ngroups
&& Connections
[cnum
].groups
)
3967 if (Connections
[cnum
].igroups
!= (int *)Connections
[cnum
].groups
)
3968 free(Connections
[cnum
].groups
);
3969 free(Connections
[cnum
].igroups
);
3970 Connections
[cnum
].groups
= NULL
;
3971 Connections
[cnum
].igroups
= NULL
;
3972 Connections
[cnum
].ngroups
= 0;
3975 free_namearray(Connections
[cnum
].veto_list
);
3976 free_namearray(Connections
[cnum
].hide_list
);
3978 string_set(&Connections
[cnum
].user
,"");
3979 string_set(&Connections
[cnum
].dirpath
,"");
3980 string_set(&Connections
[cnum
].connectpath
,"");
3984 /****************************************************************************
3985 simple routines to do connection counting
3986 ****************************************************************************/
3987 BOOL
yield_connection(int cnum
,char *name
,int max_connections
)
3989 struct connect_record crec
;
3992 int mypid
= getpid();
3995 DEBUG(3,("Yielding connection to %d %s\n",cnum
,name
));
3997 if (max_connections
<= 0)
4000 bzero(&crec
,sizeof(crec
));
4002 pstrcpy(fname
,lp_lockdir());
4003 standard_sub(cnum
,fname
);
4004 trim_string(fname
,"","/");
4008 strcat(fname
,".LCK");
4010 f
= fopen(fname
,"r+");
4013 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname
,strerror(errno
)));
4017 fseek(f
,0,SEEK_SET
);
4019 /* find a free spot */
4020 for (i
=0;i
<max_connections
;i
++)
4022 if (fread(&crec
,sizeof(crec
),1,f
) != 1)
4024 DEBUG(2,("Entry not found in lock file %s\n",fname
));
4028 if (crec
.pid
== mypid
&& crec
.cnum
== cnum
)
4032 if (crec
.pid
!= mypid
|| crec
.cnum
!= cnum
)
4035 DEBUG(2,("Entry not found in lock file %s\n",fname
));
4039 bzero((void *)&crec
,sizeof(crec
));
4041 /* remove our mark */
4042 if (fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
4043 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
4045 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname
,strerror(errno
)));
4050 DEBUG(3,("Yield successful\n"));
4057 /****************************************************************************
4058 simple routines to do connection counting
4059 ****************************************************************************/
4060 BOOL
claim_connection(int cnum
,char *name
,int max_connections
,BOOL Clear
)
4062 struct connect_record crec
;
4065 int snum
= SNUM(cnum
);
4069 if (max_connections
<= 0)
4072 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name
,max_connections
));
4074 pstrcpy(fname
,lp_lockdir());
4075 standard_sub(cnum
,fname
);
4076 trim_string(fname
,"","/");
4078 if (!directory_exist(fname
,NULL
))
4083 strcat(fname
,".LCK");
4085 if (!file_exist(fname
,NULL
))
4087 int oldmask
= umask(022);
4088 f
= fopen(fname
,"w");
4093 total_recs
= file_size(fname
) / sizeof(crec
);
4095 f
= fopen(fname
,"r+");
4099 DEBUG(1,("couldn't open lock file %s\n",fname
));
4103 /* find a free spot */
4104 for (i
=0;i
<max_connections
;i
++)
4107 if (i
>=total_recs
||
4108 fseek(f
,i
*sizeof(crec
),SEEK_SET
) != 0 ||
4109 fread(&crec
,sizeof(crec
),1,f
) != 1)
4111 if (foundi
< 0) foundi
= i
;
4115 if (Clear
&& crec
.pid
&& !process_exists(crec
.pid
))
4117 fseek(f
,i
*sizeof(crec
),SEEK_SET
);
4118 bzero((void *)&crec
,sizeof(crec
));
4119 fwrite(&crec
,sizeof(crec
),1,f
);
4120 if (foundi
< 0) foundi
= i
;
4123 if (foundi
< 0 && (!crec
.pid
|| !process_exists(crec
.pid
)))
4132 DEBUG(3,("no free locks in %s\n",fname
));
4137 /* fill in the crec */
4138 bzero((void *)&crec
,sizeof(crec
));
4139 crec
.magic
= 0x280267;
4140 crec
.pid
= getpid();
4142 crec
.uid
= Connections
[cnum
].uid
;
4143 crec
.gid
= Connections
[cnum
].gid
;
4144 StrnCpy(crec
.name
,lp_servicename(snum
),sizeof(crec
.name
)-1);
4145 crec
.start
= time(NULL
);
4147 StrnCpy(crec
.machine
,remote_machine
,sizeof(crec
.machine
)-1);
4148 StrnCpy(crec
.addr
,client_addr(),sizeof(crec
.addr
)-1);
4151 if (fseek(f
,foundi
*sizeof(crec
),SEEK_SET
) != 0 ||
4152 fwrite(&crec
,sizeof(crec
),1,f
) != 1)
4163 /*******************************************************************
4164 prepare to dump a core file - carefully!
4165 ********************************************************************/
4166 static BOOL
dump_core(void)
4170 pstrcpy(dname
,debugf
);
4171 if ((p
=strrchr(dname
,'/'))) *p
=0;
4172 strcat(dname
,"/corefiles");
4174 sys_chown(dname
,getuid(),getgid());
4176 if (chdir(dname
)) return(False
);
4179 #ifndef NO_GETRLIMIT
4183 getrlimit(RLIMIT_CORE
, &rlp
);
4184 rlp
.rlim_cur
= MAX(4*1024*1024,rlp
.rlim_cur
);
4185 setrlimit(RLIMIT_CORE
, &rlp
);
4186 getrlimit(RLIMIT_CORE
, &rlp
);
4187 DEBUG(3,("Core limits now %d %d\n",rlp
.rlim_cur
,rlp
.rlim_max
));
4193 DEBUG(0,("Dumping core in %s\n",dname
));
4198 /****************************************************************************
4200 ****************************************************************************/
4201 void exit_server(char *reason
)
4203 static int firsttime
=1;
4206 if (!firsttime
) exit(0);
4210 DEBUG(2,("Closing connections\n"));
4211 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4212 if (Connections
[i
].open
)
4213 close_cnum(i
,(uint16
)-1);
4215 if (dcelogin_atmost_once
)
4219 int oldlevel
= DEBUGLEVEL
;
4221 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message
)));
4223 show_msg(last_inbuf
);
4224 DEBUGLEVEL
= oldlevel
;
4225 DEBUG(0,("===============================================================\n"));
4227 if (dump_core()) return;
4233 DEBUG(3,("%s Server exit (%s)\n",timestring(),reason
?reason
:""));
4237 /****************************************************************************
4238 do some standard substitutions in a string
4239 ****************************************************************************/
4240 void standard_sub(int cnum
,char *str
)
4242 if (VALID_CNUM(cnum
)) {
4245 for ( s
=str
; (p
=strchr(s
, '%')) != NULL
; s
=p
) {
4247 case 'H' : if ((home
= get_home_dir(Connections
[cnum
].user
))!=NULL
)
4248 string_sub(p
,"%H",home
);
4252 case 'P' : string_sub(p
,"%P",Connections
[cnum
].connectpath
); break;
4253 case 'S' : string_sub(p
,"%S",lp_servicename(Connections
[cnum
].service
)); break;
4254 case 'g' : string_sub(p
,"%g",gidtoname(Connections
[cnum
].gid
)); break;
4255 case 'u' : string_sub(p
,"%u",Connections
[cnum
].user
); break;
4256 case '\0' : p
++; break; /* don't run off the end of the string */
4257 default : p
+=2; break;
4261 standard_sub_basic(str
);
4265 These flags determine some of the permissions required to do an operation
4267 Note that I don't set NEED_WRITE on some write operations because they
4268 are used by some brain-dead clients when printing, and I don't want to
4269 force write permissions on print services.
4271 #define AS_USER (1<<0)
4272 #define NEED_WRITE (1<<1)
4273 #define TIME_INIT (1<<2)
4274 #define CAN_IPC (1<<3)
4275 #define AS_GUEST (1<<5)
4279 define a list of possible SMB messages and their corresponding
4280 functions. Any message that has a NULL function is unimplemented -
4281 please feel free to contribute implementations!
4283 struct smb_message_struct
4297 {SMBnegprot
,"SMBnegprot",reply_negprot
,0},
4298 {SMBtcon
,"SMBtcon",reply_tcon
,0},
4299 {SMBtdis
,"SMBtdis",reply_tdis
,0},
4300 {SMBexit
,"SMBexit",reply_exit
,0},
4301 {SMBioctl
,"SMBioctl",reply_ioctl
,0},
4302 {SMBecho
,"SMBecho",reply_echo
,0},
4303 {SMBsesssetupX
,"SMBsesssetupX",reply_sesssetup_and_X
,0},
4304 {SMBtconX
,"SMBtconX",reply_tcon_and_X
,0},
4305 {SMBulogoffX
, "SMBulogoffX", reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
4306 {SMBgetatr
,"SMBgetatr",reply_getatr
,AS_USER
},
4307 {SMBsetatr
,"SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
4308 {SMBchkpth
,"SMBchkpth",reply_chkpth
,AS_USER
},
4309 {SMBsearch
,"SMBsearch",reply_search
,AS_USER
},
4310 {SMBopen
,"SMBopen",reply_open
,AS_USER
},
4312 /* note that SMBmknew and SMBcreate are deliberately overloaded */
4313 {SMBcreate
,"SMBcreate",reply_mknew
,AS_USER
},
4314 {SMBmknew
,"SMBmknew",reply_mknew
,AS_USER
},
4316 {SMBunlink
,"SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
4317 {SMBread
,"SMBread",reply_read
,AS_USER
},
4318 {SMBwrite
,"SMBwrite",reply_write
,AS_USER
},
4319 {SMBclose
,"SMBclose",reply_close
,AS_USER
| CAN_IPC
},
4320 {SMBmkdir
,"SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
4321 {SMBrmdir
,"SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
4322 {SMBdskattr
,"SMBdskattr",reply_dskattr
,AS_USER
},
4323 {SMBmv
,"SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
4325 /* this is a Pathworks specific call, allowing the
4326 changing of the root path */
4327 {pSETDIR
,"pSETDIR",reply_setdir
,AS_USER
},
4329 {SMBlseek
,"SMBlseek",reply_lseek
,AS_USER
},
4330 {SMBflush
,"SMBflush",reply_flush
,AS_USER
},
4331 {SMBctemp
,"SMBctemp",reply_ctemp
,AS_USER
},
4332 {SMBsplopen
,"SMBsplopen",reply_printopen
,AS_USER
},
4333 {SMBsplclose
,"SMBsplclose",reply_printclose
,AS_USER
},
4334 {SMBsplretq
,"SMBsplretq",reply_printqueue
,AS_USER
|AS_GUEST
},
4335 {SMBsplwr
,"SMBsplwr",reply_printwrite
,AS_USER
},
4336 {SMBlock
,"SMBlock",reply_lock
,AS_USER
},
4337 {SMBunlock
,"SMBunlock",reply_unlock
,AS_USER
},
4339 /* CORE+ PROTOCOL FOLLOWS */
4341 {SMBreadbraw
,"SMBreadbraw",reply_readbraw
,AS_USER
},
4342 {SMBwritebraw
,"SMBwritebraw",reply_writebraw
,AS_USER
},
4343 {SMBwriteclose
,"SMBwriteclose",reply_writeclose
,AS_USER
},
4344 {SMBlockread
,"SMBlockread",reply_lockread
,AS_USER
},
4345 {SMBwriteunlock
,"SMBwriteunlock",reply_writeunlock
,AS_USER
},
4347 /* LANMAN1.0 PROTOCOL FOLLOWS */
4349 {SMBreadBmpx
,"SMBreadBmpx",reply_readbmpx
,AS_USER
},
4350 {SMBreadBs
,"SMBreadBs",NULL
,AS_USER
},
4351 {SMBwriteBmpx
,"SMBwriteBmpx",reply_writebmpx
,AS_USER
},
4352 {SMBwriteBs
,"SMBwriteBs",reply_writebs
,AS_USER
},
4353 {SMBwritec
,"SMBwritec",NULL
,AS_USER
},
4354 {SMBsetattrE
,"SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
4355 {SMBgetattrE
,"SMBgetattrE",reply_getattrE
,AS_USER
},
4356 {SMBtrans
,"SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
4357 {SMBtranss
,"SMBtranss",NULL
,AS_USER
| CAN_IPC
},
4358 {SMBioctls
,"SMBioctls",NULL
,AS_USER
},
4359 {SMBcopy
,"SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
4360 {SMBmove
,"SMBmove",NULL
,AS_USER
| NEED_WRITE
},
4362 {SMBopenX
,"SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
4363 {SMBreadX
,"SMBreadX",reply_read_and_X
,AS_USER
},
4364 {SMBwriteX
,"SMBwriteX",reply_write_and_X
,AS_USER
},
4365 {SMBlockingX
,"SMBlockingX",reply_lockingX
,AS_USER
},
4367 {SMBffirst
,"SMBffirst",reply_search
,AS_USER
},
4368 {SMBfunique
,"SMBfunique",reply_search
,AS_USER
},
4369 {SMBfclose
,"SMBfclose",reply_fclose
,AS_USER
},
4371 /* LANMAN2.0 PROTOCOL FOLLOWS */
4372 {SMBfindnclose
, "SMBfindnclose", reply_findnclose
, AS_USER
},
4373 {SMBfindclose
, "SMBfindclose", reply_findclose
,AS_USER
},
4374 {SMBtrans2
, "SMBtrans2", reply_trans2
, AS_USER
},
4375 {SMBtranss2
, "SMBtranss2", reply_transs2
, AS_USER
},
4377 /* messaging routines */
4378 {SMBsends
,"SMBsends",reply_sends
,AS_GUEST
},
4379 {SMBsendstrt
,"SMBsendstrt",reply_sendstrt
,AS_GUEST
},
4380 {SMBsendend
,"SMBsendend",reply_sendend
,AS_GUEST
},
4381 {SMBsendtxt
,"SMBsendtxt",reply_sendtxt
,AS_GUEST
},
4383 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
4385 {SMBsendb
,"SMBsendb",NULL
,AS_GUEST
},
4386 {SMBfwdname
,"SMBfwdname",NULL
,AS_GUEST
},
4387 {SMBcancelf
,"SMBcancelf",NULL
,AS_GUEST
},
4388 {SMBgetmac
,"SMBgetmac",NULL
,AS_GUEST
}
4391 /****************************************************************************
4392 return a string containing the function name of a SMB command
4393 ****************************************************************************/
4394 char *smb_fn_name(int type
)
4396 static char *unknown_name
= "SMBunknown";
4397 static int num_smb_messages
=
4398 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
4401 for (match
=0;match
<num_smb_messages
;match
++)
4402 if (smb_messages
[match
].code
== type
)
4405 if (match
== num_smb_messages
)
4406 return(unknown_name
);
4408 return(smb_messages
[match
].name
);
4412 /****************************************************************************
4413 do a switch on the message type, and return the response size
4414 ****************************************************************************/
4415 static int switch_message(int type
,char *inbuf
,char *outbuf
,int size
,int bufsize
)
4419 static int num_smb_messages
=
4420 sizeof(smb_messages
) / sizeof(struct smb_message_struct
);
4424 struct timeval msg_start_time
;
4425 struct timeval msg_end_time
;
4426 static unsigned long total_time
= 0;
4428 GetTimeOfDay(&msg_start_time
);
4435 last_message
= type
;
4437 /* make sure this is an SMB packet */
4438 if (strncmp(smb_base(inbuf
),"\377SMB",4) != 0)
4440 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf
)));
4444 for (match
=0;match
<num_smb_messages
;match
++)
4445 if (smb_messages
[match
].code
== type
)
4448 if (match
== num_smb_messages
)
4450 DEBUG(0,("Unknown message type %d!\n",type
));
4451 outsize
= reply_unknown(inbuf
,outbuf
);
4455 DEBUG(3,("switch message %s (pid %d)\n",smb_messages
[match
].name
,pid
));
4456 if (smb_messages
[match
].fn
)
4458 int cnum
= SVAL(inbuf
,smb_tid
);
4459 int flags
= smb_messages
[match
].flags
;
4460 uint16 session_tag
= SVAL(inbuf
,smb_uid
);
4462 /* does this protocol need to be run as root? */
4463 if (!(flags
& AS_USER
))
4466 /* does this protocol need to be run as the connected user? */
4467 if ((flags
& AS_USER
) && !become_user(cnum
,session_tag
)) {
4468 if (flags
& AS_GUEST
)
4471 return(ERROR(ERRSRV
,ERRinvnid
));
4473 /* this code is to work around a bug is MS client 3 without
4474 introducing a security hole - it needs to be able to do
4475 print queue checks as guest if it isn't logged in properly */
4476 if (flags
& AS_USER
)
4479 /* does it need write permission? */
4480 if ((flags
& NEED_WRITE
) && !CAN_WRITE(cnum
))
4481 return(ERROR(ERRSRV
,ERRaccess
));
4483 /* ipc services are limited */
4484 if (IS_IPC(cnum
) && (flags
& AS_USER
) && !(flags
& CAN_IPC
))
4485 return(ERROR(ERRSRV
,ERRaccess
));
4487 /* load service specific parameters */
4488 if (OPEN_CNUM(cnum
) && !become_service(cnum
,(flags
& AS_USER
)?True
:False
))
4489 return(ERROR(ERRSRV
,ERRaccess
));
4491 /* does this protocol need to be run as guest? */
4492 if ((flags
& AS_GUEST
) && (!become_guest() || !check_access(-1)))
4493 return(ERROR(ERRSRV
,ERRaccess
));
4497 outsize
= smb_messages
[match
].fn(inbuf
,outbuf
,size
,bufsize
);
4501 outsize
= reply_unknown(inbuf
,outbuf
);
4506 GetTimeOfDay(&msg_end_time
);
4507 if (!(smb_messages
[match
].flags
& TIME_INIT
))
4509 smb_messages
[match
].time
= 0;
4510 smb_messages
[match
].flags
|= TIME_INIT
;
4513 unsigned long this_time
=
4514 (msg_end_time
.tv_sec
- msg_start_time
.tv_sec
)*1e6
+
4515 (msg_end_time
.tv_usec
- msg_start_time
.tv_usec
);
4516 smb_messages
[match
].time
+= this_time
;
4517 total_time
+= this_time
;
4519 DEBUG(2,("TIME %s %d usecs %g pct\n",
4520 smb_fn_name(type
),smb_messages
[match
].time
,
4521 (100.0*smb_messages
[match
].time
) / total_time
));
4528 /****************************************************************************
4529 construct a chained reply and add it to the already made reply
4530 **************************************************************************/
4531 int chain_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
4533 static char *orig_inbuf
;
4534 static char *orig_outbuf
;
4535 int smb_com1
, smb_com2
= CVAL(inbuf
,smb_vwv0
);
4536 unsigned smb_off2
= SVAL(inbuf
,smb_vwv1
);
4537 char *inbuf2
, *outbuf2
;
4539 char inbuf_saved
[smb_wct
];
4540 char outbuf_saved
[smb_wct
];
4541 extern int chain_size
;
4542 int wct
= CVAL(outbuf
,smb_wct
);
4543 int outsize
= smb_size
+ 2*wct
+ SVAL(outbuf
,smb_vwv0
+2*wct
);
4545 /* maybe its not chained */
4546 if (smb_com2
== 0xFF) {
4547 CVAL(outbuf
,smb_vwv0
) = 0xFF;
4551 if (chain_size
== 0) {
4552 /* this is the first part of the chain */
4554 orig_outbuf
= outbuf
;
4557 /* we need to tell the client where the next part of the reply will be */
4558 SSVAL(outbuf
,smb_vwv1
,smb_offset(outbuf
+outsize
,outbuf
));
4559 CVAL(outbuf
,smb_vwv0
) = smb_com2
;
4561 /* remember how much the caller added to the chain, only counting stuff
4562 after the parameter words */
4563 chain_size
+= outsize
- smb_wct
;
4565 /* work out pointers into the original packets. The
4566 headers on these need to be filled in */
4567 inbuf2
= orig_inbuf
+ smb_off2
+ 4 - smb_wct
;
4568 outbuf2
= orig_outbuf
+ SVAL(outbuf
,smb_vwv1
) + 4 - smb_wct
;
4570 /* remember the original command type */
4571 smb_com1
= CVAL(orig_inbuf
,smb_com
);
4573 /* save the data which will be overwritten by the new headers */
4574 memcpy(inbuf_saved
,inbuf2
,smb_wct
);
4575 memcpy(outbuf_saved
,outbuf2
,smb_wct
);
4577 /* give the new packet the same header as the last part of the SMB */
4578 memmove(inbuf2
,inbuf
,smb_wct
);
4580 /* create the in buffer */
4581 CVAL(inbuf2
,smb_com
) = smb_com2
;
4583 /* create the out buffer */
4584 bzero(outbuf2
,smb_size
);
4585 set_message(outbuf2
,0,0,True
);
4586 CVAL(outbuf2
,smb_com
) = CVAL(inbuf2
,smb_com
);
4588 memcpy(outbuf2
+4,inbuf2
+4,4);
4589 CVAL(outbuf2
,smb_rcls
) = SUCCESS
;
4590 CVAL(outbuf2
,smb_reh
) = 0;
4591 CVAL(outbuf2
,smb_flg
) = 0x80 | (CVAL(inbuf2
,smb_flg
) & 0x8); /* bit 7 set
4593 SSVAL(outbuf2
,smb_flg2
,1); /* say we support long filenames */
4594 SSVAL(outbuf2
,smb_err
,SUCCESS
);
4595 SSVAL(outbuf2
,smb_tid
,SVAL(inbuf2
,smb_tid
));
4596 SSVAL(outbuf2
,smb_pid
,SVAL(inbuf2
,smb_pid
));
4597 SSVAL(outbuf2
,smb_uid
,SVAL(inbuf2
,smb_uid
));
4598 SSVAL(outbuf2
,smb_mid
,SVAL(inbuf2
,smb_mid
));
4600 DEBUG(3,("Chained message\n"));
4603 /* process the request */
4604 outsize2
= switch_message(smb_com2
,inbuf2
,outbuf2
,size
-chain_size
,
4605 bufsize
-chain_size
);
4607 /* copy the new reply and request headers over the old ones, but
4608 preserve the smb_com field */
4609 memmove(orig_outbuf
,outbuf2
,smb_wct
);
4610 CVAL(orig_outbuf
,smb_com
) = smb_com1
;
4612 /* restore the saved data, being careful not to overwrite any
4613 data from the reply header */
4614 memcpy(inbuf2
,inbuf_saved
,smb_wct
);
4616 int ofs
= smb_wct
- PTR_DIFF(outbuf2
,orig_outbuf
);
4617 if (ofs
< 0) ofs
= 0;
4618 memmove(outbuf2
+ofs
,outbuf_saved
+ofs
,smb_wct
-ofs
);
4626 /****************************************************************************
4627 construct a reply to the incoming packet
4628 ****************************************************************************/
4629 int construct_reply(char *inbuf
,char *outbuf
,int size
,int bufsize
)
4631 int type
= CVAL(inbuf
,smb_com
);
4633 int msg_type
= CVAL(inbuf
,0);
4634 extern int chain_size
;
4636 smb_last_time
= time(NULL
);
4641 bzero(outbuf
,smb_size
);
4644 return(reply_special(inbuf
,outbuf
));
4646 CVAL(outbuf
,smb_com
) = CVAL(inbuf
,smb_com
);
4647 set_message(outbuf
,0,0,True
);
4649 memcpy(outbuf
+4,inbuf
+4,4);
4650 CVAL(outbuf
,smb_rcls
) = SUCCESS
;
4651 CVAL(outbuf
,smb_reh
) = 0;
4652 CVAL(outbuf
,smb_flg
) = 0x80 | (CVAL(inbuf
,smb_flg
) & 0x8); /* bit 7 set
4654 SSVAL(outbuf
,smb_flg2
,1); /* say we support long filenames */
4655 SSVAL(outbuf
,smb_err
,SUCCESS
);
4656 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
4657 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
4658 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
4659 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
4661 outsize
= switch_message(type
,inbuf
,outbuf
,size
,bufsize
);
4663 outsize
+= chain_size
;
4666 smb_setlen(outbuf
,outsize
- 4);
4670 /****************************************************************************
4671 process commands from the client
4672 ****************************************************************************/
4673 static void process(void)
4677 InBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
4678 OutBuffer
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
);
4679 if ((InBuffer
== NULL
) || (OutBuffer
== NULL
))
4682 InBuffer
+= SMB_ALIGNMENT
;
4683 OutBuffer
+= SMB_ALIGNMENT
;
4686 DEBUG(3,("priming nmbd\n"));
4689 ip
= *interpret_addr2("localhost");
4690 if (zero_ip(ip
)) ip
= *interpret_addr2("127.0.0.1");
4692 send_one_packet(OutBuffer
,1,ip
,NMB_PORT
,SOCK_DGRAM
);
4698 int deadtime
= lp_deadtime()*60;
4700 int last_keepalive
=0;
4701 int service_load_counter
= 0;
4702 BOOL got_smb
= False
;
4705 deadtime
= DEFAULT_SMBD_TIMEOUT
;
4707 if (lp_readprediction())
4708 do_read_prediction();
4712 for (counter
=SMBD_SELECT_LOOP
;
4713 !receive_message_or_smb(Client
,oplock_sock
,
4714 InBuffer
,BUFFER_SIZE
,SMBD_SELECT_LOOP
*1000,&got_smb
);
4715 counter
+= SMBD_SELECT_LOOP
)
4719 BOOL allidle
= True
;
4720 extern int keepalive
;
4722 if (counter
> 365 * 3600) /* big number of seconds. */
4725 service_load_counter
= 0;
4728 if (smb_read_error
== READ_EOF
)
4730 DEBUG(3,("end of file from client\n"));
4734 if (smb_read_error
== READ_ERROR
)
4736 DEBUG(3,("receive_smb error (%s) exiting\n",
4743 /* become root again if waiting */
4746 /* check for smb.conf reload */
4747 if (counter
>= service_load_counter
+ SMBD_RELOAD_CHECK
)
4749 service_load_counter
= counter
;
4751 /* reload services, if files have changed. */
4752 reload_services(True
);
4755 /* automatic timeout if all connections are closed */
4756 if (num_connections_open
==0 && counter
>= IDLE_CLOSED_TIMEOUT
)
4758 DEBUG(2,("%s Closing idle connection\n",timestring()));
4762 if (keepalive
&& (counter
-last_keepalive
)>keepalive
)
4764 struct cli_state
*cli
= server_client();
4765 if (!send_keepalive(Client
)) {
4766 DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
4769 /* also send a keepalive to the password server if its still
4771 if (cli
&& cli
->initialised
)
4772 send_keepalive(cli
->fd
);
4773 last_keepalive
= counter
;
4776 /* check for connection timeouts */
4777 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4778 if (Connections
[i
].open
)
4780 /* close dirptrs on connections that are idle */
4781 if ((t
-Connections
[i
].lastused
)>DPTR_IDLE_TIMEOUT
)
4784 if (Connections
[i
].num_files_open
> 0 ||
4785 (t
-Connections
[i
].lastused
)<deadtime
)
4789 if (allidle
&& num_connections_open
>0)
4791 DEBUG(2,("%s Closing idle connection 2\n",timestring()));
4797 process_smb(InBuffer
, OutBuffer
);
4799 process_local_message(oplock_sock
, InBuffer
, BUFFER_SIZE
);
4804 /****************************************************************************
4805 initialise connect, service and file structs
4806 ****************************************************************************/
4807 static void init_structs(void )
4810 get_myname(myhostname
,NULL
);
4812 for (i
=0;i
<MAX_CONNECTIONS
;i
++)
4814 Connections
[i
].open
= False
;
4815 Connections
[i
].num_files_open
=0;
4816 Connections
[i
].lastused
=0;
4817 Connections
[i
].used
=False
;
4818 string_init(&Connections
[i
].user
,"");
4819 string_init(&Connections
[i
].dirpath
,"");
4820 string_init(&Connections
[i
].connectpath
,"");
4821 string_init(&Connections
[i
].origpath
,"");
4824 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
4826 Files
[i
].open
= False
;
4827 string_init(&Files
[i
].name
,"");
4831 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
4833 file_fd_struct
*fd_ptr
= &FileFd
[i
];
4834 fd_ptr
->ref_count
= 0;
4835 fd_ptr
->dev
= (int32
)-1;
4836 fd_ptr
->inode
= (int32
)-1;
4838 fd_ptr
->fd_readonly
= -1;
4839 fd_ptr
->fd_writeonly
= -1;
4840 fd_ptr
->real_open_flags
= -1;
4846 /****************************************************************************
4847 usage on the program
4848 ****************************************************************************/
4849 static void usage(char *pname
)
4851 DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
4853 printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname
);
4854 printf("Version %s\n",VERSION
);
4855 printf("\t-D become a daemon\n");
4856 printf("\t-p port listen on the specified port\n");
4857 printf("\t-d debuglevel set the debuglevel\n");
4858 printf("\t-l log basename. Basename for log/debug files\n");
4859 printf("\t-s services file. Filename of services file\n");
4860 printf("\t-P passive only\n");
4861 printf("\t-a overwrite log file, don't append\n");
4866 /****************************************************************************
4868 ****************************************************************************/
4869 int main(int argc
,char *argv
[])
4871 extern BOOL append_log
;
4872 /* shall I run as a daemon */
4873 BOOL is_daemon
= False
;
4874 int port
= SMB_PORT
;
4876 extern char *optarg
;
4877 char pidFile
[100] = { 0 };
4879 #ifdef NEED_AUTH_PARAMETERS
4880 set_auth_parameters(argc
,argv
);
4891 strcpy(debugf
,SMBLOGFILE
);
4893 setup_logging(argv
[0],False
);
4895 charset_initialise();
4897 /* make absolutely sure we run as root - to handle cases whre people
4898 are crazy enough to have it setuid */
4908 fault_setup(exit_server
);
4909 signal(SIGTERM
, SIGNAL_CAST dflt_sig
);
4911 /* we want total control over the permissions on created files,
4912 so set our umask to 0 */
4919 /* this is for people who can't start the program correctly */
4920 while (argc
> 1 && (*argv
[1] != '-'))
4926 while ((opt
= getopt(argc
, argv
, "O:i:l:s:d:Dp:hPaf:")) != EOF
)
4930 strncpy(pidFile
, optarg
, sizeof(pidFile
));
4933 strcpy(user_socket_options
,optarg
);
4936 strcpy(scope
,optarg
);
4940 extern BOOL passive
;
4945 strcpy(servicesf
,optarg
);
4948 strcpy(debugf
,optarg
);
4952 extern BOOL append_log
;
4953 append_log
= !append_log
;
4963 DEBUGLEVEL
= atoi(optarg
);
4966 port
= atoi(optarg
);
4979 DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION
));
4980 DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
4982 #ifndef NO_GETRLIMIT
4983 #ifdef RLIMIT_NOFILE
4986 getrlimit(RLIMIT_NOFILE
, &rlp
);
4987 rlp
.rlim_cur
= (MAX_OPEN_FILES
>rlp
.rlim_max
)? rlp
.rlim_max
:MAX_OPEN_FILES
;
4988 setrlimit(RLIMIT_NOFILE
, &rlp
);
4989 getrlimit(RLIMIT_NOFILE
, &rlp
);
4990 DEBUG(3,("Maximum number of open files per session is %d\n",rlp
.rlim_cur
));
4996 DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
4997 getuid(),getgid(),geteuid(),getegid()));
4999 if (sizeof(uint16
) < 2 || sizeof(uint32
) < 4)
5001 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
5007 if (!reload_services(False
))
5010 codepage_initialise(lp_client_code_page());
5012 strcpy(myworkgroup
, lp_workgroup());
5014 #ifndef NO_SIGNAL_TEST
5015 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
5018 DEBUG(3,("%s loaded services\n",timestring()));
5020 if (!is_daemon
&& !is_a_socket(0))
5022 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
5028 DEBUG(3,("%s becoming a daemon\n",timestring()));
5037 if ((fd
= open(pidFile
,
5041 O_CREAT
| O_WRONLY
| O_TRUNC
, 0644)) < 0)
5043 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile
, strerror(errno
)));
5046 if(fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)==False
)
5048 DEBUG(0,("ERROR: smbd is already running\n"));
5051 sprintf(buf
, "%u\n", (unsigned int) getpid());
5052 if (write(fd
, buf
, strlen(buf
)) < 0)
5054 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile
, strerror(errno
)));
5057 /* Leave pid file open & locked for the duration... */
5060 if (!open_sockets(is_daemon
,port
))
5063 if (!locking_init())
5066 /* possibly reload the services file. */
5067 reload_services(True
);
5069 max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
5073 if (sys_chroot(lp_rootdir()) == 0)
5074 DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
5077 /* Setup the oplock IPC socket. */
5078 if(!open_oplock_ipc())
5084 exit_server("normal exit");