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 * This module provides the high level interface to the SAM RPC
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * functions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#include <sys/types.h>
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#include <sys/isa_defs.h>
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#include <sys/byteorder.h>
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <alloca.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libsmb.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libmlsvc.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/ntaccess.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <lsalib.h>
8d7e41661dc4633488e93b13363137523ce59977jose borrego#include <samlib.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#ifdef _LITTLE_ENDIAN
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/* little-endian values on little-endian */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#define htolel(x) ((uint32_t)(x))
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#define letohl(x) ((uint32_t)(x))
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#else /* (BYTE_ORDER == LITTLE_ENDIAN) */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/* little-endian values on big-endian (swap) */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#define letohl(x) BSWAP_32(x)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#define htolel(x) BSWAP_32(x)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#endif /* (BYTE_ORDER == LITTLE_ENDIAN) */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Valid values for the OEM OWF password encryption.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SAM_KEYLEN 16
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossstatic void samr_fill_userpw(struct samr_user_password *, const char *);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossstatic void samr_make_encrypted_password(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_encr_passwd *epw,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *new_pw_clear,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross uint8_t *crypt_key);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Todo: Implement "unjoin" domain, which would use the
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * sam_remove_trust_account code below.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sam_remove_trust_account
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Attempt to remove the workstation trust account for this system.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Administrator access is required to perform this operation.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsam_remove_trust_account(char *server, char *domain)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States char account_name[SMB_SAMACCT_MAXLEN];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States if (smb_getsamaccount(account_name, SMB_SAMACCT_MAXLEN) != 0)
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States return (NT_STATUS_INTERNAL_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (sam_delete_account(server, domain, account_name));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sam_delete_account
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Attempt to remove an account from the SAM database on the specified
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * server.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsam_delete_account(char *server, char *domain_name, char *account_name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t samr_handle;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t domain_handle;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t user_handle;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_account_t ainfo;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross smb_sid_t *sid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD access_mask;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright char user[SMB_USERNAME_MAXLEN];
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION,
55bf511df53aad0fdb7eb3fa349f0308cc05234cas &samr_handle);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (rc != 0)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross sid = samr_lookup_domain(&samr_handle, domain_name);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (sid == NULL) {
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross goto out_samr_hdl;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (struct samr_sid *)sid, &domain_handle);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (status != NT_STATUS_SUCCESS)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross goto out_sid_ptr;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross status = samr_lookup_domain_names(&domain_handle, account_name, &ainfo);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (status != NT_STATUS_SUCCESS)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross goto out_dom_hdl;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross access_mask = STANDARD_RIGHTS_EXECUTE | DELETE;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross status = samr_open_user(&domain_handle, access_mask,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross ainfo.a_rid, &user_handle);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (status != NT_STATUS_SUCCESS)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross goto out_dom_hdl;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross status = samr_delete_user(&user_handle);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) samr_close_handle(&user_handle);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossout_dom_hdl:
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego (void) samr_close_handle(&domain_handle);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossout_sid_ptr:
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross free(sid);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossout_samr_hdl:
55bf511df53aad0fdb7eb3fa349f0308cc05234cas (void) samr_close_handle(&samr_handle);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
55bf511df53aad0fdb7eb3fa349f0308cc05234cas return (status);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas}
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sam_lookup_name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Lookup an account name in the SAM database on the specified domain
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * controller. Provides the account RID on success.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsam_lookup_name(char *server, char *domain_name, char *account_name,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD *rid_ret)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t samr_handle;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t domain_handle;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_account_t ainfo;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct samr_sid *domain_sid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD status;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright char user[SMB_USERNAME_MAXLEN];
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *rid_ret = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION,
55bf511df53aad0fdb7eb3fa349f0308cc05234cas &samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_OPEN_FAILED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego domain_sid = (struct samr_sid *)samr_lookup_domain(&samr_handle,
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego domain_name);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (domain_sid == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) samr_close_handle(&samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_NO_SUCH_DOMAIN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw domain_sid, &domain_handle);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (status == NT_STATUS_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = samr_lookup_domain_names(&domain_handle,
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego account_name, &ainfo);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (status == NT_STATUS_SUCCESS)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego *rid_ret = ainfo.a_rid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) samr_close_handle(&domain_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) samr_close_handle(&samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sam_get_local_domains
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Query a remote server to get the list of local domains that it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * supports.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwDWORD
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsam_get_local_domains(char *server, char *domain_name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mlsvc_handle_t samr_handle;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright char user[SMB_USERNAME_MAXLEN];
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas rc = samr_open(server, domain_name, user, SAM_ENUM_LOCAL_DOMAIN,
55bf511df53aad0fdb7eb3fa349f0308cc05234cas &samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_OPEN_FAILED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = samr_enum_local_domains(&samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) samr_close_handle(&samr_handle);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Set the account control flags on some account for which we
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * have already opened a SAM handle with appropriate rights,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * passed in here as sam_handle, along with the new flags.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon RossDWORD
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossnetr_set_user_control(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross mlsvc_handle_t *user_handle,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross DWORD UserAccountControl)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross{
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_SetUserInfo16 info;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross info.UserAccountControl = UserAccountControl;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross return (samr_set_user_info(user_handle, 16, &info));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross}
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Set the password on some account, for which we have already
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * opened a SAM handle with appropriate rights, passed in here
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * as sam_handle, along with the new password as cleartext.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * This builds a struct SAMPR_USER_INTERNAL5_INFORMATION [MS-SAMR]
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * containing the new password, encrypted with our session key.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon RossDWORD
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossnetr_set_user_password(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross mlsvc_handle_t *user_handle,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *new_pw_clear)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross{
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross unsigned char ssn_key[SMBAUTH_HASH_SZ];
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_SetUserInfo24 info;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (ndr_rpc_get_ssnkey(user_handle, ssn_key, SMBAUTH_HASH_SZ))
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross return (NT_STATUS_INTERNAL_ERROR);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(&info, 0, sizeof (info));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross samr_make_encrypted_password(&info.encr_pw, new_pw_clear, ssn_key);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /* Rather not leave the session key around. */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(ssn_key, 0, sizeof (ssn_key));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross return (samr_set_user_info(user_handle, 24, &info));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross}
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Change a password like NetUserChangePassword(),
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * but where we already know which AD server to use,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * so we don't request the domain name or search for
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * an AD server for that domain here.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon RossDWORD
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossnetr_change_password(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *server,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *account,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *old_pw_clear,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *new_pw_clear)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_encr_passwd epw;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_encr_hash old_hash;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross uint8_t old_nt_hash[SAMR_PWHASH_LEN];
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross uint8_t new_nt_hash[SAMR_PWHASH_LEN];
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross mlsvc_handle_t handle;
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross DWORD status;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Create an RPC handle to this server, bound to SAMR.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = ndr_rpc_bind(&handle, server, "", "", "SAMR");
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross if (status != NT_STATUS_SUCCESS)
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (status);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Encrypt the new p/w (plus random filler) with the
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * old password, and send the old p/w encrypted with
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * the new p/w hash to prove we know the old p/w.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Details: [MS-SAMR 3.1.5.10.3]
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) smb_auth_ntlm_hash(old_pw_clear, old_nt_hash);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) smb_auth_ntlm_hash(new_pw_clear, new_nt_hash);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross samr_make_encrypted_password(&epw, new_pw_clear, old_nt_hash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) smb_auth_DES(old_hash.data, SAMR_PWHASH_LEN,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross new_nt_hash, 14, /* key */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross old_nt_hash, SAMR_PWHASH_LEN);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Finally, ready to try the OtW call.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross status = samr_change_password(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross &handle, server, account,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross &epw, &old_hash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /* Avoid leaving cleartext (or equivalent) around. */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(old_nt_hash, 0, sizeof (old_nt_hash));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(new_nt_hash, 0, sizeof (new_nt_hash));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross ndr_rpc_unbind(&handle);
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross return (status);
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Build an encrypted password, as used by samr_set_user_info
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * and samr_change_password. Note: This builds the unencrypted
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * form in one union arm, and encrypts it in the other union arm.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossvoid
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rosssamr_make_encrypted_password(
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_encr_passwd *epw,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross char *new_pw_clear,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross uint8_t *crypt_key)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross{
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross union {
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_user_password u;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross struct samr_encr_passwd e;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross } pwu;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross samr_fill_userpw(&pwu.u, new_pw_clear);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) smb_auth_RC4(pwu.e.data, sizeof (pwu.e.data),
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross crypt_key, SAMR_PWHASH_LEN,
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross pwu.e.data, sizeof (pwu.e.data));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memcpy(epw->data, pwu.e.data, sizeof (pwu.e.data));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(pwu.e.data, 0, sizeof (pwu.e.data));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
8d7e41661dc4633488e93b13363137523ce59977jose borrego
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross/*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * This fills in a samr_user_password (a.k.a. SAMPR_USER_PASSWORD
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * in the MS Net API) which has the new password "right justified"
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * in the buffer, and any space on the left filled with random junk
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * to improve the quality of the encryption that is subsequently
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * applied to this buffer before it goes over the wire.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rossstatic void
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Rosssamr_fill_userpw(struct samr_user_password *upw, const char *new_pw)
8d7e41661dc4633488e93b13363137523ce59977jose borrego{
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross smb_wchar_t *pbuf;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross uint32_t pwlen_bytes;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross size_t pwlen_wchars;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * First fill the whole buffer with the random junk.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * (Slightly less random when debugging:)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#ifdef DEBUG
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) memset(upw->Buffer, '*', sizeof (upw->Buffer));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#else
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross randomize((char *)upw->Buffer, sizeof (upw->Buffer));
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross#endif
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /*
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * Now overwrite the last pwlen characters of
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * that buffer with the password, and set the
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * length field so the receiving end knows where
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross * the junk ends and the real password starts.
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross pwlen_wchars = smb_wcequiv_strlen(new_pw) / 2;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross if (pwlen_wchars > SAMR_USER_PWLEN)
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross pwlen_wchars = SAMR_USER_PWLEN;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross pwlen_bytes = pwlen_wchars * 2;
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross pbuf = &upw->Buffer[SAMR_USER_PWLEN - pwlen_wchars];
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross (void) smb_mbstowcs(pbuf, new_pw, pwlen_wchars);
8d7e41661dc4633488e93b13363137523ce59977jose borrego
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross /* Yes, this is in Bytes, not wchars. */
1ed6b69a5ca1ca3ee5e9a4931f74e2237c7e1c9fGordon Ross upw->Length = htolel(pwlen_bytes);
8d7e41661dc4633488e93b13363137523ce59977jose borrego}