2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1998-2001
6 Copyright (C) Andrew Bartlett 2001
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 uint32 global_client_caps
= 0;
26 static struct auth_context
*ntlmssp_auth_context
= NULL
;
29 on a logon error possibly map the error to success if "map to guest"
32 static NTSTATUS
do_map_to_guest(NTSTATUS status
, auth_serversupplied_info
**server_info
,
33 const char *user
, const char *domain
)
35 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
36 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
37 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
38 DEBUG(3,("No such user %s [%s] - using guest account\n",
40 make_server_info_guest(server_info
);
41 status
= NT_STATUS_OK
;
45 if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
46 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
47 DEBUG(3,("Registered username %s for guest access\n",user
));
48 make_server_info_guest(server_info
);
49 status
= NT_STATUS_OK
;
57 /****************************************************************************
58 Add the standard 'Samba' signature to the end of the session setup.
59 ****************************************************************************/
60 static void add_signature(char *outbuf
)
64 p
+= srvstr_push(outbuf
, p
, "Unix", -1, STR_TERMINATE
);
65 p
+= srvstr_push(outbuf
, p
, "Samba", -1, STR_TERMINATE
);
66 p
+= srvstr_push(outbuf
, p
, lp_workgroup(), -1, STR_TERMINATE
);
67 set_message_end(outbuf
,p
);
70 /****************************************************************************
71 Do a 'guest' logon, getting back the
72 ****************************************************************************/
73 static NTSTATUS
check_guest_password(auth_serversupplied_info
**server_info
)
75 struct auth_context
*auth_context
;
76 auth_usersupplied_info
*user_info
= NULL
;
79 unsigned char chal
[8];
83 DEBUG(3,("Got anonymous request\n"));
85 if (!NT_STATUS_IS_OK(nt_status
= make_auth_context_fixed(&auth_context
, chal
))) {
89 if (!make_user_info_guest(&user_info
)) {
90 auth_context
->free(&auth_context
);
91 return NT_STATUS_NO_MEMORY
;
94 nt_status
= auth_context
->check_ntlm_password(auth_context
, user_info
, server_info
);
95 auth_context
->free(&auth_context
);
96 free_user_info(&user_info
);
102 /****************************************************************************
103 reply to a session setup spnego negotiate packet for kerberos
104 ****************************************************************************/
105 static int reply_spnego_kerberos(connection_struct
*conn
,
106 char *inbuf
, char *outbuf
,
107 int length
, int bufsize
,
112 const struct passwd
*pw
;
117 auth_serversupplied_info
*server_info
= NULL
;
120 if (!spnego_parse_krb5_wrap(*secblob
, &ticket
)) {
121 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
124 ads
= ads_init(NULL
, NULL
, NULL
, NULL
);
126 ret
= ads_verify_ticket(ads
, &ticket
, &client
, &auth_data
);
127 if (!NT_STATUS_IS_OK(ret
)) {
128 DEBUG(1,("Failed to verify incoming ticket!\n"));
130 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
133 DEBUG(3,("Ticket name is [%s]\n", client
));
135 p
= strchr_m(client
, '@');
137 DEBUG(3,("Doesn't look like a valid principal\n"));
139 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
143 if (strcasecmp(p
+1, ads
->realm
) != 0) {
144 DEBUG(3,("Ticket for foreign realm %s@%s\n", client
, p
+1));
145 if (!lp_allow_trusted_domains()) {
146 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
148 /* this gives a fully qualified user name (ie. with full realm).
149 that leads to very long usernames, but what else can we do? */
150 asprintf(&user
, "%s%s%s", p
+1, lp_winbind_separator(), client
);
152 user
= strdup(client
);
156 /* the password is good - let them in */
157 pw
= smb_getpwnam(user
,False
);
158 if (!pw
&& !strstr(user
, lp_winbind_separator())) {
160 /* try it with a winbind domain prefix */
161 asprintf(&user2
, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user
);
162 pw
= smb_getpwnam(user2
,False
);
170 DEBUG(1,("Username %s is invalid on this system\n",user
));
171 return ERROR_NT(NT_STATUS_NO_SUCH_USER
);
174 if (!make_server_info_pw(&server_info
,pw
)) {
175 DEBUG(1,("make_server_info_from_pw failed!\n"));
176 return ERROR_NT(NT_STATUS_NO_MEMORY
);
179 sess_vuid
= register_vuid(server_info
, user
);
182 free_server_info(&server_info
);
184 if (sess_vuid
== -1) {
185 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
188 set_message(outbuf
,4,0,True
);
189 SSVAL(outbuf
, smb_vwv3
, 0);
190 add_signature(outbuf
);
192 SSVAL(outbuf
,smb_uid
,sess_vuid
);
193 SSVAL(inbuf
,smb_uid
,sess_vuid
);
195 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
200 /****************************************************************************
201 send a security blob via a session setup reply
202 ****************************************************************************/
203 static BOOL
reply_sesssetup_blob(connection_struct
*conn
, char *outbuf
,
208 set_message(outbuf
,4,0,True
);
210 /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
211 that we aren't finished yet */
213 SIVAL(outbuf
, smb_rcls
, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED
));
214 SSVAL(outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
215 SSVAL(outbuf
, smb_vwv3
, blob
.length
);
217 memcpy(p
, blob
.data
, blob
.length
);
219 p
+= srvstr_push(outbuf
, p
, "Unix", -1, STR_TERMINATE
);
220 p
+= srvstr_push(outbuf
, p
, "Samba", -1, STR_TERMINATE
);
221 p
+= srvstr_push(outbuf
, p
, lp_workgroup(), -1, STR_TERMINATE
);
222 set_message_end(outbuf
,p
);
224 return send_smb(smbd_server_fd(),outbuf
);
227 /****************************************************************************
228 reply to a session setup spnego negotiate packet
229 ****************************************************************************/
230 static int reply_spnego_negotiate(connection_struct
*conn
,
233 int length
, int bufsize
,
236 char *OIDs
[ASN1_MAX_OIDS
];
239 uint32 ntlmssp_command
, neg_flags
;
240 DATA_BLOB sess_key
, chal
, spnego_chal
;
241 const uint8
*cryptkey
;
242 BOOL got_kerberos
= False
;
245 /* parse out the OIDs and the first sec blob */
246 if (!parse_negTokenTarg(blob1
, OIDs
, &secblob
)) {
247 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
250 for (i
=0;OIDs
[i
];i
++) {
251 DEBUG(3,("Got OID %s\n", OIDs
[i
]));
252 if (strcmp(OID_KERBEROS5
, OIDs
[i
]) == 0 ||
253 strcmp(OID_KERBEROS5_OLD
, OIDs
[i
]) == 0) {
258 DEBUG(3,("Got secblob of size %d\n", secblob
.length
));
262 int ret
= reply_spnego_kerberos(conn
, inbuf
, outbuf
,
263 length
, bufsize
, &secblob
);
264 data_blob_free(&secblob
);
269 /* parse the NTLMSSP packet */
271 file_save("secblob.dat", secblob
.data
, secblob
.length
);
274 if (!msrpc_parse(&secblob
, "CddB",
279 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
282 data_blob_free(&secblob
);
283 data_blob_free(&sess_key
);
285 if (ntlmssp_command
!= NTLMSSP_NEGOTIATE
) {
286 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
289 DEBUG(3,("Got neg_flags=%08x\n", neg_flags
));
291 if (ntlmssp_auth_context
) {
292 ntlmssp_auth_context
->free(&ntlmssp_auth_context
);
295 if (!NT_STATUS_IS_OK(nt_status
= make_auth_context_subsystem(&ntlmssp_auth_context
))) {
296 return ERROR_NT(nt_status
);
299 cryptkey
= ntlmssp_auth_context
->get_ntlm_challenge(ntlmssp_auth_context
);
301 /* Give them the challenge. For now, ignore neg_flags and just
302 return the flags we want. Obviously this is not correct */
304 neg_flags
= NTLMSSP_NEGOTIATE_UNICODE
|
305 NTLMSSP_NEGOTIATE_LM_KEY
|
306 NTLMSSP_NEGOTIATE_NTLM
;
308 msrpc_gen(&chal
, "Cddddbdddd",
314 cryptkey
, sizeof(cryptkey
),
318 if (!spnego_gen_challenge(&spnego_chal
, &chal
, &chal
)) {
319 DEBUG(3,("Failed to generate challenge\n"));
320 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
323 /* now tell the client to send the auth packet */
324 reply_sesssetup_blob(conn
, outbuf
, spnego_chal
);
326 data_blob_free(&chal
);
327 data_blob_free(&spnego_chal
);
329 /* and tell smbd that we have already replied to this packet */
334 /****************************************************************************
335 reply to a session setup spnego auth packet
336 ****************************************************************************/
337 static int reply_spnego_auth(connection_struct
*conn
, char *inbuf
, char *outbuf
,
338 int length
, int bufsize
,
342 char *workgroup
= NULL
, *user
= NULL
, *machine
= NULL
;
343 DATA_BLOB lmhash
, nthash
, sess_key
;
344 DATA_BLOB plaintext_password
= data_blob(NULL
, 0);
345 uint32 ntlmssp_command
, neg_flags
;
350 auth_usersupplied_info
*user_info
= NULL
;
351 auth_serversupplied_info
*server_info
= NULL
;
353 if (!spnego_parse_auth(blob1
, &auth
)) {
355 file_save("auth.dat", blob1
.data
, blob1
.length
);
357 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
360 /* now the NTLMSSP encoded auth hashes */
361 if (!msrpc_parse(&auth
, "CdBBUUUBd",
371 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
374 data_blob_free(&auth
);
375 data_blob_free(&sess_key
);
377 DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n",
378 user
, workgroup
, machine
, lmhash
.length
, nthash
.length
));
381 file_save("nthash1.dat", nthash
.data
, nthash
.length
);
382 file_save("lmhash1.dat", lmhash
.data
, lmhash
.length
);
385 if (!make_user_info_map(&user_info
,
391 return ERROR_NT(NT_STATUS_NO_MEMORY
);
394 nt_status
= ntlmssp_auth_context
->check_ntlm_password(ntlmssp_auth_context
, user_info
, &server_info
);
396 if (!NT_STATUS_IS_OK(nt_status
)) {
397 nt_status
= do_map_to_guest(nt_status
, &server_info
, user
, workgroup
);
400 SAFE_FREE(workgroup
);
403 ntlmssp_auth_context
->free(&ntlmssp_auth_context
);
405 free_user_info(&user_info
);
407 data_blob_free(&lmhash
);
409 data_blob_free(&nthash
);
411 if (!NT_STATUS_IS_OK(nt_status
)) {
413 return ERROR_NT(nt_status_squash(nt_status
));
416 as_guest
= server_info
->guest
;
418 sess_vuid
= register_vuid(server_info
, user
);
419 free_server_info(&server_info
);
423 if (sess_vuid
== -1) {
424 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
427 set_message(outbuf
,4,0,True
);
428 SSVAL(outbuf
, smb_vwv3
, 0);
431 SSVAL(outbuf
,smb_vwv2
,1);
434 add_signature(outbuf
);
436 SSVAL(outbuf
,smb_uid
,sess_vuid
);
437 SSVAL(inbuf
,smb_uid
,sess_vuid
);
439 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
443 /****************************************************************************
444 reply to a session setup spnego anonymous packet
445 ****************************************************************************/
446 static int reply_spnego_anonymous(connection_struct
*conn
, char *inbuf
, char *outbuf
,
447 int length
, int bufsize
)
450 auth_serversupplied_info
*server_info
= NULL
;
453 nt_status
= check_guest_password(&server_info
);
455 if (!NT_STATUS_IS_OK(nt_status
)) {
456 return ERROR_NT(nt_status_squash(nt_status
));
459 sess_vuid
= register_vuid(server_info
, lp_guestaccount());
461 free_server_info(&server_info
);
463 if (sess_vuid
== -1) {
464 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
467 set_message(outbuf
,4,0,True
);
468 SSVAL(outbuf
, smb_vwv3
, 0);
469 add_signature(outbuf
);
471 SSVAL(outbuf
,smb_uid
,sess_vuid
);
472 SSVAL(inbuf
,smb_uid
,sess_vuid
);
474 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
478 /****************************************************************************
479 reply to a session setup command
480 ****************************************************************************/
481 static int reply_sesssetup_and_X_spnego(connection_struct
*conn
, char *inbuf
,char *outbuf
,
482 int length
,int bufsize
)
488 DEBUG(3,("Doing spnego session setup\n"));
490 if (global_client_caps
== 0) {
491 global_client_caps
= IVAL(inbuf
,smb_vwv10
);
494 p
= (uint8
*)smb_buf(inbuf
);
496 if (SVAL(inbuf
, smb_vwv7
) == 0) {
497 /* an anonymous request */
498 return reply_spnego_anonymous(conn
, inbuf
, outbuf
, length
, bufsize
);
501 /* pull the spnego blob */
502 blob1
= data_blob(p
, SVAL(inbuf
, smb_vwv7
));
505 file_save("negotiate.dat", blob1
.data
, blob1
.length
);
508 if (blob1
.data
[0] == ASN1_APPLICATION(0)) {
509 /* its a negTokenTarg packet */
510 ret
= reply_spnego_negotiate(conn
, inbuf
, outbuf
, length
, bufsize
, blob1
);
511 data_blob_free(&blob1
);
515 if (blob1
.data
[0] == ASN1_CONTEXT(1)) {
516 /* its a auth packet */
517 ret
= reply_spnego_auth(conn
, inbuf
, outbuf
, length
, bufsize
, blob1
);
518 data_blob_free(&blob1
);
522 /* what sort of packet is this? */
523 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
525 data_blob_free(&blob1
);
527 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
531 /****************************************************************************
532 reply to a session setup command
533 ****************************************************************************/
534 int reply_sesssetup_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,
535 int length
,int bufsize
)
541 DATA_BLOB plaintext_password
;
543 pstring sub_user
; /* Sainitised username for substituion */
546 fstring native_lanman
;
547 static BOOL done_sesssetup
= False
;
548 extern BOOL global_encrypted_passwords_negotiated
;
549 extern BOOL global_spnego_negotiated
;
551 extern fstring remote_machine
;
552 extern userdom_struct current_user_info
;
555 auth_usersupplied_info
*user_info
= NULL
;
556 extern struct auth_context
*negprot_global_auth_context
;
557 auth_serversupplied_info
*server_info
= NULL
;
561 BOOL doencrypt
= global_encrypted_passwords_negotiated
;
563 START_PROFILE(SMBsesssetupX
);
565 ZERO_STRUCT(lm_resp
);
566 ZERO_STRUCT(nt_resp
);
567 ZERO_STRUCT(plaintext_password
);
569 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf
, smb_wct
), SVAL(inbuf
, smb_flg2
)));
571 /* a SPNEGO session setup has 12 command words, whereas a normal
572 NT1 session setup has 13. See the cifs spec. */
573 if (CVAL(inbuf
, smb_wct
) == 12 &&
574 (SVAL(inbuf
, smb_flg2
) & FLAGS2_EXTENDED_SECURITY
)) {
575 if (!global_spnego_negotiated
) {
576 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
577 return ERROR_NT(NT_STATUS_UNSUCCESSFUL
);
580 return reply_sesssetup_and_X_spnego(conn
, inbuf
, outbuf
, length
, bufsize
);
583 smb_bufsize
= SVAL(inbuf
,smb_vwv2
);
585 if (Protocol
< PROTOCOL_NT1
) {
586 uint16 passlen1
= SVAL(inbuf
,smb_vwv7
);
587 if (passlen1
> MAX_PASS_LEN
) {
588 return ERROR_DOS(ERRDOS
,ERRbuftoosmall
);
592 lm_resp
= data_blob(smb_buf(inbuf
), passlen1
);
594 plaintext_password
= data_blob(smb_buf(inbuf
), passlen1
+1);
595 /* Ensure null termination */
596 plaintext_password
.data
[passlen1
] = 0;
599 srvstr_pull(inbuf
, user
, smb_buf(inbuf
)+passlen1
, sizeof(user
), -1, STR_TERMINATE
);
603 uint16 passlen1
= SVAL(inbuf
,smb_vwv7
);
604 uint16 passlen2
= SVAL(inbuf
,smb_vwv8
);
605 enum remote_arch_types ra_type
= get_remote_arch();
606 char *p
= smb_buf(inbuf
);
608 if(global_client_caps
== 0)
609 global_client_caps
= IVAL(inbuf
,smb_vwv11
);
611 /* client_caps is used as final determination if client is NT or Win95.
612 This is needed to return the correct error codes in some
616 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
|| ra_type
== RA_WIN95
) {
617 if(!(global_client_caps
& (CAP_NT_SMBS
| CAP_STATUS32
))) {
618 set_remote_arch( RA_WIN95
);
622 if (passlen1
> MAX_PASS_LEN
) {
623 return ERROR_DOS(ERRDOS
,ERRbuftoosmall
);
626 passlen1
= MIN(passlen1
, MAX_PASS_LEN
);
627 passlen2
= MIN(passlen2
, MAX_PASS_LEN
);
630 /* both Win95 and WinNT stuff up the password lengths for
631 non-encrypting systems. Uggh.
633 if passlen1==24 its a win95 system, and its setting the
634 password length incorrectly. Luckily it still works with the
635 default code because Win95 will null terminate the password
638 if passlen1>0 and passlen2>0 then maybe its a NT box and its
639 setting passlen2 to some random value which really stuffs
640 things up. we need to fix that one. */
642 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 && passlen2
!= 1)
646 /* Save the lanman2 password and the NT md4 password. */
648 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
653 lm_resp
= data_blob(p
, passlen1
);
654 nt_resp
= data_blob(p
+passlen1
, passlen2
);
656 plaintext_password
= data_blob(p
, passlen1
+1);
657 /* Ensure null termination */
658 plaintext_password
.data
[passlen1
] = 0;
661 p
+= passlen1
+ passlen2
;
662 p
+= srvstr_pull(inbuf
, user
, p
, sizeof(user
), -1,
664 p
+= srvstr_pull(inbuf
, domain
, p
, sizeof(domain
),
666 p
+= srvstr_pull(inbuf
, native_os
, p
, sizeof(native_os
),
668 p
+= srvstr_pull(inbuf
, native_lanman
, p
, sizeof(native_lanman
),
670 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
671 domain
,native_os
,native_lanman
));
674 /* don't allow for weird usernames or domains */
675 alpha_strcpy(user
, user
, ". _-$", sizeof(user
));
676 alpha_strcpy(domain
, domain
, ". _-", sizeof(domain
));
677 if (strstr(user
, "..") || strstr(domain
,"..")) {
678 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
681 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain
, user
, remote_machine
));
684 pstrcpy(sub_user
, user
);
686 pstrcpy(sub_user
, lp_guestaccount());
689 pstrcpy(current_user_info
.smb_name
,sub_user
);
691 reload_services(True
);
693 if (lp_security() == SEC_SHARE
) {
694 /* in share level we should ignore any passwords */
696 data_blob_free(&lm_resp
);
697 data_blob_free(&nt_resp
);
698 data_blob_clear_free(&plaintext_password
);
700 map_username(sub_user
);
701 add_session_user(sub_user
);
702 /* Then force it to null for the benfit of the code below */
707 if (global_spnego_negotiated
) {
709 /* This has to be here, becouse this is a perfectly valid behaviour for guest logons :-( */
711 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
712 return ERROR_NT(NT_STATUS_UNSUCCESSFUL
);
715 nt_status
= check_guest_password(&server_info
);
717 } else if (doencrypt
) {
718 if (!make_user_info_for_reply_enc(&user_info
,
721 nt_status
= NT_STATUS_NO_MEMORY
;
723 nt_status
= negprot_global_auth_context
->check_ntlm_password(negprot_global_auth_context
,
728 struct auth_context
*plaintext_auth_context
= NULL
;
730 if (NT_STATUS_IS_OK(nt_status
= make_auth_context_subsystem(&plaintext_auth_context
))) {
731 chal
= plaintext_auth_context
->get_ntlm_challenge(plaintext_auth_context
);
733 if (!make_user_info_for_reply(&user_info
,
735 plaintext_password
)) {
736 nt_status
= NT_STATUS_NO_MEMORY
;
739 if (NT_STATUS_IS_OK(nt_status
)) {
740 nt_status
= plaintext_auth_context
->check_ntlm_password(plaintext_auth_context
,
744 plaintext_auth_context
->free(&plaintext_auth_context
);
749 free_user_info(&user_info
);
751 data_blob_free(&lm_resp
);
752 data_blob_free(&nt_resp
);
753 data_blob_clear_free(&plaintext_password
);
755 if (!NT_STATUS_IS_OK(nt_status
)) {
756 nt_status
= do_map_to_guest(nt_status
, &server_info
, user
, domain
);
759 if (!NT_STATUS_IS_OK(nt_status
)) {
760 return ERROR_NT(nt_status_squash(nt_status
));
763 /* it's ok - setup a reply */
764 if (Protocol
< PROTOCOL_NT1
) {
765 set_message(outbuf
,3,0,True
);
767 set_message(outbuf
,3,0,True
);
768 add_signature(outbuf
);
769 /* perhaps grab OS version here?? */
772 if (server_info
->guest
) {
773 SSVAL(outbuf
,smb_vwv2
,1);
775 const char *home_dir
= pdb_get_homedir(server_info
->sam_account
);
776 const char *username
= pdb_get_username(server_info
->sam_account
);
777 if ((home_dir
&& *home_dir
)
778 && (lp_servicenumber(username
) < 0)) {
779 add_home_service(username
, home_dir
);
783 /* register the name and uid as being validated, so further connections
784 to a uid can get through without a password, on the same VC */
786 sess_vuid
= register_vuid(server_info
, sub_user
);
788 free_server_info(&server_info
);
790 if (sess_vuid
== -1) {
791 return ERROR_NT(NT_STATUS_LOGON_FAILURE
);
795 SSVAL(outbuf
,smb_uid
,sess_vuid
);
796 SSVAL(inbuf
,smb_uid
,sess_vuid
);
799 max_send
= MIN(max_send
,smb_bufsize
);
801 done_sesssetup
= True
;
803 END_PROFILE(SMBsesssetupX
);
804 return chain_reply(inbuf
,outbuf
,length
,bufsize
);