idmap_config.c revision 651c0131ccc65381cbda174bee44a4fd7a518d6b
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * CDDL HEADER START
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * The contents of this file are subject to the terms of the
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Common Development and Distribution License (the "License").
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * You may not use this file except in compliance with the License.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * or http://www.opensolaris.org/os/licensing.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * See the License for the specific language governing permissions
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * and limitations under the License.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * When distributing Covered Code, include this CDDL HEADER in each
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * If applicable, add the following below this CDDL HEADER, with the
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * fields enclosed by brackets "[]" replaced with your own identifying
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * information: Portions Copyright [yyyy] [name of copyright owner]
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * CDDL HEADER END
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Use is subject to license terms.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#pragma ident "%Z%%M% %I% %E% SMI"
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami/*
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami * Config routines common to idmap(1M) and idmapd(1M)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami */
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <stdlib.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <synch.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <assert.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <sys/varargs.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <sys/systeminfo.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <strings.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <libintl.h>
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami#include <ctype.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <errno.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include "idmapd.h"
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh#include <stdio.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <stdarg.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek#define FMRI_BASE "svc:/system/idmap"
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#define CONFIG_PG "config"
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek#define GENERAL_PG "general"
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/* initial length of the array for policy options/attributes: */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#define DEF_ARRAY_LENGTH 16
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstatic const char *me = "idmapd";
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/* Check if in the case of failure the original value of *val is preserved */
37774979c2601819ef2cdb4ae1469d9111ccf52bgjelinekstatic int
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnget_val_int(idmap_cfg_t *cfg, char *name, void *val, scf_type_t type)
1100f00d5652de2808b73c61bcfdb3fc87ef1fc8gjelinek{
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek int rc = 0;
c5cd6260c3d6c06a9359df595ad9dddbfd00a80e
37774979c2601819ef2cdb4ae1469d9111ccf52bgjelinek scf_property_t *scf_prop = scf_property_create(cfg->handles.main);
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek scf_value_t *value = scf_value_create(cfg->handles.main);
c5cd6260c3d6c06a9359df595ad9dddbfd00a80e
37774979c2601819ef2cdb4ae1469d9111ccf52bgjelinek
c5cd6260c3d6c06a9359df595ad9dddbfd00a80e if (0 > scf_pg_get_property(cfg->handles.config_pg, name, scf_prop))
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek /* this is OK: the property is just undefined */
858a4b9997a29c40b725e606eb9bc3ac0a8c765bsl goto destruction;
ff17c8bf86c3e567734be83f90267edee20f580fgjelinek
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn if (0 > scf_property_get_value(scf_prop, value))
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn /* It is still OK when a property doesn't have any value */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn goto destruction;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn switch (type) {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn case SCF_TYPE_BOOLEAN:
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn rc = scf_value_get_boolean(value, val);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn break;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn case SCF_TYPE_COUNT:
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn rc = scf_value_get_count(value, val);
break;
case SCF_TYPE_INTEGER:
rc = scf_value_get_integer(value, val);
break;
default:
idmapdlog(LOG_ERR, "%s: Invalid scf integer type (%d)",
me, type);
rc = -1;
break;
}
destruction:
scf_value_destroy(value);
scf_property_destroy(scf_prop);
return (rc);
}
static char *
scf_value2string(scf_value_t *value) {
int rc = -1;
char buf_size = 127;
int length;
char *buf = NULL;
buf = (char *) malloc(sizeof (char) * buf_size);
for (;;) {
length = scf_value_get_astring(value, buf, buf_size);
if (length < 0) {
rc = -1;
goto destruction;
}
if (length == buf_size - 1) {
buf_size *= 2;
buf = (char *)realloc(buf, buf_size * sizeof (char));
if (!buf) {
idmapdlog(LOG_ERR, "%s: Out of memory", me);
rc = -1;
goto destruction;
}
} else {
rc = 0;
break;
}
}
destruction:
if (rc < 0) {
if (buf)
free(buf);
buf = NULL;
}
return (buf);
}
static int
get_val_astring(idmap_cfg_t *cfg, char *name, char **val)
{
int rc = 0;
scf_property_t *scf_prop = scf_property_create(cfg->handles.main);
scf_value_t *value = scf_value_create(cfg->handles.main);
if (0 > scf_pg_get_property(cfg->handles.config_pg, name, scf_prop))
/* this is OK: the property is just undefined */
goto destruction;
if (0 > scf_property_get_value(scf_prop, value)) {
idmapdlog(LOG_ERR,
"%s: scf_property_get_value(%s) failed: %s",
me, name, scf_strerror(scf_error()));
rc = -1;
goto destruction;
}
if (!(*val = scf_value2string(value))) {
rc = -1;
idmapdlog(LOG_ERR,
"%s: scf_value2string(%s) failed: %s",
me, name, scf_strerror(scf_error()));
}
destruction:
scf_value_destroy(value);
scf_property_destroy(scf_prop);
if (rc < 0) {
if (*val)
free(*val);
*val = NULL;
}
return (rc);
}
int
idmap_cfg_load(idmap_cfg_t *cfg)
{
int rc = 0;
cfg->pgcfg.list_size_limit = 0;
cfg->pgcfg.mapping_domain = NULL;
cfg->pgcfg.machine_sid = NULL;
cfg->pgcfg.domain_controller = NULL;
cfg->pgcfg.global_catalog = NULL;
if (0 > scf_pg_update(cfg->handles.config_pg)) {
idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s",
me, scf_strerror(scf_error()));
return (-1);
}
if (0 > scf_pg_update(cfg->handles.general_pg)) {
idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s",
me, scf_strerror(scf_error()));
return (-1);
}
rc = get_val_int(cfg, "list_size_limit",
&cfg->pgcfg.list_size_limit, SCF_TYPE_COUNT);
if (rc != 0)
return (-1);
rc = get_val_astring(cfg, "mapping_domain",
&cfg->pgcfg.mapping_domain);
if (rc != 0)
return (-1);
/*
* If there is no mapping_domain in idmap's smf config then
* set it to the joined domain.
* Till domain join is implemented, temporarily set it to
* the system domain for testing purposes.
*/
if (!cfg->pgcfg.mapping_domain) {
char test[1];
long dname_size = sysinfo(SI_SRPC_DOMAIN, test, 1);
if (dname_size > 0) {
cfg->pgcfg.mapping_domain =
(char *)malloc(dname_size * sizeof (char));
dname_size = sysinfo(SI_SRPC_DOMAIN,
cfg->pgcfg.mapping_domain, dname_size);
}
if (dname_size <= 0) {
idmapdlog(LOG_ERR,
"%s: unable to get name service domain", me);
if (cfg->pgcfg.mapping_domain)
free(cfg->pgcfg.mapping_domain);
cfg->pgcfg.mapping_domain = NULL;
}
}
rc = get_val_astring(cfg, "machine_sid", &cfg->pgcfg.machine_sid);
if (rc != 0)
return (-1);
rc = get_val_astring(cfg, "global_catalog", &cfg->pgcfg.global_catalog);
if (rc != 0)
return (-1);
rc = get_val_astring(cfg, "domain_controller",
&cfg->pgcfg.domain_controller);
if (rc != 0)
return (-1);
return (rc);
}
/*
* Initialize 'cfg'.
*/
idmap_cfg_t *
idmap_cfg_init() {
/* First the smf repository handles: */
idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t));
if (!cfg) {
idmapdlog(LOG_ERR, "%s: Out of memory", me);
return (NULL);
}
if (!(cfg->handles.main = scf_handle_create(SCF_VERSION))) {
idmapdlog(LOG_ERR, "%s: scf_handle_create() failed: %s",
me, scf_strerror(scf_error()));
goto error;
}
if (0 > scf_handle_bind(cfg->handles.main)) {
idmapdlog(LOG_ERR, "%s: scf_handle_bind() failed: %s",
me, scf_strerror(scf_error()));
goto error;
}
if (!(cfg->handles.service = scf_service_create(cfg->handles.main)) ||
!(cfg->handles.instance = scf_instance_create(cfg->handles.main)) ||
!(cfg->handles.config_pg = scf_pg_create(cfg->handles.main)) ||
!(cfg->handles.general_pg = scf_pg_create(cfg->handles.main))) {
idmapdlog(LOG_ERR, "%s: scf handle creation failed: %s",
me, scf_strerror(scf_error()));
goto error;
}
if (0 > scf_handle_decode_fmri(cfg->handles.main,
FMRI_BASE "/:properties/" CONFIG_PG,
NULL, /* scope */
cfg->handles.service, /* service */
cfg->handles.instance, /* instance */
cfg->handles.config_pg, /* pg */
NULL, /* prop */
SCF_DECODE_FMRI_EXACT)) {
idmapdlog(LOG_ERR, "%s: scf_handle_decode_fmri() failed: %s",
me, scf_strerror(scf_error()));
goto error;
}
if (0 > scf_service_get_pg(cfg->handles.service,
GENERAL_PG, cfg->handles.general_pg)) {
idmapdlog(LOG_ERR, "%s: scf_service_get_pg() failed: %s",
me, scf_strerror(scf_error()));
goto error;
}
return (cfg);
error:
(void) idmap_cfg_fini(cfg);
return (NULL);
}
/* ARGSUSED */
static void
idmap_pgcfg_fini(idmap_pg_config_t *pgcfg) {
if (pgcfg->mapping_domain)
free(pgcfg->mapping_domain);
if (pgcfg->machine_sid)
free(pgcfg->mapping_domain);
if (pgcfg->global_catalog)
free(pgcfg->global_catalog);
if (pgcfg->domain_controller)
free(pgcfg->domain_controller);
}
int
idmap_cfg_fini(idmap_cfg_t *cfg)
{
idmap_pgcfg_fini(&cfg->pgcfg);
scf_pg_destroy(cfg->handles.config_pg);
scf_pg_destroy(cfg->handles.general_pg);
scf_instance_destroy(cfg->handles.instance);
scf_service_destroy(cfg->handles.service);
scf_handle_destroy(cfg->handles.main);
free(cfg);
return (0);
}