xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c (revision 88d3e830e3d64f655cacd9c04c21b0677c7c6605)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * SMB: session_setup_andx
27  *
28  * This SMB is used to further "Set up" the session normally just
29  * established via the negotiate protocol.
30  *
31  * One primary function is to perform a "user logon" in the case where the
32  * server is in user level security mode.  The Uid in the SMB header is set
33  * by the client to be the userid desired for the AccountName and validated
34  * by the AccountPassword.
35  *
36  * If the negotiated protocol is prior to NT LM 0.12, the format of
37  * SMB_COM_SESSION_SETUP_ANDX is:
38  *
39  * Client Request                 Description
40  * ============================== =====================================
41  *
42  * UCHAR WordCount;               Count of parameter words = 10
43  * UCHAR AndXCommand;             Secondary (X) command; 0xFF = none
44  * UCHAR AndXReserved;            Reserved (must be 0)
45  * USHORT AndXOffset;             Offset to next command WordCount
46  * USHORT MaxBufferSize;          Client maximum buffer size
47  * USHORT MaxMpxCount;            Actual maximum multiplexed pending
48  *                                 requests
49  * USHORT VcNumber;               0 = first (only), nonzero=additional
50  *                                 VC number
51  * ULONG SessionKey;              Session key (valid iff VcNumber != 0)
52  * USHORT PasswordLength;         Account password size
53  * ULONG Reserved;                Must be 0
54  * USHORT ByteCount;              Count of data bytes;    min = 0
55  * UCHAR AccountPassword[];       Account Password
56  * STRING AccountName[];          Account Name
57  * STRING PrimaryDomain[];        Client's primary domain
58  * STRING NativeOS[];             Client's native operating system
59  * STRING NativeLanMan[];         Client's native LAN Manager type
60  *
61  * and the response is:
62  *
63  * Server Response                    Description
64  * ================================== =================================
65  *
66  * UCHAR WordCount;                   Count of parameter words = 3
67  * UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
68  *                                     none
69  * UCHAR AndXReserved;                Reserved (must be 0)
70  * USHORT AndXOffset;                 Offset to next command WordCount
71  * USHORT Action;                     Request mode:
72  *                                     bit0 = logged in as GUEST
73  * USHORT ByteCount;                  Count of data bytes
74  * STRING NativeOS[];                 Server's native operating system
75  * STRING NativeLanMan[];             Server's native LAN Manager type
76  * STRING PrimaryDomain[];            Server's primary domain
77  *
78  * If the server is in "share level security mode", the account name and
79  * passwd should be ignored by the server.
80  *
81  * If challenge/response authentication is not being used, AccountPassword
82  * should be a null terminated ASCII string with PasswordLength set to the
83  * string size including the null; the password will case insensitive. If
84  * challenge/response authentication is being used (see section 2.10), then
85  * AccountPassword will be the response to the server's challenge, and
86  * PasswordLength should be set to its length.
87  *
88  * The server validates the name and password supplied and if valid, it
89  * registers the user identifier on this session as representing the
90  * specified AccountName.  The Uid  field in the SMB header will then be
91  * used to validate access on subsequent SMB requests.  The SMB requests
92  * where permission checks are required are those which refer to a
93  * symbolically named resource such as SMB_COM_OPEN, SMB_COM_RENAME,
94  * SMB_COM_DELETE, etc..  The value of the Uid is relative to a specific
95  * client/server session so it is possible to have the same Uid value
96  * represent two different users on two different sessions at the server.
97  *
98  * Multiple session setup commands may be sent to register additional users
99  * on this session.  If the server receives an additional
100  * SMB_COM_SESSION_SETUP_ANDX, only the Uid, AccountName and
101  * AccountPassword fields need contain valid values (the server MUST ignore
102  * the other fields).
103  *
104  * The client writes the name of its domain in PrimaryDomain if it knows
105  * what the domain name is.  If the domain name is unknown, the client
106  * either encodes it as a NULL string, or as a question mark.
107  *
108  * If bit0 of Action is set, this informs the client that although the
109  * server did not recognize the AccountName, it logged the user in as a
110  * guest.  This is optional behavior by the server, and in any case one
111  * would ordinarily expect guest privileges to limited.
112  *
113  * Another function of the Session Set Up protocol is to inform the server
114  * of the maximum values which will be utilized by this client.  Here
115  * MaxBufferSize is the maximum message size which the client can receive.
116  * Thus although the server may support 16k buffers (as returned in the
117  * SMB_COM_NEGOTIATE response), if the client only has 4k buffers, the
118  * value of MaxBufferSize here would be 4096.  The minimum allowable value
119  * for MaxBufferSize is 1024.  The SMB_COM_NEGOTIATE response includes the
120  * server buffer size supported.  Thus this is the maximum SMB message size
121  * which the client can send to the server.  This size may be larger than
122  * the size returned to the server from the client via the
123  * SMB_COM_SESSION_SETUP_AND X protocol which is the maximum SMB message
124  * size which the server may send to the client.  Thus if the server's
125  * buffer size were 4k and the client's buffer size were only 2K,  the
126  * client could send up to 4k (standard) write requests but must only
127  * request up to 2k for (standard) read requests.
128  *
129  * The field, MaxMpxCount informs the server of the maximum number of
130  * requests which the client will have outstanding to the server
131  * simultaneously (see sections 5.13 and 5.25).
132  *
133  * The VcNumber field specifies whether the client wants this to be the
134  * first VC or an additional VC.  If the the SMB_COM_SESSION_SETUP_ANDX
135  * request contains a VcNumber of 0 and other VCs are still connected to
136  * that client, they should be aborted to free any resources held by the
137  * server. This condition could occur if the client was rebooted and
138  * reconnected to the server before the transport level had informed the
139  * server of the previous VC termination. There is more information on
140  * VCs in smb_negotiate.c.
141  *
142  * The values for MaxBufferSize, MaxMpxCount, and VcNumber must be less
143  * than or equal to the maximum values supported by the server as returned
144  * in the SMB_COM_NEGOTIATE response.
145  *
146  * If the negotiated SMB dialect is "NT LM 0.12" or later, the format of
147  * the response SMB is unchanged, but the request is:
148  *
149  * Client Request                 Description
150  * ============================== =====================================
151  *
152  * UCHAR WordCount;               Count of parameter words = 13
153  * UCHAR AndXCommand;             Secondary (X) command;  0xFF = none
154  * UCHAR AndXReserved;            Reserved (must be 0)
155  * USHORT AndXOffset;             Offset to next command WordCount
156  * USHORT MaxBufferSize;          Client's maximum buffer size
157  * USHORT MaxMpxCount;            Actual maximum multiplexed pending
158  *                                 requests
159  * USHORT VcNumber;               0 = first (only), nonzero=additional
160  *                                 VC number
161  * ULONG SessionKey;              Session key (valid iff VcNumber != 0)
162  * USHORT                         Account password size, ANSI
163  * CaseInsensitivePasswordLength;
164  * USHORT                         Account password size, Unicode
165  * CaseSensitivePasswordLength;
166  * ULONG Reserved;                must be 0
167  * ULONG Capabilities;            Client capabilities
168  * USHORT ByteCount;              Count of data bytes;    min = 0
169  * UCHAR                          Account Password, ANSI
170  * CaseInsensitivePassword[];
171  * UCHAR CaseSensitivePassword[]; Account Password, Unicode
172  * STRING AccountName[];          Account Name, Unicode
173  * STRING PrimaryDomain[];        Client's primary domain, Unicode
174  * STRING NativeOS[];             Client's native operating system,
175  *                                 Unicode
176  * STRING NativeLanMan[];         Client's native LAN Manager type,
177  *                                 Unicode
178  *
179  * The client expresses its capabilities to the server encoded in the
180  * Capabilities field:
181  *
182  * Capability Name           Encoding  Description
183  * ========================  ========= ================================
184  *
185  * CAP_UNICODE               0x0004    The client can use UNICODE
186  *                                      strings
187  * CAP_LARGE_FILES           0x0008    The client can deal with files
188  *                                      having 64 bit offsets
189  * CAP_NT_SMBS               0x0010    The client understands the SMBs
190  *                                      introduced with the NT LM 0.12
191  *                                      dialect.  Implies CAP_NT_FIND.
192  * CAP_NT_FIND               0x0200
193  * CAP_STATUS32              0x0040    The client can receive 32 bit
194  *                                      errors encoded in Status.Status
195  * CAP_LEVEL_II_OPLOCKS      0x0080    The client understands Level II
196  *                                      oplocks
197  *
198  * The entire message sent and received including the optional ANDX SMB
199  * must fit in the negotiated maximum transfer size.  The following are the
200  * only valid SMB commands for AndXCommand for SMB_COM_SESSION_SETUP_ANDX
201  *
202  * SMB_COM_TREE_CONNECT_ANDX     SMB_COM_OPEN
203  * SMB_COM_OPEN_ANDX             SMB_COM_CREATE
204  * SMB_COM_CREATE_NEW            SMB_COM_CREATE_DIRECTORY
205  * SMB_COM_DELETE                SMB_COM_DELETE_DIRECTORY
206  * SMB_COM_FIND                  SMB_COM_FIND_UNIQUE
207  * SMB_COM_COPY                  SMB_COM_RENAME
208  * SMB_COM_NT_RENAME             SMB_COM_CHECK_DIRECTORY
209  * SMB_COM_QUERY_INFORMATION     SMB_COM_SET_INFORMATION
210  * SMB_COM_NO_ANDX_COMMAND       SMB_COM_OPEN_PRINT_FILE
211  * SMB_COM_GET_PRINT_QUEUE       SMB_COM_TRANSACTION
212  *
213  * 4.1.2.1   Errors
214  *
215  * ERRSRV/ERRerror     - no NEG_PROT issued
216  * ERRSRV/ERRbadpw     - password not correct for given user name
217  * ERRSRV/ERRtoomanyuids    - maximum number of users per session exceeded
218  * ERRSRV/ERRnosupport - chaining of this request to the previous one is
219  * not supported
220  */
221 
222 #include <sys/types.h>
223 #include <sys/socket.h>
224 #include <netinet/in.h>
225 #include <smbsrv/smb_incl.h>
226 #include <smbsrv/smb_token.h>
227 #include <smbsrv/smb_door_svc.h>
228 
229 smb_sdrc_t
230 smb_pre_session_setup_andx(smb_request_t *sr)
231 {
232 	DTRACE_SMB_1(op__SessionSetupX__start, smb_request_t *, sr);
233 	return (SDRC_SUCCESS);
234 }
235 
236 void
237 smb_post_session_setup_andx(smb_request_t *sr)
238 {
239 	DTRACE_SMB_1(op__SessionSetupX__done, smb_request_t *, sr);
240 }
241 
242 smb_sdrc_t
243 smb_com_session_setup_andx(smb_request_t *sr)
244 {
245 	uint16_t maxbufsize, maxmpxcount, vcnumber = 0;
246 	uint32_t sesskey;
247 	uint32_t capabilities = 0;
248 	char *username = "";
249 	char *userdomain = "";
250 	char *native_os = "";
251 	char *native_lanman = "";
252 	char *hostname = sr->sr_cfg->skc_hostname;
253 	char *nbdomain = sr->sr_cfg->skc_nbdomain;
254 #ifdef FIX_6765156
255 	char *fqdn = sr->sr_cfg->skc_fqdn;
256 #endif
257 	smb_token_t *usr_token = NULL;
258 	smb_user_t *user = NULL;
259 	int security = sr->sr_cfg->skc_secmode;
260 
261 	uint16_t ci_pwlen = 0;
262 	unsigned char *ci_password = NULL;
263 	uint16_t cs_pwlen = 0;
264 	unsigned char *cs_password = NULL;
265 
266 	netr_client_t clnt_info;
267 	smb_session_key_t *session_key = NULL;
268 	int rc;
269 	char ipaddr_buf[INET6_ADDRSTRLEN];
270 	boolean_t known_domain;
271 
272 	if (sr->session->dialect >= NT_LM_0_12) {
273 		rc = smbsr_decode_vwv(sr, "b.wwwwlww4.l", &sr->andx_com,
274 		    &sr->andx_off, &maxbufsize, &maxmpxcount, &vcnumber,
275 		    &sesskey, &ci_pwlen, &cs_pwlen, &capabilities);
276 
277 		if (rc != 0)
278 			return (SDRC_ERROR);
279 
280 		ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP);
281 		cs_password = kmem_alloc(cs_pwlen + 1, KM_SLEEP);
282 
283 		/*
284 		 * The padding between the Native OS and Native LM is a
285 		 * bit strange. On NT4.0, there is a 2 byte pad between
286 		 * the OS (Windows NT 1381) and LM (Windows NT 4.0).
287 		 * On Windows 2000, there is no padding between the OS
288 		 * (Windows 2000 2195) and LM (Windows 2000 5.0).
289 		 *
290 		 * If the padding is removed from this decode string
291 		 * the NT4.0 LM comes out as an empty string.
292 		 *
293 		 * So if the client's native OS is Win NT we consider
294 		 * the padding otherwise we don't.
295 		 */
296 		rc = smbsr_decode_data(sr, "%#c#cuuu",
297 		    sr,
298 		    ci_pwlen, ci_password,
299 		    cs_pwlen, cs_password,
300 		    &username,
301 		    &userdomain,
302 		    &native_os);
303 
304 		if (rc != 0) {
305 			kmem_free(ci_password, ci_pwlen + 1);
306 			kmem_free(cs_password, cs_pwlen + 1);
307 			return (SDRC_ERROR);
308 		}
309 
310 		ci_password[ci_pwlen] = 0;
311 		cs_password[cs_pwlen] = 0;
312 
313 		sr->session->native_os = smbnative_os_value(native_os);
314 
315 		if (sr->session->native_os == NATIVE_OS_WINNT)
316 			rc = smbsr_decode_data(sr, "%,u", sr, &native_lanman);
317 		else
318 			rc = smbsr_decode_data(sr, "%u", sr, &native_lanman);
319 
320 		/*
321 		 * Native Lanman could be null so we really don't care
322 		 * if above decode fails, but to have a valid value for
323 		 * the field we set it to Win NT.
324 		 */
325 		if (rc != 0)
326 			native_lanman = "NT LAN Manager 4.0";
327 
328 	} else {
329 		rc = smbsr_decode_vwv(sr, "b.wwwwlw4.", &sr->andx_com,
330 		    &sr->andx_off, &maxbufsize, &maxmpxcount,
331 		    &vcnumber, &sesskey, &ci_pwlen);
332 
333 		if (rc != 0)
334 			return (SDRC_ERROR);
335 
336 		ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP);
337 		rc = smbsr_decode_data(sr, "%#c", sr, ci_pwlen, ci_password);
338 		if (rc != 0) {
339 			kmem_free(ci_password, ci_pwlen + 1);
340 			return (SDRC_ERROR);
341 		}
342 
343 		ci_password[ci_pwlen] = 0;
344 
345 		/*
346 		 * Despite the CIFS/1.0 spec, the rest of this message is
347 		 * not always present. We need to try to get the account
348 		 * name and the primary domain but we don't care about the
349 		 * the native OS or native LanMan fields.
350 		 */
351 		if (smbsr_decode_data(sr, "%u", sr, &username) != 0)
352 			username = "";
353 
354 		if (smbsr_decode_data(sr, "%u", sr, &userdomain) != 0)
355 			userdomain = "";
356 
357 		sr->session->native_os = NATIVE_OS_UNKNOWN;
358 	}
359 
360 	/*
361 	 * If the vcnumber is zero, we can discard any
362 	 * other connections associated with this client.
363 	 */
364 	sr->session->vcnumber = vcnumber;
365 	if (vcnumber == 0)
366 		smb_server_reconnection_check(sr->sr_server, sr->session);
367 
368 	sr->session->smb_msg_size = maxbufsize;
369 
370 	bzero(&clnt_info, sizeof (netr_client_t));
371 
372 	/*
373 	 * Both local and domain users can be authenticated in
374 	 * domain mode. Whether a user is local or not is determined
375 	 * by given domain name in the request. If client does not
376 	 * specify the domain name, both local and domain
377 	 * authentications should be tried. The preferred order is to
378 	 * try the local authentication first.
379 	 */
380 	known_domain = B_TRUE;
381 	if (*userdomain == 0) {
382 		userdomain = hostname;
383 		if (security == SMB_SECMODE_DOMAIN)
384 			known_domain = B_FALSE;
385 	}
386 
387 	if ((cs_pwlen == 0) &&
388 	    (ci_pwlen == 0 || (ci_pwlen == 1 && *ci_password == 0))) {
389 		/* anonymous user */
390 		clnt_info.flags |= NETR_CFLG_ANON;
391 		username = "nobody";
392 	} else if (*username == '\0') {
393 		if (ci_password)
394 			kmem_free(ci_password, ci_pwlen + 1);
395 		if (cs_password)
396 			kmem_free(cs_password, cs_pwlen + 1);
397 		smbsr_error(sr, 0, ERRSRV, ERRaccess);
398 		return (SDRC_ERROR);
399 #ifndef FIX_6765156
400 	} else if (utf8_strcasecmp(userdomain, hostname) == 0) {
401 		/*
402 		 * When domain name is equal to hostname, it means
403 		 * the user is local even if system is running in
404 		 * domain mode, so perform a local logon.
405 		 */
406 		clnt_info.flags |= NETR_CFLG_LOCAL;
407 #endif
408 	} else if (security == SMB_SECMODE_DOMAIN) {
409 #ifdef FIX_6765156
410 		/*
411 		 * If the system is running in domain mode, domain
412 		 * authentication will be performed only when the client
413 		 * sends the domain that matches either the NetBIOS name
414 		 * or FQDN of the domain. Otherwise, local authentication
415 		 * will be performed.
416 		 */
417 		if (utf8_strcasecmp(userdomain, nbdomain) == 0 ||
418 		    utf8_strcasecmp(userdomain, fqdn) == 0)
419 			clnt_info.flags |= NETR_CFLG_DOMAIN;
420 		else
421 			clnt_info.flags |= NETR_CFLG_LOCAL;
422 #else
423 		clnt_info.flags |= NETR_CFLG_DOMAIN;
424 #endif
425 	} else if (security == SMB_SECMODE_WORKGRP) {
426 		clnt_info.flags |= NETR_CFLG_LOCAL;
427 	}
428 
429 	/*
430 	 * If the domain is unknown, we are unable to determine
431 	 * whether the specified user is local or domain until
432 	 * the authentication has taken place; thus, the user
433 	 * lookup will be postponed until the user is successfully
434 	 * authenticated.
435 	 */
436 	if (known_domain)
437 		user = smb_session_dup_user(sr->session,
438 		    (clnt_info.flags & NETR_CFLG_LOCAL) ?
439 		    hostname : nbdomain, username);
440 
441 	if (user == NULL) {
442 		cred_t		*cr;
443 		uint32_t	privileges;
444 
445 		clnt_info.logon_level = NETR_NETWORK_LOGON;
446 		clnt_info.domain = userdomain;
447 		clnt_info.username = username;
448 		clnt_info.workstation = sr->session->workstation;
449 		clnt_info.ipaddr = sr->session->ipaddr;
450 		clnt_info.local_ipaddr = sr->session->local_ipaddr;
451 		clnt_info.challenge_key.challenge_key_val =
452 		    sr->session->challenge_key;
453 		clnt_info.challenge_key.challenge_key_len =
454 		    sr->session->challenge_len;
455 		clnt_info.nt_password.nt_password_val = cs_password;
456 		clnt_info.nt_password.nt_password_len = cs_pwlen;
457 		clnt_info.lm_password.lm_password_val = ci_password;
458 		clnt_info.lm_password.lm_password_len = ci_pwlen;
459 		clnt_info.native_os = sr->session->native_os;
460 		clnt_info.native_lm = smbnative_lm_value(native_lanman);
461 		clnt_info.local_port = sr->session->s_local_port;
462 
463 		DTRACE_PROBE1(smb__sessionsetup__clntinfo, netr_client_t *,
464 		    &clnt_info);
465 
466 		usr_token = smb_upcall_get_token(&clnt_info);
467 
468 		/*
469 		 * If the domain is unknown and we fail to authenticate
470 		 * the user locally, pass-through authentication will be
471 		 * attempted.
472 		 */
473 		if (!known_domain) {
474 			if (usr_token == NULL) {
475 				clnt_info.domain = nbdomain;
476 				clnt_info.flags &= ~NETR_CFLG_LOCAL;
477 				clnt_info.flags |= NETR_CFLG_DOMAIN;
478 				usr_token = smb_upcall_get_token(&clnt_info);
479 			}
480 
481 			/*
482 			 * Now that the user has successfully been
483 			 * authenticated, the clnt_info.domain is valid.
484 			 * Try to see if the user has already logged in from
485 			 * this session.
486 			 *
487 			 * If this is a subsequent login, a duplicate user
488 			 * instance will be returned. Otherwise, NULL is
489 			 * returned.
490 			 */
491 			if (usr_token != NULL)
492 				user = smb_session_dup_user(sr->session,
493 				    clnt_info.domain, username);
494 		}
495 
496 
497 		/* authentication fails */
498 		if (usr_token == NULL) {
499 			if (ci_password)
500 				kmem_free(ci_password, ci_pwlen + 1);
501 			if (cs_password)
502 				kmem_free(cs_password, cs_pwlen + 1);
503 			smbsr_error(sr, 0, ERRSRV, ERRbadpw);
504 			return (SDRC_ERROR);
505 		}
506 
507 		if (usr_token->tkn_session_key) {
508 			session_key = kmem_alloc(sizeof (smb_session_key_t),
509 			    KM_SLEEP);
510 			(void) memcpy(session_key, usr_token->tkn_session_key,
511 			    sizeof (smb_session_key_t));
512 		}
513 
514 		/* first login */
515 		if (user == NULL) {
516 			cr = smb_cred_create(usr_token, &privileges);
517 			if (cr != NULL) {
518 				user = smb_user_login(sr->session, cr,
519 				    usr_token->tkn_domain_name,
520 				    usr_token->tkn_account_name,
521 				    usr_token->tkn_flags,
522 				    privileges,
523 				    usr_token->tkn_audit_sid);
524 				smb_cred_rele(user->u_cred);
525 
526 				if (user->u_privcred)
527 					smb_cred_rele(user->u_privcred);
528 			}
529 		}
530 		smb_token_free(usr_token);
531 	}
532 
533 	if (ci_password)
534 		kmem_free(ci_password, ci_pwlen + 1);
535 
536 	if (user == NULL) {
537 		if (session_key)
538 			kmem_free(session_key, sizeof (smb_session_key_t));
539 		if (cs_password)
540 			kmem_free(cs_password, cs_pwlen + 1);
541 		smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
542 		return (SDRC_ERROR);
543 	}
544 
545 	sr->user_cr = user->u_cred;
546 	sr->smb_uid = user->u_uid;
547 	sr->uid_user = user;
548 	sr->session->capabilities = capabilities;
549 
550 	/*
551 	 * Check to see if SMB signing is enable, but if it is already turned
552 	 * on leave it.
553 	 * The first authenticated logon provides the MAC key and sequence
554 	 * numbers for signing all further session on the
555 	 * same network connection.
556 	 */
557 	if (!(sr->session->signing.flags & SMB_SIGNING_ENABLED) &&
558 	    (sr->session->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) &&
559 	    (sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
560 	    session_key)
561 		smb_sign_init(sr, session_key, (char *)cs_password, cs_pwlen);
562 
563 	if (cs_password)
564 		kmem_free(cs_password, cs_pwlen + 1);
565 
566 	if (session_key)
567 		kmem_free(session_key, sizeof (smb_session_key_t));
568 
569 	if (!(sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
570 	    (sr->sr_cfg->skc_signing_required)) {
571 		(void) inet_ntop(AF_INET, (char *)&sr->session->ipaddr,
572 		    ipaddr_buf, sizeof (ipaddr_buf));
573 		cmn_err(CE_NOTE,
574 		    "SmbSessonSetupX: client %s is not capable of signing",
575 		    ipaddr_buf);
576 		smbsr_error(sr, NT_STATUS_LOGON_FAILURE,
577 		    ERRDOS, ERROR_LOGON_FAILURE);
578 		return (SDRC_ERROR);
579 	}
580 
581 	/*
582 	 * NT systems use different native OS and native LanMan values
583 	 * dependent on whether they are acting as a client or a server.
584 	 * As a server, NT 4.0 responds with the following values:
585 	 *
586 	 *	NativeOS:	Windows NT 4.0
587 	 *	NativeLM:	NT LAN Manager 4.0
588 	 *
589 	 * We should probably use the same values as NT but this code has
590 	 * been using the product name and "Windows NT 4.0" for a long time
591 	 * and I don't know if a change would cause any problems (see the
592 	 * conditional test below).
593 	 */
594 	rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
595 	    3,
596 	    sr->andx_com,
597 	    -1,			/* andx_off */
598 	    ((user->u_flags & SMB_USER_FLAG_GUEST) ? 1 : 0),
599 	    VAR_BCC,
600 	    sr,
601 	    "Windows NT 4.0",
602 	    "NT LAN Manager 4.0",
603 	    nbdomain);
604 
605 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
606 }
607