added a REALLY gross hack into kerberos_kinit_password so that
[Samba/ekacnet.git] / source / smbd / sesssetup.c
blob8e7ee38504631307848e0ff7d57b4c5f4f80768c
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 handle SMBsessionsetup
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.
23 #include "includes.h"
25 uint32 global_client_caps = 0;
26 static auth_authsupplied_info *ntlmssp_auth_info;
28 /****************************************************************************
29 Add the standard 'Samba' signature to the end of the session setup.
30 ****************************************************************************/
31 static void add_signature(char *outbuf)
33 char *p;
34 p = smb_buf(outbuf);
35 p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
36 p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
37 p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
38 set_message_end(outbuf,p);
41 /****************************************************************************
42 Do a 'guest' logon, getting back the
43 ****************************************************************************/
44 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
47 auth_authsupplied_info *auth_info;
48 auth_usersupplied_info *user_info = NULL;
50 NTSTATUS nt_status;
51 char chal[8];
53 ZERO_STRUCT(chal);
55 DEBUG(3,("Got anonymous request\n"));
57 make_user_info_guest(&user_info);
58 make_auth_info_fixed(&auth_info, chal);
60 nt_status = check_password(user_info, auth_info, server_info);
61 free_auth_info(&auth_info);
62 free_user_info(&user_info);
63 return nt_status;
67 #ifdef HAVE_KRB5
68 /****************************************************************************
69 reply to a session setup spnego negotiate packet for kerberos
70 ****************************************************************************/
71 static int reply_spnego_kerberos(connection_struct *conn,
72 char *inbuf, char *outbuf,
73 int length, int bufsize,
74 DATA_BLOB *secblob)
76 DATA_BLOB ticket;
77 char *client, *p;
78 const struct passwd *pw;
79 char *user;
80 int sess_vuid;
81 NTSTATUS ret;
82 DATA_BLOB auth_data;
83 auth_serversupplied_info *server_info = NULL;
84 ADS_STRUCT *ads;
86 if (!spnego_parse_krb5_wrap(*secblob, &ticket)) {
87 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
90 ads = ads_init(NULL, NULL, NULL, NULL);
92 ret = ads_verify_ticket(ads, &ticket, &client, &auth_data);
93 if (!NT_STATUS_IS_OK(ret)) {
94 DEBUG(1,("Failed to verify incoming ticket!\n"));
95 ads_destroy(&ads);
96 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
99 DEBUG(3,("Ticket name is [%s]\n", client));
101 p = strchr_m(client, '@');
102 if (!p) {
103 DEBUG(3,("Doesn't look like a valid principal\n"));
104 ads_destroy(&ads);
105 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
108 *p = 0;
109 if (strcasecmp(p+1, ads->realm) != 0) {
110 DEBUG(3,("Ticket for incorrect realm %s\n", p+1));
111 ads_destroy(&ads);
112 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
114 ads_destroy(&ads);
116 user = client;
118 /* the password is good - let them in */
119 pw = smb_getpwnam(user,False);
120 if (!pw) {
121 DEBUG(1,("Username %s is invalid on this system\n",user));
122 return ERROR_NT(NT_STATUS_NO_SUCH_USER);
125 if (!make_server_info_pw(&server_info,pw)) {
126 DEBUG(1,("make_server_info_from_pw failed!\n"));
127 return ERROR_NT(NT_STATUS_NO_MEMORY);
130 sess_vuid = register_vuid(server_info, user);
132 free_server_info(&server_info);
134 if (sess_vuid == -1) {
135 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
138 set_message(outbuf,4,0,True);
139 SSVAL(outbuf, smb_vwv3, 0);
140 add_signature(outbuf);
142 SSVAL(outbuf,smb_uid,sess_vuid);
143 SSVAL(inbuf,smb_uid,sess_vuid);
145 return chain_reply(inbuf,outbuf,length,bufsize);
147 #endif
150 /****************************************************************************
151 send a security blob via a session setup reply
152 ****************************************************************************/
153 static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
154 DATA_BLOB blob)
156 char *p;
158 set_message(outbuf,4,0,True);
160 /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
161 that we aren't finished yet */
163 SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
164 SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
165 SSVAL(outbuf, smb_vwv3, blob.length);
166 p = smb_buf(outbuf);
167 memcpy(p, blob.data, blob.length);
168 p += blob.length;
169 p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
170 p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
171 p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
172 set_message_end(outbuf,p);
174 return send_smb(smbd_server_fd(),outbuf);
177 /****************************************************************************
178 reply to a session setup spnego negotiate packet
179 ****************************************************************************/
180 static int reply_spnego_negotiate(connection_struct *conn,
181 char *inbuf,
182 char *outbuf,
183 int length, int bufsize,
184 DATA_BLOB blob1)
186 char *OIDs[ASN1_MAX_OIDS];
187 DATA_BLOB secblob;
188 int i;
189 uint32 ntlmssp_command, neg_flags;
190 DATA_BLOB sess_key, chal, spnego_chal;
191 DATA_BLOB cryptkey;
192 BOOL got_kerberos = False;
194 /* parse out the OIDs and the first sec blob */
195 if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
196 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
199 for (i=0;OIDs[i];i++) {
200 DEBUG(3,("Got OID %s\n", OIDs[i]));
201 if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 ||
202 strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) {
203 got_kerberos = True;
205 free(OIDs[i]);
207 DEBUG(3,("Got secblob of size %d\n", secblob.length));
209 #ifdef HAVE_KRB5
210 if (got_kerberos) {
211 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
212 length, bufsize, &secblob);
213 data_blob_free(&secblob);
214 return ret;
216 #endif
218 /* parse the NTLMSSP packet */
219 #if 0
220 file_save("secblob.dat", secblob.data, secblob.length);
221 #endif
223 if (!msrpc_parse(&secblob, "CddB",
224 "NTLMSSP",
225 &ntlmssp_command,
226 &neg_flags,
227 &sess_key)) {
228 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
231 data_blob_free(&secblob);
232 data_blob_free(&sess_key);
234 if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
235 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
238 DEBUG(3,("Got neg_flags=%08x\n", neg_flags));
240 if (!make_auth_info_subsystem(&ntlmssp_auth_info)) {
241 return ERROR_NT(NT_STATUS_NO_MEMORY);
244 cryptkey = auth_get_challenge(ntlmssp_auth_info);
246 /* Give them the challenge. For now, ignore neg_flags and just
247 return the flags we want. Obviously this is not correct */
249 neg_flags = NTLMSSP_NEGOTIATE_UNICODE |
250 NTLMSSP_NEGOTIATE_LM_KEY |
251 NTLMSSP_NEGOTIATE_NTLM;
253 msrpc_gen(&chal, "Cddddbdddd",
254 "NTLMSSP",
255 NTLMSSP_CHALLENGE,
257 0x30, /* ?? */
258 neg_flags,
259 cryptkey.data, cryptkey.length,
260 0, 0, 0,
261 0x3000); /* ?? */
263 if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) {
264 DEBUG(3,("Failed to generate challenge\n"));
265 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
268 /* now tell the client to send the auth packet */
269 reply_sesssetup_blob(conn, outbuf, spnego_chal);
271 data_blob_free(&chal);
272 data_blob_free(&cryptkey);
273 data_blob_free(&spnego_chal);
275 /* and tell smbd that we have already replied to this packet */
276 return -1;
280 /****************************************************************************
281 reply to a session setup spnego auth packet
282 ****************************************************************************/
283 static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
284 int length, int bufsize,
285 DATA_BLOB blob1)
287 DATA_BLOB auth;
288 char *workgroup = NULL, *user = NULL, *machine = NULL;
289 DATA_BLOB lmhash, nthash, sess_key;
290 DATA_BLOB plaintext_password = data_blob(NULL, 0);
291 uint32 ntlmssp_command, neg_flags;
292 NTSTATUS nt_status;
293 int sess_vuid;
295 auth_usersupplied_info *user_info = NULL;
296 auth_serversupplied_info *server_info = NULL;
298 if (!spnego_parse_auth(blob1, &auth)) {
299 #if 0
300 file_save("auth.dat", blob1.data, blob1.length);
301 #endif
302 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
305 /* now the NTLMSSP encoded auth hashes */
306 if (!msrpc_parse(&auth, "CdBBUUUBd",
307 "NTLMSSP",
308 &ntlmssp_command,
309 &lmhash,
310 &nthash,
311 &workgroup,
312 &user,
313 &machine,
314 &sess_key,
315 &neg_flags)) {
316 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
319 data_blob_free(&auth);
320 data_blob_free(&sess_key);
322 DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n",
323 user, workgroup, machine, lmhash.length, nthash.length));
325 #if 0
326 file_save("nthash1.dat", nthash.data, nthash.length);
327 file_save("lmhash1.dat", lmhash.data, lmhash.length);
328 #endif
330 if (!make_user_info_map(&user_info,
331 user, workgroup,
332 machine,
333 lmhash, nthash,
334 plaintext_password,
335 neg_flags, True)) {
336 return ERROR_NT(NT_STATUS_NO_MEMORY);
339 SAFE_FREE(workgroup);
340 SAFE_FREE(user);
341 SAFE_FREE(machine);
343 nt_status = check_password(user_info, ntlmssp_auth_info, &server_info);
345 free_auth_info(&ntlmssp_auth_info);
347 free_user_info(&user_info);
349 data_blob_free(&lmhash);
351 data_blob_free(&nthash);
353 if (!NT_STATUS_IS_OK(nt_status)) {
354 return ERROR_NT(nt_status_squash(nt_status));
357 sess_vuid = register_vuid(server_info, user);
359 free_server_info(&server_info);
361 if (sess_vuid == -1) {
362 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
365 set_message(outbuf,4,0,True);
366 SSVAL(outbuf, smb_vwv3, 0);
367 add_signature(outbuf);
369 SSVAL(outbuf,smb_uid,sess_vuid);
370 SSVAL(inbuf,smb_uid,sess_vuid);
372 return chain_reply(inbuf,outbuf,length,bufsize);
376 /****************************************************************************
377 reply to a session setup spnego anonymous packet
378 ****************************************************************************/
379 static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf,
380 int length, int bufsize)
382 int sess_vuid;
383 auth_serversupplied_info *server_info = NULL;
384 NTSTATUS nt_status;
386 nt_status = check_guest_password(&server_info);
388 if (!NT_STATUS_IS_OK(nt_status)) {
389 return ERROR_NT(nt_status_squash(nt_status));
392 sess_vuid = register_vuid(server_info, lp_guestaccount());
394 free_server_info(&server_info);
396 if (sess_vuid == -1) {
397 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
400 set_message(outbuf,4,0,True);
401 SSVAL(outbuf, smb_vwv3, 0);
402 add_signature(outbuf);
404 SSVAL(outbuf,smb_uid,sess_vuid);
405 SSVAL(inbuf,smb_uid,sess_vuid);
407 return chain_reply(inbuf,outbuf,length,bufsize);
411 /****************************************************************************
412 reply to a session setup command
413 ****************************************************************************/
414 static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,char *outbuf,
415 int length,int bufsize)
417 uint8 *p;
418 DATA_BLOB blob1;
419 int ret;
421 DEBUG(3,("Doing spnego session setup\n"));
423 if (global_client_caps == 0) {
424 global_client_caps = IVAL(inbuf,smb_vwv10);
427 p = (uint8 *)smb_buf(inbuf);
429 if (SVAL(inbuf, smb_vwv7) == 0) {
430 /* an anonymous request */
431 return reply_spnego_anonymous(conn, inbuf, outbuf, length, bufsize);
434 /* pull the spnego blob */
435 blob1 = data_blob(p, SVAL(inbuf, smb_vwv7));
437 #if 0
438 file_save("negotiate.dat", blob1.data, blob1.length);
439 #endif
441 if (blob1.data[0] == ASN1_APPLICATION(0)) {
442 /* its a negTokenTarg packet */
443 ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1);
444 data_blob_free(&blob1);
445 return ret;
448 if (blob1.data[0] == ASN1_CONTEXT(1)) {
449 /* its a auth packet */
450 ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1);
451 data_blob_free(&blob1);
452 return ret;
455 /* what sort of packet is this? */
456 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
458 data_blob_free(&blob1);
460 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
464 /****************************************************************************
465 reply to a session setup command
466 ****************************************************************************/
467 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
468 int length,int bufsize)
470 int sess_vuid;
471 int smb_bufsize;
472 DATA_BLOB lm_resp;
473 DATA_BLOB nt_resp;
474 DATA_BLOB plaintext_password;
475 pstring user;
476 pstring sub_user; /* Sainitised username for substituion */
477 fstring domain;
478 fstring native_os;
479 fstring native_lanman;
480 static BOOL done_sesssetup = False;
481 extern BOOL global_encrypted_passwords_negotiated;
482 extern BOOL global_spnego_negotiated;
483 extern int Protocol;
484 extern fstring remote_machine;
485 extern userdom_struct current_user_info;
486 extern int max_send;
488 auth_usersupplied_info *user_info = NULL;
489 extern auth_authsupplied_info *negprot_global_auth_info;
490 auth_serversupplied_info *server_info = NULL;
492 NTSTATUS nt_status;
494 BOOL doencrypt = global_encrypted_passwords_negotiated;
496 START_PROFILE(SMBsesssetupX);
498 ZERO_STRUCT(lm_resp);
499 ZERO_STRUCT(nt_resp);
500 ZERO_STRUCT(plaintext_password);
502 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
504 /* a SPNEGO session setup has 12 command words, whereas a normal
505 NT1 session setup has 13. See the cifs spec. */
506 if (CVAL(inbuf, smb_wct) == 12 &&
507 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
508 return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
511 smb_bufsize = SVAL(inbuf,smb_vwv2);
513 if (Protocol < PROTOCOL_NT1) {
514 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
515 if (passlen1 > MAX_PASS_LEN) {
516 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
519 if (doencrypt) {
520 lm_resp = data_blob(smb_buf(inbuf), passlen1);
521 } else {
522 plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
523 /* Ensure null termination */
524 plaintext_password.data[passlen1] = 0;
527 srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE);
528 *domain = 0;
530 } else {
531 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
532 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
533 enum remote_arch_types ra_type = get_remote_arch();
534 char *p = smb_buf(inbuf);
536 if(global_client_caps == 0)
537 global_client_caps = IVAL(inbuf,smb_vwv11);
539 /* client_caps is used as final determination if client is NT or Win95.
540 This is needed to return the correct error codes in some
541 circumstances.
544 if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
545 if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
546 set_remote_arch( RA_WIN95);
550 if (passlen1 > MAX_PASS_LEN) {
551 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
554 passlen1 = MIN(passlen1, MAX_PASS_LEN);
555 passlen2 = MIN(passlen2, MAX_PASS_LEN);
557 if (!doencrypt) {
558 /* both Win95 and WinNT stuff up the password lengths for
559 non-encrypting systems. Uggh.
561 if passlen1==24 its a win95 system, and its setting the
562 password length incorrectly. Luckily it still works with the
563 default code because Win95 will null terminate the password
564 anyway
566 if passlen1>0 and passlen2>0 then maybe its a NT box and its
567 setting passlen2 to some random value which really stuffs
568 things up. we need to fix that one. */
570 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
571 passlen2 = 0;
574 /* Save the lanman2 password and the NT md4 password. */
576 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
577 doencrypt = False;
580 if (doencrypt) {
581 lm_resp = data_blob(p, passlen1);
582 nt_resp = data_blob(p+passlen1, passlen2);
583 } else {
584 plaintext_password = data_blob(p, passlen1+1);
585 /* Ensure null termination */
586 plaintext_password.data[passlen1] = 0;
589 p += passlen1 + passlen2;
590 p += srvstr_pull(inbuf, user, p, sizeof(user), -1,
591 STR_TERMINATE);
592 p += srvstr_pull(inbuf, domain, p, sizeof(domain),
593 -1, STR_TERMINATE);
594 p += srvstr_pull(inbuf, native_os, p, sizeof(native_os),
595 -1, STR_TERMINATE);
596 p += srvstr_pull(inbuf, native_lanman, p, sizeof(native_lanman),
597 -1, STR_TERMINATE);
598 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
599 domain,native_os,native_lanman));
602 /* don't allow for weird usernames or domains */
603 alpha_strcpy(user, user, ". _-$", sizeof(user));
604 alpha_strcpy(domain, domain, ". _-", sizeof(domain));
605 if (strstr(user, "..") || strstr(domain,"..")) {
606 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
609 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
611 if (*user) {
612 if (global_spnego_negotiated) {
613 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
614 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
618 if (*user) {
619 pstrcpy(sub_user, user);
620 } else {
621 pstrcpy(sub_user, lp_guestaccount());
624 pstrcpy(current_user_info.smb_name,sub_user);
626 reload_services(True);
628 if (lp_security() == SEC_SHARE) {
629 /* in share level we should ignore any passwords */
631 data_blob_free(&lm_resp);
632 data_blob_free(&nt_resp);
633 data_blob_clear_free(&plaintext_password);
635 map_username(sub_user);
636 add_session_user(sub_user);
637 /* Then force it to null for the benfit of the code below */
638 *user = 0;
641 if (!*user) {
643 nt_status = check_guest_password(&server_info);
645 } else if (doencrypt) {
646 if (!make_user_info_for_reply_enc(&user_info,
647 user, domain,
648 lm_resp, nt_resp,
649 plaintext_password)) {
650 return ERROR_NT(NT_STATUS_NO_MEMORY);
653 nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
655 } else {
656 auth_authsupplied_info *plaintext_auth_info = NULL;
657 DATA_BLOB chal;
658 if (!make_auth_info_subsystem(&plaintext_auth_info)) {
659 return ERROR_NT(NT_STATUS_NO_MEMORY);
662 chal = auth_get_challenge(plaintext_auth_info);
664 if (!make_user_info_for_reply(&user_info,
665 user, domain, chal.data,
666 plaintext_password)) {
667 return ERROR_NT(NT_STATUS_NO_MEMORY);
670 nt_status = check_password(user_info, plaintext_auth_info, &server_info);
672 data_blob_free(&chal);
673 free_auth_info(&plaintext_auth_info);
676 free_user_info(&user_info);
678 data_blob_free(&lm_resp);
679 data_blob_free(&nt_resp);
680 data_blob_clear_free(&plaintext_password);
682 if (!NT_STATUS_IS_OK(nt_status)) {
683 if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
684 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
685 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
687 DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
688 make_server_info_guest(&server_info);
689 nt_status = NT_STATUS_OK;
692 } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
693 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
694 DEBUG(3,("Registered username %s for guest access\n",user));
695 make_server_info_guest(&server_info);
696 nt_status = NT_STATUS_OK;
701 if (!NT_STATUS_IS_OK(nt_status)) {
702 return ERROR_NT(nt_status_squash(nt_status));
705 /* it's ok - setup a reply */
706 if (Protocol < PROTOCOL_NT1) {
707 set_message(outbuf,3,0,True);
708 } else {
709 set_message(outbuf,3,0,True);
710 add_signature(outbuf);
711 /* perhaps grab OS version here?? */
714 if (server_info->guest) {
715 SSVAL(outbuf,smb_vwv2,1);
716 } else {
717 const char *home_dir = pdb_get_homedir(server_info->sam_account);
718 const char *username = pdb_get_username(server_info->sam_account);
719 if ((home_dir && *home_dir)
720 && (lp_servicenumber(username) < 0)) {
721 add_home_service(username, home_dir);
725 /* register the name and uid as being validated, so further connections
726 to a uid can get through without a password, on the same VC */
728 sess_vuid = register_vuid(server_info, sub_user);
730 free_server_info(&server_info);
732 if (sess_vuid == -1) {
733 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
737 SSVAL(outbuf,smb_uid,sess_vuid);
738 SSVAL(inbuf,smb_uid,sess_vuid);
740 if (!done_sesssetup)
741 max_send = MIN(max_send,smb_bufsize);
743 done_sesssetup = True;
745 END_PROFILE(SMBsesssetupX);
746 return chain_reply(inbuf,outbuf,length,bufsize);