2 Unix SMB/CIFS implementation.
3 service (connection) opening and closing
4 Copyright (C) Andrew Tridgell 1992-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern struct timeval smb_last_time
;
24 extern int case_default
;
25 extern BOOL case_preserve
;
26 extern BOOL short_case_preserve
;
27 extern BOOL case_mangle
;
28 extern BOOL case_sensitive
;
29 extern BOOL use_mangled_map
;
30 extern userdom_struct current_user_info
;
33 /****************************************************************************
34 Load parameters specific to a connection/service.
35 ****************************************************************************/
37 BOOL
set_current_service(connection_struct
*conn
,BOOL do_chdir
)
39 extern char magic_char
;
40 static connection_struct
*last_conn
;
48 conn
->lastused
= smb_last_time
.tv_sec
;
53 vfs_ChDir(conn
,conn
->connectpath
) != 0 &&
54 vfs_ChDir(conn
,conn
->origpath
) != 0) {
55 DEBUG(0,("chdir (%s) failed\n",
60 if (conn
== last_conn
)
65 case_default
= lp_defaultcase(snum
);
66 case_preserve
= lp_preservecase(snum
);
67 short_case_preserve
= lp_shortpreservecase(snum
);
68 case_mangle
= lp_casemangle(snum
);
69 case_sensitive
= lp_casesensitive(snum
);
70 magic_char
= lp_magicchar(snum
);
71 use_mangled_map
= (*lp_mangled_map(snum
) ? True
:False
);
75 /****************************************************************************
76 Add a home service. Returns the new service number or -1 if fail.
77 ****************************************************************************/
79 int add_home_service(const char *service
, const char *username
, const char *homedir
)
83 if (!service
|| !homedir
)
86 if ((iHomeService
= lp_servicenumber(HOMES_NAME
)) < 0)
90 * If this is a winbindd provided username, remove
91 * the domain component before adding the service.
92 * Log a warning if the "path=" parameter does not
97 const char *p
= strchr(service
,*lp_winbind_separator());
99 /* We only want the 'user' part of the string */
105 if (!lp_add_home(service
, iHomeService
, username
, homedir
)) {
109 return lp_servicenumber(service
);
115 * Find a service entry. service is always in dos codepage.
117 * @param service is modified (to canonical form??)
119 int find_service(fstring service
)
123 all_string_sub(service
,"\\","/",0);
125 iService
= lp_servicenumber(service
);
127 /* now handle the special case of a home directory */
130 char *phome_dir
= get_user_home_dir(service
);
135 * Try mapping the servicename, it may
136 * be a Windows to unix mapped user name.
138 if(map_username(service
))
139 phome_dir
= get_user_home_dir(service
);
142 DEBUG(3,("checking for home directory %s gave %s\n",service
,
143 phome_dir
?phome_dir
:"(NULL)"));
145 iService
= add_home_service(service
,service
/* 'username' */, phome_dir
);
148 /* If we still don't have a service, attempt to add it as a printer. */
153 if ((iPrinterService
= lp_servicenumber(PRINTERS_NAME
)) >= 0)
157 DEBUG(3,("checking whether %s is a valid printer name...\n", service
));
158 pszTemp
= lp_printcapname();
159 if ((pszTemp
!= NULL
) && pcap_printername_ok(service
, pszTemp
))
161 DEBUG(3,("%s is a valid printer name\n", service
));
162 DEBUG(3,("adding %s as a printer service\n", service
));
163 lp_add_printer(service
, iPrinterService
);
164 iService
= lp_servicenumber(service
);
166 DEBUG(0,("failed to add %s as a printer service!\n", service
));
169 DEBUG(3,("%s is not a valid printer name\n", service
));
173 /* Check for default vfs service? Unsure whether to implement this */
178 /* just possibly it's a default service? */
181 char *pdefservice
= lp_defaultservice();
182 if (pdefservice
&& *pdefservice
&&
183 !strequal(pdefservice
,service
) &&
184 !strstr(service
,".."))
187 * We need to do a local copy here as lp_defaultservice()
188 * returns one of the rotating lp_string buffers that
189 * could get overwritten by the recursive find_service() call
190 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
193 pstrcpy(defservice
, pdefservice
);
194 iService
= find_service(defservice
);
197 all_string_sub(service
, "_","/",0);
198 iService
= lp_add_service(service
, iService
);
204 if (!VALID_SNUM(iService
))
206 DEBUG(0,("Invalid snum %d for %s\n",iService
, service
));
211 DEBUG(3,("find_service() failed to find service %s\n", service
));
217 /****************************************************************************
218 do some basic sainity checks on the share.
219 This function modifies dev, ecode.
220 ****************************************************************************/
221 static NTSTATUS
share_sanity_checks(int snum
, fstring dev
)
224 if (!lp_snum_ok(snum
) ||
225 !check_access(smbd_server_fd(),
226 lp_hostsallow(snum
), lp_hostsdeny(snum
))) {
227 return NT_STATUS_ACCESS_DENIED
;
230 if (dev
[0] == '?' || !dev
[0]) {
231 if (lp_print_ok(snum
)) {
232 fstrcpy(dev
,"LPT1:");
233 } else if (strequal(lp_fstype(snum
), "IPC")) {
242 if (lp_print_ok(snum
)) {
243 if (!strequal(dev
, "LPT1:")) {
244 return NT_STATUS_BAD_DEVICE_TYPE
;
246 } else if (strequal(lp_fstype(snum
), "IPC")) {
247 if (!strequal(dev
, "IPC")) {
248 return NT_STATUS_BAD_DEVICE_TYPE
;
250 } else if (!strequal(dev
, "A:")) {
251 return NT_STATUS_BAD_DEVICE_TYPE
;
254 /* Behave as a printer if we are supposed to */
255 if (lp_print_ok(snum
) && (strcmp(dev
, "A:") == 0)) {
256 fstrcpy(dev
, "LPT1:");
262 /****************************************************************************
264 ****************************************************************************/
266 static void set_read_only(connection_struct
*conn
, gid_t
*groups
, size_t n_groups
)
269 const char *service
= lp_servicename(conn
->service
);
270 conn
->read_only
= lp_readonly(conn
->service
);
275 str_list_copy(&list
, lp_readlist(conn
->service
));
277 if (!str_list_sub_basic(list
, current_user_info
.smb_name
) ) {
278 DEBUG(0, ("ERROR: read list substitution failed\n"));
280 if (!str_list_substitute(list
, "%S", service
)) {
281 DEBUG(0, ("ERROR: read list service substitution failed\n"));
283 if (user_in_list(conn
->user
, (const char **)list
, groups
, n_groups
))
284 conn
->read_only
= True
;
285 str_list_free(&list
);
288 str_list_copy(&list
, lp_writelist(conn
->service
));
290 if (!str_list_sub_basic(list
, current_user_info
.smb_name
) ) {
291 DEBUG(0, ("ERROR: write list substitution failed\n"));
293 if (!str_list_substitute(list
, "%S", service
)) {
294 DEBUG(0, ("ERROR: write list service substitution failed\n"));
296 if (user_in_list(conn
->user
, (const char **)list
, groups
, n_groups
))
297 conn
->read_only
= False
;
298 str_list_free(&list
);
302 /****************************************************************************
304 ****************************************************************************/
306 static void set_admin_user(connection_struct
*conn
, gid_t
*groups
, size_t n_groups
)
308 /* admin user check */
310 /* JRA - original code denied admin user if the share was
311 marked read_only. Changed as I don't think this is needed,
312 but old code left in case there is a problem here.
314 if (user_in_list(conn
->user
,lp_admin_users(conn
->service
), groups
, n_groups
)
319 conn
->admin_user
= True
;
320 conn
->force_user
= True
; /* Admin users are effectivly 'forced' */
321 DEBUG(0,("%s logged in as admin user (root privileges)\n",conn
->user
));
323 conn
->admin_user
= False
;
326 #if 0 /* This done later, for now */
327 /* admin users always run as uid=0 */
328 if (conn
->admin_user
) {
334 /****************************************************************************
335 Make a connection, given the snum to connect to, and the vuser of the
336 connecting user if appropriate.
337 ****************************************************************************/
339 static connection_struct
*make_connection_snum(int snum
, user_struct
*vuser
,
341 const char *pdev
, NTSTATUS
*status
)
343 struct passwd
*pass
= NULL
;
345 connection_struct
*conn
;
353 if (NT_STATUS_IS_ERR(*status
= share_sanity_checks(snum
, dev
))) {
359 DEBUG(0,("Couldn't find free connection.\n"));
360 *status
= NT_STATUS_INSUFFICIENT_RESOURCES
;
364 if (lp_guest_only(snum
)) {
365 const char *guestname
= lp_guestaccount();
367 pass
= getpwnam_alloc(guestname
);
369 DEBUG(0,("make_connection_snum: Invalid guest account %s??\n",guestname
));
371 *status
= NT_STATUS_NO_SUCH_USER
;
374 fstrcpy(user
,pass
->pw_name
);
375 conn
->force_user
= True
;
376 conn
->uid
= pass
->pw_uid
;
377 conn
->gid
= pass
->pw_gid
;
378 string_set(&conn
->user
,pass
->pw_name
);
380 DEBUG(3,("Guest only user %s\n",user
));
383 if (!lp_guest_ok(snum
)) {
384 DEBUG(2, ("guest user (from session setup) not permitted to access this share (%s)\n", lp_servicename(snum
)));
386 *status
= NT_STATUS_ACCESS_DENIED
;
390 if (!user_ok(vuser
->user
.unix_name
, snum
, vuser
->groups
, vuser
->n_groups
)) {
391 DEBUG(2, ("user '%s' (from session setup) not permitted to access this share (%s)\n", vuser
->user
.unix_name
, lp_servicename(snum
)));
393 *status
= NT_STATUS_ACCESS_DENIED
;
397 conn
->vuid
= vuser
->vuid
;
398 conn
->uid
= vuser
->uid
;
399 conn
->gid
= vuser
->gid
;
400 string_set(&conn
->user
,vuser
->user
.unix_name
);
401 fstrcpy(user
,vuser
->user
.unix_name
);
402 guest
= vuser
->guest
;
403 } else if (lp_security() == SEC_SHARE
) {
404 /* add it as a possible user name if we
405 are in share mode security */
406 add_session_user(lp_servicename(snum
));
407 /* shall we let them in? */
408 if (!authorise_login(snum
,user
,password
,&guest
)) {
409 DEBUG( 2, ( "Invalid username/password for [%s]\n",
410 lp_servicename(snum
)) );
412 *status
= NT_STATUS_WRONG_PASSWORD
;
415 pass
= Get_Pwnam(user
);
416 conn
->force_user
= True
;
417 conn
->uid
= pass
->pw_uid
;
418 conn
->gid
= pass
->pw_gid
;
419 string_set(&conn
->user
, pass
->pw_name
);
420 fstrcpy(user
, pass
->pw_name
);
423 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
425 *status
= NT_STATUS_ACCESS_DENIED
;
429 add_session_user(user
);
431 safe_strcpy(conn
->client_address
, client_addr(),
432 sizeof(conn
->client_address
)-1);
433 conn
->num_files_open
= 0;
434 conn
->lastused
= time(NULL
);
435 conn
->service
= snum
;
437 conn
->printer
= (strncmp(dev
,"LPT",3) == 0);
438 conn
->ipc
= ((strncmp(dev
,"IPC",3) == 0) || strequal(dev
,"ADMIN$"));
440 conn
->veto_list
= NULL
;
441 conn
->hide_list
= NULL
;
442 conn
->veto_oplock_list
= NULL
;
443 string_set(&conn
->dirpath
,"");
444 string_set(&conn
->user
,user
);
445 conn
->nt_user_token
= NULL
;
447 set_read_only(conn
, vuser
? vuser
->groups
: NULL
, vuser
? vuser
->n_groups
: 0);
449 set_admin_user(conn
, vuser
? vuser
->groups
: NULL
, vuser
? vuser
->n_groups
: 0);
452 * If force user is true, then store the
453 * given userid and also the groups
454 * of the user we're forcing.
457 if (*lp_force_user(snum
)) {
458 struct passwd
*pass2
;
460 pstrcpy(fuser
,lp_force_user(snum
));
462 /* Allow %S to be used by force user. */
463 pstring_sub(fuser
,"%S",lp_servicename(snum
));
465 pass2
= (struct passwd
*)Get_Pwnam(fuser
);
467 conn
->uid
= pass2
->pw_uid
;
468 conn
->gid
= pass2
->pw_gid
;
469 string_set(&conn
->user
,pass2
->pw_name
);
470 fstrcpy(user
,pass2
->pw_name
);
471 conn
->force_user
= True
;
472 DEBUG(3,("Forced user %s\n",user
));
474 DEBUG(1,("Couldn't find user %s\n",fuser
));
476 *status
= NT_STATUS_NO_SUCH_USER
;
481 /* admin users always run as uid=0 */
482 if (conn
->admin_user
) {
488 * If force group is true, then override
489 * any groupid stored for the connecting user.
492 if (*lp_force_group(snum
)) {
496 BOOL user_must_be_member
= False
;
498 pstrcpy(tmp_gname
,lp_force_group(snum
));
500 if (tmp_gname
[0] == '+') {
501 user_must_be_member
= True
;
502 /* even now, tmp_gname is null terminated */
503 pstrcpy(gname
,&tmp_gname
[1]);
505 pstrcpy(gname
,tmp_gname
);
507 /* default service may be a group name */
508 pstring_sub(gname
,"%S",lp_servicename(snum
));
509 gid
= nametogid(gname
);
511 if (gid
!= (gid_t
)-1) {
514 * If the user has been forced and the forced group starts
515 * with a '+', then we only set the group to be the forced
516 * group if the forced user is a member of that group.
517 * Otherwise, the meaning of the '+' would be ignored.
519 if (conn
->force_user
&& user_must_be_member
) {
520 if (user_in_group_list( user
, gname
, NULL
, 0)) {
522 DEBUG(3,("Forced group %s for member %s\n",gname
,user
));
526 DEBUG(3,("Forced group %s\n",gname
));
528 conn
->force_group
= True
;
530 DEBUG(1,("Couldn't find group %s\n",gname
));
532 *status
= NT_STATUS_NO_SUCH_GROUP
;
536 #endif /* HAVE_GETGRNAM */
540 pstrcpy(s
,lp_pathname(snum
));
541 standard_sub_conn(conn
,s
,sizeof(s
));
542 string_set(&conn
->connectpath
,s
);
543 DEBUG(3,("Connect path is '%s' for service [%s]\n",s
, lp_servicename(snum
)));
546 if (conn
->force_user
|| conn
->force_group
) {
548 /* groups stuff added by ih */
552 /* Find all the groups this uid is in and
553 store them. Used by change_to_user() */
554 initialise_groups(conn
->user
, conn
->uid
, conn
->gid
);
555 get_current_groups(conn
->gid
, &conn
->ngroups
,&conn
->groups
);
557 conn
->nt_user_token
= create_nt_token(conn
->uid
, conn
->gid
,
558 conn
->ngroups
, conn
->groups
,
563 * New code to check if there's a share security descripter
564 * added from NT server manager. This is done after the
565 * smb.conf checks are done as we need a uid and token. JRA.
570 BOOL can_write
= share_access_check(conn
, snum
, vuser
, FILE_WRITE_DATA
);
573 if (!share_access_check(conn
, snum
, vuser
, FILE_READ_DATA
)) {
574 /* No access, read or write. */
575 DEBUG(0,( "make_connection: connection to %s denied due to security descriptor.\n",
576 lp_servicename(snum
)));
578 *status
= NT_STATUS_ACCESS_DENIED
;
581 conn
->read_only
= True
;
585 /* Initialise VFS function pointers */
587 if (!smbd_vfs_init(conn
)) {
588 DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn
))));
590 *status
= NT_STATUS_BAD_NETWORK_NAME
;
594 /* ROOT Activities: */
595 /* check number of connections */
596 if (!claim_connection(conn
,
597 lp_servicename(SNUM(conn
)),
598 lp_max_connections(SNUM(conn
)),
600 DEBUG(1,("too many connections - rejected\n"));
602 *status
= NT_STATUS_INSUFFICIENT_RESOURCES
;
606 /* Preexecs are done here as they might make the dir we are to ChDir to below */
607 /* execute any "root preexec = " line */
608 if (*lp_rootpreexec(SNUM(conn
))) {
611 pstrcpy(cmd
,lp_rootpreexec(SNUM(conn
)));
612 standard_sub_conn(conn
,cmd
,sizeof(cmd
));
613 DEBUG(5,("cmd=%s\n",cmd
));
614 ret
= smbrun(cmd
,NULL
);
615 if (ret
!= 0 && lp_rootpreexec_close(SNUM(conn
))) {
616 DEBUG(1,("root preexec gave %d - failing connection\n", ret
));
617 yield_connection(conn
, lp_servicename(SNUM(conn
)));
619 *status
= NT_STATUS_ACCESS_DENIED
;
624 /* USER Activites: */
625 if (!change_to_user(conn
, conn
->vuid
)) {
626 /* No point continuing if they fail the basic checks */
627 DEBUG(0,("Can't become connected user!\n"));
629 *status
= NT_STATUS_LOGON_FAILURE
;
633 /* Remember that a different vuid can connect later without these checks... */
635 /* Preexecs are done here as they might make the dir we are to ChDir to below */
636 /* execute any "preexec = " line */
637 if (*lp_preexec(SNUM(conn
))) {
640 pstrcpy(cmd
,lp_preexec(SNUM(conn
)));
641 standard_sub_conn(conn
,cmd
,sizeof(cmd
));
642 ret
= smbrun(cmd
,NULL
);
643 if (ret
!= 0 && lp_preexec_close(SNUM(conn
))) {
644 DEBUG(1,("preexec gave %d - failing connection\n", ret
));
645 change_to_root_user();
646 yield_connection(conn
, lp_servicename(SNUM(conn
)));
648 *status
= NT_STATUS_ACCESS_DENIED
;
653 #ifdef WITH_FAKE_KASERVER
654 if (lp_afs_share(SNUM(conn
))) {
659 #if CHECK_PATH_ON_TCONX
660 /* win2000 does not check the permissions on the directory
661 during the tree connect, instead relying on permission
662 check during individual operations. To match this behaviour
663 I have disabled this chdir check (tridge) */
664 if (vfs_ChDir(conn
,conn
->connectpath
) != 0) {
665 DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
666 get_remote_machine_name(), conn
->client_address
,
667 conn
->connectpath
,strerror(errno
)));
668 change_to_root_user();
669 yield_connection(conn
, lp_servicename(SNUM(conn
)));
671 *status
= NT_STATUS_BAD_NETWORK_NAME
;
675 /* the alternative is just to check the directory exists */
676 if (stat(conn
->connectpath
, &st
) != 0 || !S_ISDIR(st
.st_mode
)) {
677 DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn
->connectpath
, lp_servicename(SNUM(conn
))));
678 change_to_root_user();
679 yield_connection(conn
, lp_servicename(SNUM(conn
)));
681 *status
= NT_STATUS_BAD_NETWORK_NAME
;
686 string_set(&conn
->origpath
,conn
->connectpath
);
688 #if SOFTLINK_OPTIMISATION
689 /* resolve any soft links early if possible */
690 if (vfs_ChDir(conn
,conn
->connectpath
) == 0) {
692 pstrcpy(s
,conn
->connectpath
);
694 string_set(&conn
->connectpath
,s
);
695 vfs_ChDir(conn
,conn
->connectpath
);
700 * Print out the 'connected as' stuff here as we need
701 * to know the effective uid and gid we will be using
702 * (at least initially).
705 if( DEBUGLVL( IS_IPC(conn
) ? 3 : 1 ) ) {
706 dbgtext( "%s (%s) ", get_remote_machine_name(), conn
->client_address
);
707 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
708 dbgtext( "connect to service %s ", lp_servicename(SNUM(conn
)) );
709 dbgtext( "initially as user %s ", user
);
710 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
711 dbgtext( "(pid %d)\n", (int)sys_getpid() );
714 /* Add veto/hide lists */
715 if (!IS_IPC(conn
) && !IS_PRINT(conn
)) {
716 set_namearray( &conn
->veto_list
, lp_veto_files(SNUM(conn
)));
717 set_namearray( &conn
->hide_list
, lp_hide_files(SNUM(conn
)));
718 set_namearray( &conn
->veto_oplock_list
, lp_veto_oplocks(SNUM(conn
)));
721 /* Invoke VFS make connection hook */
723 if (SMB_VFS_CONNECT(conn
, lp_servicename(snum
), user
) < 0) {
724 DEBUG(0,("make_connection: VFS make connection failed!\n"));
725 change_to_root_user();
727 *status
= NT_STATUS_UNSUCCESSFUL
;
731 /* we've finished with the user stuff - go back to root */
732 change_to_root_user();
737 /***************************************************************************************
738 Simple wrapper function for make_connection() to include a call to
740 **************************************************************************************/
742 connection_struct
*make_connection_with_chdir(const char *service_in
, DATA_BLOB password
,
743 const char *dev
, uint16 vuid
, NTSTATUS
*status
)
745 connection_struct
*conn
= NULL
;
747 conn
= make_connection(service_in
, password
, dev
, vuid
, status
);
750 * make_connection() does not change the directory for us any more
751 * so we have to do it as a separate step --jerry
754 if ( conn
&& vfs_ChDir(conn
,conn
->connectpath
) != 0 ) {
755 DEBUG(0,("move_driver_to_download_area: Can't change directory to %s for [print$] (%s)\n",
756 conn
->connectpath
,strerror(errno
)));
757 yield_connection(conn
, lp_servicename(SNUM(conn
)));
759 *status
= NT_STATUS_UNSUCCESSFUL
;
766 /****************************************************************************
767 Make a connection to a service.
770 ****************************************************************************/
772 connection_struct
*make_connection(const char *service_in
, DATA_BLOB password
,
773 const char *pdev
, uint16 vuid
, NTSTATUS
*status
)
776 user_struct
*vuser
= NULL
;
783 /* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
784 if (!non_root_mode() && (euid
= geteuid()) != 0) {
785 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid
));
786 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
789 if(lp_security() != SEC_SHARE
) {
790 vuser
= get_valid_user_struct(vuid
);
792 DEBUG(1,("make_connection: refusing to connect with no session setup\n"));
793 *status
= NT_STATUS_ACCESS_DENIED
;
798 /* Logic to try and connect to the correct [homes] share, preferably without too many
799 getpwnam() lookups. This is particulary nasty for winbind usernames, where the
800 share name isn't the same as unix username.
802 The snum of the homes share is stored on the vuser at session setup time.
805 if (strequal(service_in
,HOMES_NAME
)) {
806 if(lp_security() != SEC_SHARE
) {
807 DATA_BLOB no_pw
= data_blob(NULL
, 0);
808 if (vuser
->homes_snum
== -1) {
809 DEBUG(2, ("[homes] share not available for this user because it was not found or created at session setup time\n"));
810 *status
= NT_STATUS_BAD_NETWORK_NAME
;
813 DEBUG(5, ("making a connection to [homes] service created at session setup time\n"));
814 return make_connection_snum(vuser
->homes_snum
,
818 /* Security = share. Try with current_user_info.smb_name
819 * as the username. */
820 if (*current_user_info
.smb_name
) {
821 fstring unix_username
;
822 fstrcpy(unix_username
,
823 current_user_info
.smb_name
);
824 map_username(unix_username
);
825 snum
= find_service(unix_username
);
828 DEBUG(5, ("making a connection to 'homes' service %s based on security=share\n", service_in
));
829 return make_connection_snum(snum
, NULL
,
834 } else if ((lp_security() != SEC_SHARE
) && (vuser
->homes_snum
!= -1)
835 && strequal(service_in
, lp_servicename(vuser
->homes_snum
))) {
836 DATA_BLOB no_pw
= data_blob(NULL
, 0);
837 DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service_in
));
838 return make_connection_snum(vuser
->homes_snum
,
843 fstrcpy(service
, service_in
);
847 snum
= find_service(service
);
850 if (strequal(service
,"IPC$") || strequal(service
,"ADMIN$")) {
851 DEBUG(3,("refusing IPC connection to %s\n", service
));
852 *status
= NT_STATUS_ACCESS_DENIED
;
856 DEBUG(0,("%s (%s) couldn't find service %s\n",
857 get_remote_machine_name(), client_addr(), service
));
858 *status
= NT_STATUS_BAD_NETWORK_NAME
;
862 /* Handle non-Dfs clients attempting connections to msdfs proxy */
863 if (lp_host_msdfs() && (*lp_msdfs_proxy(snum
) != '\0')) {
864 DEBUG(3, ("refusing connection to dfs proxy '%s'\n", service
));
865 *status
= NT_STATUS_BAD_NETWORK_NAME
;
869 DEBUG(5, ("making a connection to 'normal' service %s\n", service
));
871 return make_connection_snum(snum
, vuser
,
876 /****************************************************************************
878 ****************************************************************************/
879 void close_cnum(connection_struct
*conn
, uint16 vuid
)
881 DirCacheFlush(SNUM(conn
));
883 change_to_root_user();
885 DEBUG(IS_IPC(conn
)?3:1, ("%s (%s) closed connection to service %s\n",
886 get_remote_machine_name(),conn
->client_address
,
887 lp_servicename(SNUM(conn
))));
889 /* Call VFS disconnect hook */
890 SMB_VFS_DISCONNECT(conn
);
892 yield_connection(conn
, lp_servicename(SNUM(conn
)));
894 file_close_conn(conn
);
895 dptr_closecnum(conn
);
897 /* make sure we leave the directory available for unmount */
898 vfs_ChDir(conn
, "/");
900 /* execute any "postexec = " line */
901 if (*lp_postexec(SNUM(conn
)) &&
902 change_to_user(conn
, vuid
)) {
904 pstrcpy(cmd
,lp_postexec(SNUM(conn
)));
905 standard_sub_conn(conn
,cmd
,sizeof(cmd
));
907 change_to_root_user();
910 change_to_root_user();
911 /* execute any "root postexec = " line */
912 if (*lp_rootpostexec(SNUM(conn
))) {
914 pstrcpy(cmd
,lp_rootpostexec(SNUM(conn
)));
915 standard_sub_conn(conn
,cmd
,sizeof(cmd
));