/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* This module provides the high level interface to the LSA RPC functions.
*/
#include <strings.h>
#include <unistd.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smb_token.h>
#include <lsalib.h>
/*
* Lookup the given account and returns the account information
* in the passed smb_account_t structure.
*
* The lookup is performed in the following order:
* well known accounts
* local accounts
* domain accounts
*
* If it's established the given account is well know or local
* but the lookup fails for some reason, the next step(s) won't be
* performed.
*
* If the name is a domain account, it may refer to a user, group or
* alias. If it is a local account, its type should be specified
* in the sid_type parameter. In case the account type is unknown
* sid_type should be set to SidTypeUnknown.
*
* account argument could be either [domain\]name or [domain/]name.
*
* Return status:
*
* NT_STATUS_SUCCESS Account is successfully translated
* NT_STATUS_NONE_MAPPED Couldn't translate the account
*/
{
char *slash;
/* \john -> john */
*slash = '\0';
*slash = '\\';
} else {
}
if (status == NT_STATUS_NOT_FOUND) {
if (status == NT_STATUS_SUCCESS)
return (status);
}
}
{
if (!smb_sid_isvalid(sid))
return (NT_STATUS_INVALID_SID);
if (status == NT_STATUS_NOT_FOUND) {
if (status == NT_STATUS_NOT_FOUND)
}
}
/*
* Obtains the primary domain SID and name from the specified server
* (domain controller).
*
* The requested information will be returned via 'info' argument.
*
* Returns NT status codes. (Raw, not LSA-ized)
*/
{
if (status != 0)
return (status);
(void) lsar_close(&domain_handle);
return (status);
}
/*
* Obtains the account domain SID and name from the current server
* (domain controller).
*
* The requested information will be returned via 'info' argument.
*
* Returns NT status codes. (Raw, not LSA-ized)
*/
{
if (status != 0)
return (status);
(void) lsar_close(&domain_handle);
return (status);
}
/*
* lsa_query_dns_domain_info
*
* Obtains the DNS domain info from the specified server
* (domain controller).
*
* The requested information will be returned via 'info' argument.
*
* Returns NT status codes. (Raw, not LSA-ized)
*/
{
if (status != 0)
return (status);
(void) lsar_close(&domain_handle);
return (status);
}
/*
* Enumerate the trusted domains of primary domain.
* This is the basic enumaration call which only returns the
* NetBIOS name of the domain and its SID.
*
* The requested information will be returned via 'info' argument.
*
* Returns NT status codes. (Raw, not LSA-ized)
*/
{
if (status != 0)
return (status);
enum_context = 0;
if (status == NT_STATUS_NO_MORE_ENTRIES) {
/*
* STATUS_NO_MORE_ENTRIES indicates that we
* have all of the available information.
*/
}
(void) lsar_close(&domain_handle);
return (status);
}
/*
* Enumerate the trusted domains of the primary domain.
* This is the extended enumaration call which besides
* NetBIOS name of the domain and its SID, it will return
* the FQDN plus some trust information which is not used.
*
* The requested information will be returned via 'info' argument.
*
* Returns NT status codes. (Raw, not LSA-ized)
*/
{
if (status != 0)
return (status);
enum_context = 0;
info);
if (status == NT_STATUS_NO_MORE_ENTRIES) {
/*
* STATUS_NO_MORE_ENTRIES indicates that we
* have all of the available information.
*/
}
(void) lsar_close(&domain_handle);
return (status);
}
/*
* Lookup well known accounts table
*
* Return status:
*
* NT_STATUS_SUCCESS Account is translated successfully
* NT_STATUS_NOT_FOUND This is not a well known account
* NT_STATUS_NONE_MAPPED Account is found but domains don't match
* NT_STATUS_NO_MEMORY Memory shortage
* NT_STATUS_INTERNAL_ERROR Internal error/unexpected failure
*/
static uint32_t
{
char *wkadom;
return (NT_STATUS_NOT_FOUND);
return (NT_STATUS_INTERNAL_ERROR);
return (NT_STATUS_NONE_MAPPED);
if (!smb_account_validate(info)) {
return (NT_STATUS_NO_MEMORY);
}
return (NT_STATUS_SUCCESS);
}
/*
* Lookup a domain account by its name.
*
* The information is returned in the user_info structure.
* The caller is responsible for allocating and releasing
* this structure.
*
* Returns NT status codes. (LSA-ized)
*/
static uint32_t
{
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
user, &domain_handle);
if (status != 0)
return (lsa_map_status(status));
(void) lsar_close(&domain_handle);
return (status);
}
/*
* lsa_lookup_privs
*
* Request the privileges associated with the specified account. In
* order to get the privileges, we first have to lookup the name on
* the specified domain controller and obtain the appropriate SID.
* The SID can then be used to open the account and obtain the
* account privileges. The results from both the name lookup and the
* privileges are returned in the user_info structure. The caller is
* responsible for allocating and releasing this structure.
*
* Returns NT status codes. (LSA-ized)
*/
/*ARGSUSED*/
{
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
user, &domain_handle);
if (status != 0)
return (lsa_map_status(status));
(void) lsar_close(&domain_handle);
return (status);
}
/*
* lsa_list_privs
*
* List the privileges supported by the specified server.
* This function is only intended for diagnostics.
*
* Returns NT status codes. (LSA-ized)
*/
{
int rc;
int i;
if (status != 0)
return (lsa_map_status(status));
for (i = 0; i < 30; ++i) {
if (rc != 0)
continue;
name, 128);
}
(void) lsar_close(&domain_handle);
return (NT_STATUS_SUCCESS);
}
/*
* lsa_list_accounts
*
* This function can be used to list the accounts in the specified
* domain. For now the SIDs are just listed in the system log.
*
* Returns NT status
*/
static DWORD
{
int i;
do {
&accounts);
if (status != 0)
return (status);
for (i = 0; i < accounts.entries_read; ++i) {
&account_handle) == 0) {
(void) lsar_enum_privs_account(&account_handle,
&ainfo);
(void) lsar_close(&account_handle);
}
}
return (0);
}
/*
* Lookup well known accounts table for the given SID
*
* Return status:
*
* NT_STATUS_SUCCESS Account is translated successfully
* NT_STATUS_NOT_FOUND This is not a well known account
* NT_STATUS_NO_MEMORY Memory shortage
* NT_STATUS_INTERNAL_ERROR Internal error/unexpected failure
*/
static uint32_t
{
char *wkadom;
return (NT_STATUS_NOT_FOUND);
return (NT_STATUS_INTERNAL_ERROR);
if (!smb_account_validate(ainfo)) {
return (NT_STATUS_NO_MEMORY);
}
return (NT_STATUS_SUCCESS);
}
/*
* Lookup a domain account by its SID.
*
* The information is returned in the user_info structure.
* The caller is responsible for allocating and releasing
* this structure.
*
* Returns NT status codes. (LSA-ized)
*/
static uint32_t
{
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
user, &domain_handle);
if (status != 0)
return (lsa_map_status(status));
(void) lsar_close(&domain_handle);
return (status);
}
/*
* Most functions that call the local security authority expect
* only a limited set of status returns. This function maps the
* status we get from talking to our domain controller into one
* that LSA functions can return. Most common errors become:
* NT_STATUS_CANT_ACCESS_DOMAIN_INFO (when no DC etc.)
*/
static uint32_t
{
switch (status) {
case NT_STATUS_SUCCESS:
break;
case NT_STATUS_INVALID_PARAMETER: /* rpc bind */
break;
case NT_STATUS_NO_MEMORY:
break;
case NT_STATUS_BAD_NETWORK_PATH: /* get server addr */
case NT_STATUS_NETWORK_ACCESS_DENIED: /* authentication */
case NT_STATUS_BAD_NETWORK_NAME: /* tree connect */
case NT_STATUS_ACCESS_DENIED: /* open pipe */
break;
default:
break;
}
return (status);
}