da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NETR challenge/response client functions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NT_STATUS_INVALID_PARAMETER
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NT_STATUS_NO_TRUST_SAM_ACCOUNT
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NT_STATUS_ACCESS_DENIED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <stdio.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <stdlib.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <strings.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <unistd.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <ctype.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <security/cryptoki.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <security/pkcs11.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libsmb.h>
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas#include <smbsrv/libsmbns.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <smbsrv/libmlsvc.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/ndl/netlogon.ndl>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smbinfo.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/netrauth.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw#define NETR_SESSKEY_ZEROBUF_SZ 4
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego/* The DES algorithm uses a 56-bit encryption key. */
3db3f65c6274eb042354801a308c8e9bc4994553amw#define NETR_DESKEY_LEN 7
3db3f65c6274eb042354801a308c8e9bc4994553amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint netr_setup_authenticator(netr_info_t *, struct netr_authenticator *,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct netr_authenticator *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD netr_validate_chain(netr_info_t *, struct netr_authenticator *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int netr_server_req_challenge(mlsvc_handle_t *, netr_info_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int netr_server_authenticate2(mlsvc_handle_t *, netr_info_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int netr_gen_password(BYTE *, BYTE *, BYTE *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Shared with netr_logon.c
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_info_t netr_global_info;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netlogon_auth
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is the core of the NETLOGON authentication protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Do the challenge response authentication.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Prior to calling this function, an anonymous session to the NETLOGON
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * pipe on a domain controller(server) should have already been opened.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * Upon a successful NETLOGON credential chain establishment, the
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * netlogon sequence number will be set to match the kpasswd sequence
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * number.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetlogon_auth(char *server, mlsvc_handle_t *netr_handle, DWORD flags)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info_t *netr_info;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas DWORD leout_rc[2];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info = &netr_global_info;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(netr_info, sizeof (netr_info_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info->flags |= flags;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States rc = smb_getnetbiosname(netr_info->hostname, NETBIOS_NAME_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_UNSUCCESSFUL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* server is our DC. Note: normally an FQDN. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) snprintf(netr_info->server, sizeof (netr_info->server),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\\\\%s", server);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&leout_rc[0], random());
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&leout_rc[1], random());
55bf511df53aad0fdb7eb3fa349f0308cc05234cas (void) memcpy(&netr_info->client_challenge, leout_rc,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (struct netr_credential));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((rc = netr_server_req_challenge(netr_handle, netr_info)) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = netr_server_authenticate2(netr_handle, netr_info);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (rc == 0) {
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * TODO: (later) When joining a domain using a
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * pre-created machine account, should do:
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * netr_server_password_set(&netr_handle, netr_info);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Nexenta issue 11960
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_update_netlogon_seqnum();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info->flags |= NETR_FLG_VALID;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ((rc) ? NT_STATUS_UNSUCCESSFUL : NT_STATUS_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_open
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Open an anonymous session to the NETLOGON pipe on a domain controller
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * and bind to the NETR RPC interface.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * We store the remote server information, which is used to drive Windows
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * version specific behavior.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross *
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Returns 0 or NT status
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon RossDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_open(char *server, char *domain, mlsvc_handle_t *netr_handle)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright char user[SMB_USERNAME_MAXLEN];
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross DWORD status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = ndr_rpc_bind(netr_handle, server, domain, user, "NETR");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_close
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Close a NETLOGON pipe and free the RPC context.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_close(mlsvc_handle_t *netr_handle)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_unbind(netr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_server_req_challenge
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_server_req_challenge(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct netr_ServerReqChallenge arg;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int opnum;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(&arg, sizeof (struct netr_ServerReqChallenge));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw opnum = NETR_OPNUM_ServerReqChallenge;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.servername = (unsigned char *)netr_info->server;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.hostname = (unsigned char *)netr_info->hostname;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) memcpy(&arg.client_challenge, &netr_info->client_challenge,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (struct netr_credential));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (ndr_rpc_call(netr_handle, opnum, &arg) != 0)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (arg.status != 0) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_status(netr_handle, opnum, arg.status);
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego (void) memcpy(&netr_info->server_challenge, &arg.server_challenge,
8d7e41661dc4633488e93b13363137523ce59977jose borrego sizeof (struct netr_credential));
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_server_authenticate2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct netr_ServerAuthenticate2 arg;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross /* sizeof netr_info->hostname, + 1 for the '$' */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross char account_name[(NETBIOS_NAME_SZ * 2) + 1];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int opnum;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(&arg, sizeof (struct netr_ServerAuthenticate2));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw opnum = NETR_OPNUM_ServerAuthenticate2;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) snprintf(account_name, sizeof (account_name), "%s$",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info->hostname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego smb_tracef("server=[%s] account_name=[%s] hostname=[%s]\n",
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego netr_info->server, account_name, netr_info->hostname);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.servername = (unsigned char *)netr_info->server;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.account_name = (unsigned char *)account_name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.account_type = NETR_WKSTA_TRUST_ACCOUNT_TYPE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.hostname = (unsigned char *)netr_info->hostname;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego arg.negotiate_flags = NETR_NEGOTIATE_BASE_FLAGS;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright if (ndr_rpc_server_os(netr_handle) == NATIVE_OS_WIN2000) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego arg.negotiate_flags |= NETR_NEGOTIATE_STRONGKEY_FLAG;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (netr_gen_skey128(netr_info) != SMBAUTH_SUCCESS)
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego return (-1);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego } else {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (netr_gen_skey64(netr_info) != SMBAUTH_SUCCESS)
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego return (-1);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (netr_gen_credentials(netr_info->session_key.key,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego &netr_info->client_challenge, 0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &netr_info->client_credential) != SMBAUTH_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (netr_gen_credentials(netr_info->session_key.key,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego &netr_info->server_challenge, 0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &netr_info->server_credential) != SMBAUTH_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) memcpy(&arg.client_credential, &netr_info->client_credential,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (struct netr_credential));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (ndr_rpc_call(netr_handle, opnum, &arg) != 0)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (arg.status != 0) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_status(netr_handle, opnum, arg.status);
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego rc = memcmp(&netr_info->server_credential, &arg.server_credential,
8d7e41661dc4633488e93b13363137523ce59977jose borrego sizeof (struct netr_credential));
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * netr_gen_skey128
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * Generate a 128-bit session key from the client and server challenges.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * See "Session-Key Computation" section of MS-NRPC document.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwint
2c1b14e51525da2c09064641416fc4aed457c72fjose borregonetr_gen_skey128(netr_info_t *netr_info)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw unsigned char ntlmhash[SMBAUTH_HASH_SZ];
3db3f65c6274eb042354801a308c8e9bc4994553amw int rc = SMBAUTH_FAILURE;
3db3f65c6274eb042354801a308c8e9bc4994553amw CK_RV rv;
3db3f65c6274eb042354801a308c8e9bc4994553amw CK_MECHANISM mechanism;
3db3f65c6274eb042354801a308c8e9bc4994553amw CK_SESSION_HANDLE hSession;
3db3f65c6274eb042354801a308c8e9bc4994553amw CK_ULONG diglen = MD_DIGEST_LEN;
3db3f65c6274eb042354801a308c8e9bc4994553amw unsigned char md5digest[MD_DIGEST_LEN];
3db3f65c6274eb042354801a308c8e9bc4994553amw unsigned char zerobuf[NETR_SESSKEY_ZEROBUF_SZ];
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(ntlmhash, SMBAUTH_HASH_SZ);
3db3f65c6274eb042354801a308c8e9bc4994553amw /*
3db3f65c6274eb042354801a308c8e9bc4994553amw * We should check (netr_info->flags & NETR_FLG_INIT) and use
3db3f65c6274eb042354801a308c8e9bc4994553amw * the appropriate password but it isn't working yet. So we
3db3f65c6274eb042354801a308c8e9bc4994553amw * always use the default one for now.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(netr_info->password, sizeof (netr_info->password));
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD,
3db3f65c6274eb042354801a308c8e9bc4994553amw (char *)netr_info->password, sizeof (netr_info->password));
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((rc != SMBD_SMF_OK) || *netr_info->password == '\0') {
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMBAUTH_FAILURE);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = smb_auth_ntlm_hash((char *)netr_info->password, ntlmhash);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rc != SMBAUTH_SUCCESS)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMBAUTH_FAILURE);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(zerobuf, NETR_SESSKEY_ZEROBUF_SZ);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw mechanism.mechanism = CKM_MD5;
3db3f65c6274eb042354801a308c8e9bc4994553amw mechanism.pParameter = 0;
3db3f65c6274eb042354801a308c8e9bc4994553amw mechanism.ulParameterLen = 0;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = SUNW_C_GetMechSession(mechanism.mechanism, &hSession);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMBAUTH_FAILURE);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = C_DigestInit(hSession, &mechanism);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw goto cleanup;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = C_DigestUpdate(hSession, (CK_BYTE_PTR)zerobuf,
3db3f65c6274eb042354801a308c8e9bc4994553amw NETR_SESSKEY_ZEROBUF_SZ);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw goto cleanup;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = C_DigestUpdate(hSession,
3db3f65c6274eb042354801a308c8e9bc4994553amw (CK_BYTE_PTR)netr_info->client_challenge.data, NETR_CRED_DATA_SZ);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw goto cleanup;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = C_DigestUpdate(hSession,
3db3f65c6274eb042354801a308c8e9bc4994553amw (CK_BYTE_PTR)netr_info->server_challenge.data, NETR_CRED_DATA_SZ);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw goto cleanup;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = C_DigestFinal(hSession, (CK_BYTE_PTR)md5digest, &diglen);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rv != CKR_OK)
3db3f65c6274eb042354801a308c8e9bc4994553amw goto cleanup;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = smb_auth_hmac_md5(md5digest, diglen, ntlmhash, SMBAUTH_HASH_SZ,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego netr_info->session_key.key);
3db3f65c6274eb042354801a308c8e9bc4994553amw
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego netr_info->session_key.len = NETR_SESSKEY128_SZ;
3db3f65c6274eb042354801a308c8e9bc4994553amwcleanup:
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) C_CloseSession(hSession);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (rc);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw}
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego/*
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * netr_gen_skey64
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * Generate a 64-bit session key from the client and server challenges.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * See "Session-Key Computation" section of MS-NRPC document.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * The algorithm is a two stage hash. For the first hash, the input is
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * the combination of the client and server challenges, the key is
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * the first 7 bytes of the password. The initial password is formed
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * using the NT password hash on the local hostname in lower case.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * The result is stored in a temporary buffer.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * input: challenge
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * key: passwd lower 7 bytes
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * output: intermediate result
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * For the second hash, the input is the result of the first hash and
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * the key is the last 7 bytes of the password.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * input: result of first hash
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * key: passwd upper 7 bytes
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * output: session_key
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * The final output should be the session key.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * FYI: smb_auth_DES(output, key, input)
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * If any difficulties occur using the cryptographic framework, the
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * function returns SMBAUTH_FAILURE. Otherwise SMBAUTH_SUCCESS is
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * returned.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
2c1b14e51525da2c09064641416fc4aed457c72fjose borregonetr_gen_skey64(netr_info_t *netr_info)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char md4hash[32];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char buffer[8];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD data[2];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD *client_challenge;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD *server_challenge;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas DWORD le_data[2];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw client_challenge = (DWORD *)(uintptr_t)&netr_info->client_challenge;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw server_challenge = (DWORD *)(uintptr_t)&netr_info->server_challenge;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(md4hash, 32);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * We should check (netr_info->flags & NETR_FLG_INIT) and use
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the appropriate password but it isn't working yet. So we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * always use the default one for now.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as bzero(netr_info->password, sizeof (netr_info->password));
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (char *)netr_info->password, sizeof (netr_info->password));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if ((rc != SMBD_SMF_OK) || *netr_info->password == '\0') {
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMBAUTH_FAILURE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rc = smb_auth_ntlm_hash((char *)netr_info->password, md4hash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != SMBAUTH_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMBAUTH_FAILURE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw data[0] = LE_IN32(&client_challenge[0]) + LE_IN32(&server_challenge[0]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw data[1] = LE_IN32(&client_challenge[1]) + LE_IN32(&server_challenge[1]);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&le_data[0], data[0]);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&le_data[1], data[1]);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego rc = smb_auth_DES(buffer, 8, md4hash, NETR_DESKEY_LEN,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego (unsigned char *)le_data, 8);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != SMBAUTH_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego netr_info->session_key.len = NETR_SESSKEY64_SZ;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego rc = smb_auth_DES(netr_info->session_key.key,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego netr_info->session_key.len, &md4hash[9], NETR_DESKEY_LEN, buffer,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego 8);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_gen_credentials
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Generate a set of credentials from a challenge and a session key.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The algorithm is a two stage hash. For the first hash, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * timestamp is added to the challenge and the result is stored in a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * temporary buffer:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * input: challenge (including timestamp)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * key: session_key
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * output: intermediate result
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * For the second hash, the input is the result of the first hash and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a strange partial key is used:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * input: result of first hash
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * key: funny partial key
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * output: credentiails
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The final output should be an encrypted set of credentials.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FYI: smb_auth_DES(output, key, input)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If any difficulties occur using the cryptographic framework, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * function returns SMBAUTH_FAILURE. Otherwise SMBAUTH_SUCCESS is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * returned.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_gen_credentials(BYTE *session_key, netr_cred_t *challenge,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD timestamp, netr_cred_t *out_cred)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char buffer[8];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD data[2];
55bf511df53aad0fdb7eb3fa349f0308cc05234cas DWORD le_data[2];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD *p;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw p = (DWORD *)(uintptr_t)challenge;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas data[0] = LE_IN32(&p[0]) + timestamp;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas data[1] = LE_IN32(&p[1]);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&le_data[0], data[0]);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas LE_OUT32(&le_data[1], data[1]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_auth_DES(buffer, 8, session_key, NETR_DESKEY_LEN,
55bf511df53aad0fdb7eb3fa349f0308cc05234cas (unsigned char *)le_data, 8) != SMBAUTH_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMBAUTH_FAILURE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = smb_auth_DES(out_cred->data, 8, &session_key[NETR_DESKEY_LEN],
3db3f65c6274eb042354801a308c8e9bc4994553amw NETR_DESKEY_LEN, buffer, 8);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_server_password_set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Attempt to change the trust account password for this system.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Note that this call may legitimately fail if the registry on the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * domain controller has been setup to deny attempts to change the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * trust account password. In this case we should just continue to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * use the original password.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Possible status values:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NT_STATUS_ACCESS_DENIED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_server_password_set(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct netr_PasswordSet arg;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int opnum;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw BYTE new_password[NETR_OWF_PASSWORD_SZ];
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States char account_name[NETBIOS_NAME_SZ * 2];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(&arg, sizeof (struct netr_PasswordSet));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw opnum = NETR_OPNUM_ServerPasswordSet;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) snprintf(account_name, sizeof (account_name), "%s$",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info->hostname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.servername = (unsigned char *)netr_info->server;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.account_name = (unsigned char *)account_name;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross arg.sec_chan_type = NETR_WKSTA_TRUST_ACCOUNT_TYPE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw arg.hostname = (unsigned char *)netr_info->hostname;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set up the client side authenticator.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (netr_setup_authenticator(netr_info, &arg.auth, 0) !=
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMBAUTH_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Generate a new password from the old password.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (netr_gen_password(netr_info->session_key.key,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw netr_info->password, new_password) == SMBAUTH_FAILURE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memcpy(&arg.owf_password, &new_password,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw NETR_OWF_PASSWORD_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (ndr_rpc_call(netr_handle, opnum, &arg) != 0)
8d7e41661dc4633488e93b13363137523ce59977jose borrego return (-1);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego if (arg.status != 0) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_status(netr_handle, opnum, arg.status);
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check the returned credentials. The server returns the new
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * client credential rather than the new server credentiali,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * as documented elsewhere.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Generate the new seed for the credential chain. Increment
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the timestamp and add it to the client challenge. Then we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * need to copy the challenge to the credential field in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * preparation for the next cycle.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (netr_validate_chain(netr_info, &arg.auth) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Save the new password.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) memcpy(netr_info->password, new_password,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw NETR_OWF_PASSWORD_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego ndr_rpc_release(netr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netr_gen_password
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Generate a new pasword from the old password and the session key.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The algorithm is a two stage hash. The session key is used in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * first hash but only part of the session key is used in the second
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * hash.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If any difficulties occur using the cryptographic framework, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * function returns SMBAUTH_FAILURE. Otherwise SMBAUTH_SUCCESS is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * returned.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetr_gen_password(BYTE *session_key, BYTE *old_password, BYTE *new_password)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rv;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = smb_auth_DES(new_password, 8, session_key, NETR_DESKEY_LEN,
3db3f65c6274eb042354801a308c8e9bc4994553amw old_password, 8);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rv != SMBAUTH_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rv);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rv = smb_auth_DES(&new_password[8], 8, &session_key[NETR_DESKEY_LEN],
3db3f65c6274eb042354801a308c8e9bc4994553amw NETR_DESKEY_LEN, &old_password[8], 8);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rv);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Todo: need netr_server_password_set2()
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * used by "unsecure join". (NX 11960)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */