smb_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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
* This file defines the domain environment values and the domain
* database interface. The database is a single linked list of
* structures containing domain type, name and SID information.
*/
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <synch.h>
#include <pwd.h>
#include <grp.h>
#include <assert.h>
#define SMB_DOMAINS_FILE "domains"
/*
* Domain cache states
*/
#define SMB_DCACHE_STATE_NONE 0
#define SMB_DCACHE_STATE_READY 1
#define SMB_DCACHE_STATE_UPDATING 2
#define SMB_DCACHE_STATE_DESTROYING 3
/*
* Cache lock modes
*/
#define SMB_DCACHE_RDLOCK 0
#define SMB_DCACHE_WRLOCK 1
typedef struct smb_domain_cache {
char dc_server[MAXHOSTNAMELEN];
static smb_domain_cache_t smb_dcache;
static uint32_t smb_domain_add_local(void);
static void smb_domain_unlink(void);
static void smb_dcache_create(void);
static void smb_dcache_destroy(void);
static uint32_t smb_dcache_lock(int);
static void smb_dcache_unlock(void);
static void smb_dcache_remove(smb_domain_t *);
static void smb_dcache_getdc(char *, size_t);
static void smb_dcache_setdc(char *);
static boolean_t smb_dcache_wait(void);
static uint32_t smb_dcache_updating(void);
static void smb_dcache_ready(void);
/*
* domain cache one time initialization. This function should
* only be called during service startup.
*
* Returns 0 on success and an error code on failure.
*/
int
{
int rc;
if ((rc = smb_domain_add_local()) != 0)
return (rc);
return (smb_domain_add_primary(secmode));
}
/*
* Destroys the cache upon service termination
*/
void
smb_domain_fini(void)
{
}
/*
* Add a domain structure to domain cache. There is no checking
* for duplicates.
*/
static uint32_t
{
return (SMB_DOMAIN_INVALID_ARG);
}
return (res);
}
/*
* Lookup a domain by its name. The passed name is the NETBIOS or fully
* qualified DNS name or non-qualified DNS name.
*
* If the requested domain is found and given 'di' pointer is not NULL
* it'll be filled with the domain information and B_TRUE is returned.
* If the caller only needs to check a domain existence it can pass
* NULL for 'di' and just check the return value.
*
* If the domain is not in the cache B_FALSE is returned.
*/
{
char *p;
return (B_FALSE);
return (B_FALSE);
while (dcnode) {
if (found) {
if (di)
break;
}
*p = '\0';
0) == 0);
*p = '.';
if (found) {
if (di)
break;
}
}
}
return (found);
}
/*
* Lookup a domain by its SID.
*
* If the requested domain is found and given 'di' pointer is not NULL
* it'll be filled with the domain information and B_TRUE is returned.
* If the caller only needs to check a domain existence it can pass
* NULL for 'di' and just check the return value.
*
* If the domain is not in the cache B_FALSE is returned.
*/
{
char sidstr[SMB_SID_STRSZ];
return (B_FALSE);
return (B_FALSE);
while (dcnode) {
if (found) {
if (di)
break;
}
}
return (found);
}
/*
* Lookup a domain by its type.
*
* If the requested domain is found and given 'di' pointer is not NULL
* it'll be filled with the domain information and B_TRUE is returned.
* If the caller only needs to check a domain existence it can pass
* NULL for 'di' and just check the return value.
*
* If the domain is not in the cache B_FALSE is returned.
*/
{
return (B_FALSE);
while (dcnode) {
if (di)
break;
}
}
return (found);
}
/*
* Returns primary domain information plus the name of
* the selected domain controller.
*/
{
if (success)
return (success);
}
/*
* Get the name of the current DC (if any)
* Does NOT block.
*/
void
{
}
/*
* Transfer the cache to updating state.
* In this state any request for reading the cache would
* be blocked until the update is finished.
*/
smb_domain_start_update(void)
{
return (smb_dcache_updating());
}
/*
* Transfer the cache from updating to ready state.
*/
void
smb_domain_end_update(void)
{
}
/*
* Updates the cache with given information for the primary
* domain, possible trusted domains and the selected domain
* controller.
*
* Before adding the new entries existing entries of type
* primary and trusted will be removed from cache.
*/
void
{
int i;
return;
while (dcnode) {
} else {
}
}
}
}
/*
*/
void
smb_domain_save(void)
{
char fname[MAXPATHLEN];
char tag;
return;
return;
while (domain) {
case SMB_DOMAIN_PRIMARY:
tag = '*';
break;
case SMB_DOMAIN_TRUSTED:
case SMB_DOMAIN_UNTRUSTED:
tag = '-';
break;
case SMB_DOMAIN_LOCAL:
tag = '.';
break;
default:
continue;
}
}
}
/*
*/
void
smb_domain_show(void)
{
char buf[MAXPATHLEN];
char *p;
*p = '\0';
}
}
}
void
{
return;
}
void
{
return;
}
void
{
return;
}
/*
*/
static void
smb_domain_unlink(void)
{
char fname[MAXPATHLEN];
}
/*
* Add an entry for the local domain to the domain cache
*/
static uint32_t
smb_domain_add_local(void)
{
char *lsidstr;
char hostname[NETBIOS_NAME_SZ];
char fq_name[MAXHOSTNAMELEN];
return (SMB_DOMAIN_NOMACHINE_SID);
return (SMB_DOMAIN_NOMACHINE_SID);
}
*fq_name = '\0';
return (SMB_DOMAIN_SUCCESS);
}
/*
* Add an entry for the primary domain to the domain cache
*/
static uint32_t
{
char sidstr[SMB_SID_STRSZ];
char fq_name[MAXHOSTNAMELEN];
char nb_name[NETBIOS_NAME_SZ];
int rc;
if (secmode != SMB_SECMODE_DOMAIN)
return (SMB_DOMAIN_SUCCESS);
if (rc != SMBD_SMF_OK)
return (SMB_DOMAIN_NODOMAIN_SID);
return (SMB_DOMAIN_NODOMAIN_NAME);
return (SMB_DOMAIN_SUCCESS);
}
/*
* Initialize the domain cache.
* This function does not populate the cache.
*/
static void
smb_dcache_create(void)
{
return;
}
smb_dcache.dc_nops = 0;
}
/*
* Removes and frees all the cache entries
*/
static void
smb_dcache_flush(void)
{
}
/*
* Destroys the cache.
*/
static void
smb_dcache_destroy(void)
{
while (smb_dcache.dc_nops > 0)
&smb_dcache.dc_mtx);
}
}
/*
* Lock the cache with the specified mode.
* If the cache is in updating state and a read lock is
* requested, the lock won't be granted until either the
* update is finished or SMB_DCACHE_UPDATE_WAIT has passed.
*
* Whenever a lock is granted, the number of inflight cache
* operations is incremented.
*/
static uint32_t
smb_dcache_lock(int mode)
{
switch (smb_dcache.dc_state) {
case SMB_DCACHE_STATE_NONE:
return (SMB_DOMAIN_INTERNAL_ERR);
if (mode == SMB_DCACHE_RDLOCK) {
/*
* Read operations should wait until the update
* is completed.
*/
if (!smb_dcache_wait()) {
return (SMB_DOMAIN_INTERNAL_ERR);
}
}
default:
break;
}
/*
* Lock has to be taken outside the mutex otherwise
* there could be a deadlock
*/
if (mode == SMB_DCACHE_RDLOCK)
else
return (SMB_DOMAIN_SUCCESS);
}
/*
* Decrement the number of inflight operations and then unlock.
*/
static void
smb_dcache_unlock(void)
{
}
static uint32_t
{
return (SMB_DOMAIN_NO_MEMORY);
return (SMB_DOMAIN_NO_MEMORY);
}
return (SMB_DOMAIN_SUCCESS);
}
static void
{
}
static void
smb_dcache_setdc(char *dc)
{
}
static void
{
}
/*
* Waits for SMB_DCACHE_UPDATE_WAIT seconds if cache is in
* UPDATING state. Upon wake up returns true if cache is
* ready to be used, otherwise it returns false.
*/
static boolean_t
smb_dcache_wait(void)
{
int err;
break;
}
}
/*
* Transfers the cache into UPDATING state, this will ensure
* any read access to the cache will be stalled until the
* update is finished. This is to avoid providing incomplete,
* inconsistent or stale information.
*
* If another thread is already updating the cache, other
* callers will wait until cache is no longer in UPDATING
* state. The return code is decided based on the new
* state of the cache.
*/
static uint32_t
smb_dcache_updating(void)
{
switch (smb_dcache.dc_state) {
case SMB_DCACHE_STATE_READY:
break;
&smb_dcache.dc_mtx);
} else {
}
break;
case SMB_DCACHE_STATE_NONE:
break;
default:
break;
}
return (rc);
}
/*
* Transfers the cache from UPDATING to READY state.
*
* Nothing will happen if the cache is no longer available
* or it is being destroyed.
*/
static void
smb_dcache_ready(void)
{
switch (smb_dcache.dc_state) {
break;
case SMB_DCACHE_STATE_NONE:
break;
default:
assert(0);
}
}