mlsvc_domain.c revision 380acbbe9da7dc2cbab5b6db169ec6968dd927fa
/*
* 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 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <syslog.h>
#include <synch.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <resolv.h>
#include <netdb.h>
#include <assert.h>
#include <smbsrv/libsmbns.h>
#include <smbsrv/libmlsvc.h>
#include <lsalib.h>
/*
* DC Locator
*/
typedef struct smb_dclocator {
char sdl_domain[SMB_PI_MAX_DOMAIN];
char sdl_dc[MAXHOSTNAMELEN];
static smb_dclocator_t smb_dclocator;
static pthread_t smb_dclocator_thr;
static void *smb_ddiscover_service(void *);
static void smb_ddiscover_main(char *, char *);
static void smb_ddiscover_enum_trusted(char *, char *, smb_domainex_t *);
static void smb_domainex_free(smb_domainex_t *);
/*
* ===================================================================
* API to initialize DC locator thread, trigger DC discovery, and
* ===================================================================
*/
/*
* Initialization of the DC locator thread.
* Returns 0 on success, an error number if thread creation fails.
*/
int
smb_dclocator_init(void)
{
int rc;
(void) pthread_attr_init(&tattr);
(void) pthread_attr_destroy(&tattr);
return (rc);
}
/*
* This is the entry point for discovering a domain controller for the
* specified domain.
*
* The actual work of discovering a DC is handled by DC locator thread.
* All we do here is signal the request and wait for a DC or a timeout.
*
* Input parameters:
* domain - domain to be discovered (can either be NetBIOS or DNS domain)
* dc - preferred DC. If the preferred DC is set to empty string, it
* will attempt to discover any DC in the specified domain.
*
* Output parameter:
* dp - on success, dp will be filled with the discovered DC and domain
* information.
*/
{
int rc;
return (B_FALSE);
if (!smb_dclocator.sdl_locate) {
}
while (smb_dclocator.sdl_locate) {
break;
}
dp = &domain_info;
return (rc);
}
/*
* If domain discovery is running, wait for it to finish.
*/
int
smb_ddiscover_wait(void)
{
int rc = 0;
if (smb_dclocator.sdl_locate) {
}
return (rc);
}
/*
* ==========================================================
* DC discovery functions
* ==========================================================
*/
/*
* This is the domain and DC discovery service: it gets woken up whenever
* there is need to locate a domain controller.
*
* Upon success, the SMB domain cache will be populated with the discovered
* DC and domain info.
*/
/*ARGSUSED*/
static void *
smb_ddiscover_service(void *arg)
{
char domain[SMB_PI_MAX_DOMAIN];
char sought_dc[MAXHOSTNAMELEN];
for (;;) {
while (!smb_dclocator.sdl_locate)
}
/*NOTREACHED*/
return (NULL);
}
/*
* Discovers a domain controller for the specified domain either via
* DNS or NetBIOS. After the domain controller is discovered successfully
* primary and trusted domain infromation will be queried using RPC queries.
* If the RPC queries fail, the domain information stored in SMF might be used
* if the the discovered domain is the same as the previously joined domain.
* If everything is successful domain cache will be updated with all the
* obtained information.
*/
static void
{
if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS)
return;
if (SMB_IS_FQDN(domain))
else
if (discovered)
if (discovered)
}
/*
* Discovers a DC for the specified domain via DNS. If a DC is found
* primary and trusted domains information will be queried.
*/
static boolean_t
{
return (B_FALSE);
return (status == NT_STATUS_SUCCESS);
}
/*
* Discovers a DC for the specified domain using NETLOGON protocol.
* If a DC cannot be found using NETLOGON then it will
* try to resolve it via DNS, i.e. find out if it is the first label
* of a DNS domain name. If the corresponding DNS name is found, DC
* discovery will be done via DNS query.
*
* If the fully-qualified domain name is derived from the DNS config
* file, the NetBIOS domain name specified by the user will be compared
* against the NetBIOS domain name obtained via LSA query. If there is
* a mismatch, the DC discovery will fail since the discovered DC is
* actually for another domain, whose first label of its FQDN somehow
* matches with the NetBIOS name of the domain we're interested in.
*/
static boolean_t
{
char dnsdomain[MAXHOSTNAMELEN];
*dnsdomain = '\0';
return (B_FALSE);
return (B_FALSE);
}
if (status != NT_STATUS_SUCCESS)
return (B_FALSE);
if ((*dnsdomain != '\0') &&
return (B_FALSE);
/*
* Now that we get the fully-qualified DNS name of the
* domain via LSA query. Verifies ADS configuration
* if we previously locate a DC via NetBIOS. On success,
* ADS cache will be populated.
*/
return (B_FALSE);
return (B_TRUE);
}
/*
* Tries to find a matching DNS domain for the given NetBIOS domain
* name by checking the first label of system's configured DNS domains.
* If a match is found, it'll be returned in the passed buffer.
*/
static boolean_t
{
struct __res_state res_state;
int i;
char *entry, *p;
char first_label[MAXHOSTNAMELEN];
return (B_FALSE);
*buf = '\0';
return (B_FALSE);
*p = '\0';
}
break;
}
}
return (found);
}
/*
* Obtain primary and trusted domain information using LSA queries.
*
* Disconnect any existing connection with the domain controller.
* This will ensure that no stale connection will be used, it will
* also pickup any configuration changes in either side by trying
* to establish a new connection.
*
* domain - either NetBIOS or fully-qualified domain name
*/
static uint32_t
{
if (status != NT_STATUS_SUCCESS) {
if (status != NT_STATUS_SUCCESS)
}
if (status == NT_STATUS_SUCCESS)
return (status);
}
/*
* Obtain trusted domains information using LSA queries.
*
* domain - either NetBIOS or fully-qualified domain name.
*/
static void
{
if (status != NT_STATUS_SUCCESS)
}
/*
* If the domain to be discovered matches the current domain (i.e the
* value of either domain or fqdn configuration), then get the primary
* domain information from SMF.
*/
static uint32_t
{
if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
return (NT_STATUS_UNSUCCESSFUL);
if (SMB_IS_FQDN(domain))
else
if (use)
}
static void
{
}