#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <strings.h>
#include <libintl.h>
#include <locale.h>
#include <thread.h>
#include <synch.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <crypt.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <netdb.h>
#include <sys/systeminfo.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <limits.h>
#include "ns_sldap.h"
#include "ns_internal.h"
#include "ns_cache_door.h"
#include "ns_connmgmt.h"
#pragma fini(__s_api_shutdown_conn_mgmt, \
_free_config, __ns_ldap_doorfd_close)
static mutex_t ns_parse_lock = DEFAULTMUTEX;
static mutex_t ns_loadrefresh_lock = DEFAULTMUTEX;
static ns_config_t *current_config = NULL;
static int cache_server = FALSE;
extern thread_key_t ns_cmgkey;
static int
__s_val_postime(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf);
static int
__s_val_basedn(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf);
static int
__s_val_binddn(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf);
static int
__s_val_bindpw(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf);
static int
__s_val_serverList(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf);
static ns_parse_status
verify_value(ns_config_t *cfg, char *name, char *value, char *errstr);
static int
set_default_value(ns_config_t *configptr, char *name, char *value,
ns_ldap_error_t **error);
static void
set_curr_config(ns_config_t *ptr);
static int
__door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error);
static ns_config_t *
SetDoorInfo(char *buffer, ns_ldap_error_t **errorp);
static boolean_t
timetorefresh(ns_config_t *cfg);
static ns_config_t *
LoadCacheConfiguration(ns_config_t *, ns_ldap_error_t **error);
static void **
dupParam(ns_param_t *ptr);
static time_t
conv_time(char *s);
static ns_enum_map ns_auth_enum_v1[] = {
{ ENUM2INT(NS_LDAP_EA_NONE), "NS_LDAP_AUTH_NONE" },
{ ENUM2INT(NS_LDAP_EA_SIMPLE), "NS_LDAP_AUTH_SIMPLE" },
{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "NS_LDAP_AUTH_SASL_CRAM_MD5" },
{ -1, NULL },
};
static ns_enum_map ns_auth_enum_v2[] = {
{ ENUM2INT(NS_LDAP_EA_NONE), "none" },
{ ENUM2INT(NS_LDAP_EA_SIMPLE), "simple" },
{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "sasl/CRAM-MD5" },
{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5), "sasl/DIGEST-MD5" },
{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_INT),
"sasl/DIGEST-MD5:auth-int" },
{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_CONF),
"sasl/DIGEST-MD5:auth-conf" },
{ ENUM2INT(NS_LDAP_EA_SASL_EXTERNAL), "sasl/EXTERNAL" },
{ ENUM2INT(NS_LDAP_EA_SASL_GSSAPI), "sasl/GSSAPI" },
{ ENUM2INT(NS_LDAP_EA_TLS_NONE), "tls:none" },
{ ENUM2INT(NS_LDAP_EA_TLS_SIMPLE), "tls:simple" },
{ ENUM2INT(NS_LDAP_EA_TLS_SASL_CRAM_MD5), "tls:sasl/CRAM-MD5" },
{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5), "tls:sasl/DIGEST-MD5" },
{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT),
"tls:sasl/DIGEST-MD5:auth-int" },
{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF),
"tls:sasl/DIGEST-MD5:auth-conf" },
{ ENUM2INT(NS_LDAP_EA_TLS_SASL_EXTERNAL), "tls:sasl/EXTERNAL" },
{ -1, NULL },
};
static ns_enum_map ns_sec_enum_v1[] = {
{ ENUM2INT(NS_LDAP_TLS_NONE), "NS_LDAP_SEC_NONE" },
{ -1, NULL },
};
static ns_enum_map ns_cred_enum_v2[] = {
{ ENUM2INT(NS_LDAP_CRED_ANON), "anonymous" },
{ ENUM2INT(NS_LDAP_CRED_PROXY), "proxy" },
{ ENUM2INT(NS_LDAP_CRED_SELF), "self" },
{ -1, NULL },
};
static ns_enum_map ns_ref_enum_v1[] = {
{ ENUM2INT(NS_LDAP_FOLLOWREF), "NS_LDAP_FOLLOWREF" },
{ ENUM2INT(NS_LDAP_NOREF), "NS_LDAP_NOREF" },
{ -1, NULL },
};
static ns_enum_map ns_ref_enum_v2[] = {
{ ENUM2INT(NS_LDAP_FOLLOWREF), "TRUE" },
{ ENUM2INT(NS_LDAP_NOREF), "FALSE" },
{ -1, NULL },
};
static ns_enum_map ns_scope_enum_v1[] = {
{ ENUM2INT(NS_LDAP_SCOPE_BASE), "NS_LDAP_SCOPE_BASE" },
{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "NS_LDAP_SCOPE_ONELEVEL" },
{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "NS_LDAP_SCOPE_SUBTREE" },
{ -1, NULL },
};
static ns_enum_map ns_scope_enum_v2[] = {
{ ENUM2INT(NS_LDAP_SCOPE_BASE), "base" },
{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "one" },
{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "sub" },
{ -1, NULL },
};
static ns_enum_map ns_pref_enum[] = {
{ ENUM2INT(NS_LDAP_PREF_FALSE), "NS_LDAP_FALSE" },
{ ENUM2INT(NS_LDAP_PREF_TRUE), "NS_LDAP_TRUE" },
{ -1, NULL },
};
static ns_enum_map ns_shadow_update_enum[] = {
{ ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE), "FALSE" },
{ ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE), "TRUE" },
{ -1, NULL },
};
static int ns_def_auth_v1[] = {
ENUM2INT(NS_LDAP_EA_NONE),
0
};
static int ns_def_auth_v2[] = {
ENUM2INT(NS_LDAP_EA_NONE),
0
};
static int ns_def_cred_v1[] = {
ENUM2INT(NS_LDAP_CRED_PROXY),
0
};
static int ns_def_cred_v2[] = {
ENUM2INT(NS_LDAP_CRED_ANON),
0
};
#if defined(__amd64)
#define INT2VOIDPTR(i) (void *)i
#else
#define INT2VOIDPTR(i) \
(void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
#endif
static ns_default_config defconfig[] = {
{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
NULL,
{ CHARPTR, 0, (void *)NS_LDAP_VERSION_1 },
NULL, NULL },
{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_BINDDN,
{ CHARPTR, 0, NULL },
__s_val_binddn, NULL },
{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_BINDPASSWORD,
{ CHARPTR, 0, NULL },
__s_val_bindpw, NULL },
{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
SERVERCONFIG, ARRAYCP, FALSE, NS_LDAP_V1,
_P1_SERVERS,
{ ARRAYCP, 0, NULL },
__s_val_serverList, NULL },
{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
SERVERCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_SEARCHBASEDN,
{ CHARPTR, 0, NULL },
__s_val_basedn, NULL },
{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
CLIENTCONFIG, ARRAYAUTH, FALSE, NS_LDAP_V1,
_P1_AUTHMETHOD,
{ ARRAYAUTH, 1, (void *)&ns_def_auth_v1[0] },
NULL, ns_auth_enum_v1 },
{"NS_LDAP_TRANSPORT_SEC", NS_LDAP_TRANSPORT_SEC_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_TRANSPORTSECURITY,
{ INT, 0, INT2VOIDPTR(NS_LDAP_TLS_NONE) },
NULL, ns_sec_enum_v1 },
{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_SEARCHREFERRAL,
{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
NULL, ns_ref_enum_v1 },
{"NS_LDAP_DOMAIN", NS_LDAP_DOMAIN_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
NULL,
{ CHARPTR, 0, NULL },
NULL, NULL },
{"NS_LDAP_EXP", NS_LDAP_EXP_P,
SERVERCONFIG, TIMET, TRUE, NS_LDAP_V1,
NULL,
{ INT, 0, 0 },
NULL, NULL },
{"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_CERTIFICATEPATH,
{ CHARPTR, 0, NULL },
NULL, NULL },
{"NS_LDAP_CERT_PASS", NS_LDAP_CERT_PASS_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_CERTIFICATEPASSWORD,
{ CHARPTR, 0, NULL },
NULL, NULL },
{"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P,
CLIENTCONFIG, SSDLIST, FALSE, NS_LDAP_V1,
_P1_DATASEARCHDN,
{ SSDLIST, 0, NULL },
NULL, NULL },
{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_SEARCHSCOPE,
{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
NULL, ns_scope_enum_v1 },
{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_SEARCHTIMELIMIT,
{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
NULL, NULL },
{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
CLIENTCONFIG, ARRAYCP, FALSE, NS_LDAP_V1,
_P1_PREFERREDSERVER,
{ ARRAYCP, 0, NULL },
__s_val_serverList, NULL },
{"NS_LDAP_PREF_ONLY", NS_LDAP_PREF_ONLY_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_PREFERREDSERVERONLY,
{ INT, 0, INT2VOIDPTR(NS_LDAP_PREF_FALSE) },
NULL, ns_pref_enum },
{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P1_CACHETTL,
{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
__s_val_postime, NULL },
{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
_P_CN,
{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
NULL, NULL },
{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
_P1_BINDTIMELIMIT,
{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
NULL, NULL },
{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
CLIENTCONFIG, ARRAYCRED, TRUE, NS_LDAP_V1,
NULL,
{ ARRAYCRED, 0, (void *)&ns_def_cred_v1[0] },
NULL, NULL },
{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, (void *)NS_LDAP_VERSION_2 },
NULL, NULL },
{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, NULL },
__s_val_binddn, NULL },
{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, NULL },
__s_val_bindpw, NULL },
{"NS_LDAP_ENABLE_SHADOW_UPDATE", NS_LDAP_ENABLE_SHADOW_UPDATE_P,
CREDCONFIG, INT, TRUE, NS_LDAP_V2,
NULL,
{ INT, 0, INT2VOIDPTR(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE) },
NULL, ns_shadow_update_enum },
{"NS_LDAP_ADMIN_BINDDN", NS_LDAP_ADMIN_BINDDN_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, NULL },
__s_val_binddn, NULL },
{"NS_LDAP_ADMIN_BINDPASSWD", NS_LDAP_ADMIN_BINDPASSWD_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, NULL },
__s_val_bindpw, NULL },
{"NS_LDAP_EXP", NS_LDAP_EXP_P,
SERVERCONFIG, TIMET, TRUE, NS_LDAP_V2,
NULL,
{ INT, 0, 0 },
NULL, NULL },
{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
CLIENTCONFIG, SERVLIST, FALSE, NS_LDAP_V2,
_P2_PREFERREDSERVER,
{ SERVLIST, 0, NULL },
__s_val_serverList, NULL },
{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
SERVERCONFIG, SERVLIST, FALSE, NS_LDAP_V2,
_P2_DEFAULTSERVER,
{ SERVLIST, 0, NULL },
__s_val_serverList, NULL },
{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
SERVERCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
_P2_SEARCHBASEDN,
{ CHARPTR, 0, NULL },
__s_val_basedn, NULL },
{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
_P2_SEARCHSCOPE,
{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
NULL, ns_scope_enum_v2 },
{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
CLIENTCONFIG, ARRAYAUTH, FALSE, NS_LDAP_V2,
_P2_AUTHMETHOD,
{ ARRAYAUTH, 2, (void *)&ns_def_auth_v2[0] },
NULL, ns_auth_enum_v2 },
{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
CLIENTCONFIG, ARRAYCRED, FALSE, NS_LDAP_V2,
_P2_CREDENTIALLEVEL,
{ ARRAYCRED, 0, (void *)&ns_def_cred_v2[0] },
NULL, ns_cred_enum_v2 },
{"NS_LDAP_SERVICE_SEARCH_DESC", NS_LDAP_SERVICE_SEARCH_DESC_P,
CLIENTCONFIG, SSDLIST, FALSE, NS_LDAP_V2,
_P2_SERVICESEARCHDESC,
{ SSDLIST, 0, NULL },
NULL, NULL },
{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
_P2_SEARCHTIMELIMIT,
{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
NULL, NULL },
{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
_P2_BINDTIMELIMIT,
{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
NULL, NULL },
{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
_P2_FOLLOWREFERRALS,
{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
NULL, ns_ref_enum_v2 },
{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
_P2_PROFILETTL,
{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
__s_val_postime, NULL },
{"NS_LDAP_ATTRIBUTEMAP", NS_LDAP_ATTRIBUTEMAP_P,
CLIENTCONFIG, ATTRMAP, FALSE, NS_LDAP_V2,
_P2_ATTRIBUTEMAP,
{ ATTRMAP, 0, NULL },
NULL, NULL },
{"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P,
CLIENTCONFIG, OBJMAP, FALSE, NS_LDAP_V2,
_P2_OBJECTCLASSMAP,
{ OBJMAP, 0, NULL },
NULL, NULL },
{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
_P_CN,
{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
NULL, NULL },
{"NS_LDAP_SERVICE_AUTH_METHOD", NS_LDAP_SERVICE_AUTH_METHOD_P,
CLIENTCONFIG, SAMLIST, FALSE, NS_LDAP_V2,
_P2_SERVICEAUTHMETHOD,
{ SAMLIST, 0, NULL },
NULL, NULL },
{"NS_LDAP_SERVICE_CRED_LEVEL", NS_LDAP_SERVICE_CRED_LEVEL_P,
CLIENTCONFIG, SCLLIST, FALSE, NS_LDAP_V2,
_P2_SERVICECREDLEVEL,
{ SCLLIST, 0, NULL },
NULL, NULL },
{"NS_LDAP_HOST_CERTPATH", NS_LDAP_HOST_CERTPATH_P,
CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
NULL,
{ CHARPTR, 0, (void *)NSLDAPDIRECTORY },
NULL, NULL },
{NULL, NS_LDAP_FILE_VERSION_P,
CLIENTCONFIG, NS_UNKNOWN, TRUE, 0,
NULL,
{ NS_UNKNOWN, 0, NULL },
NULL, NULL },
};
static char *
__getdomainname()
{
char buf[MAXHOSTNAMELEN + 1];
int status;
status = sysinfo(SI_SRPC_DOMAIN, buf, MAXHOSTNAMELEN);
if (status < 0)
return (NULL);
if (status > sizeof (buf))
return (NULL);
return (strdup(buf));
}
void
__ns_ldap_setServer(int set)
{
cache_server = set;
}
static boolean_t
timetorefresh(ns_config_t *cfg)
{
struct timeval tp;
static time_t expire = 0;
if (cfg == NULL || gettimeofday(&tp, NULL) == -1)
return (B_TRUE);
if (cfg->paramList[NS_LDAP_EXP_P].ns_ptype == TIMET)
expire = cfg->paramList[NS_LDAP_EXP_P].ns_tm;
else
return (B_TRUE);
return (expire != 0 && tp.tv_sec > expire);
}
int
__s_get_enum_value(ns_config_t *ptr, char *value, ParamIndexType i)
{
register ns_enum_map *mapp;
char *pstart = value;
char *pend;
int len;
if (pstart == NULL)
return (-1);
while (*pstart == SPACETOK)
pstart++;
pend = pstart + strlen(pstart) - 1;
for (; pend >= pstart && *pend == SPACETOK; pend--)
;
len = pend - pstart + 1;
if (len == 0)
return (-1);
switch (i) {
case NS_LDAP_AUTH_P:
if (ptr->version == NS_LDAP_V1)
mapp = &ns_auth_enum_v1[0];
else
mapp = &ns_auth_enum_v2[0];
break;
case NS_LDAP_TRANSPORT_SEC_P:
return (-1);
case NS_LDAP_SEARCH_SCOPE_P:
if (ptr->version == NS_LDAP_V1)
mapp = &ns_scope_enum_v1[0];
else
mapp = &ns_scope_enum_v2[0];
break;
case NS_LDAP_SEARCH_REF_P:
if (ptr->version == NS_LDAP_V1)
mapp = &ns_ref_enum_v1[0];
else
mapp = &ns_ref_enum_v2[0];
break;
case NS_LDAP_PREF_ONLY_P:
mapp = &ns_pref_enum[0];
break;
case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
mapp = &ns_shadow_update_enum[0];
break;
case NS_LDAP_CREDENTIAL_LEVEL_P:
if (ptr->version == NS_LDAP_V1)
return (-1);
else
mapp = &ns_cred_enum_v2[0];
break;
case NS_LDAP_SERVICE_AUTH_METHOD_P:
mapp = &ns_auth_enum_v2[0];
break;
case NS_LDAP_SERVICE_CRED_LEVEL_P:
mapp = &ns_cred_enum_v2[0];
break;
default:
return (-1);
}
for (; mapp->name != NULL; mapp++) {
if (strncasecmp(pstart, mapp->name, len) == 0 &&
(strlen(mapp->name) == len)) {
return (mapp->value);
}
}
return (-1);
}
char *
__s_get_auth_name(ns_config_t *ptr, AuthType_t type)
{
register ns_enum_map *mapp;
if (ptr->version == NS_LDAP_V1)
mapp = &ns_auth_enum_v1[0];
else
mapp = &ns_auth_enum_v2[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2AUTHENUM(mapp->value)) {
return (mapp->name);
}
}
return ("Unknown AuthType_t type specified");
}
char *
__s_get_security_name(ns_config_t *ptr, TlsType_t type)
{
register ns_enum_map *mapp;
if (ptr->version == NS_LDAP_V1) {
mapp = &ns_sec_enum_v1[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2SECENUM(mapp->value)) {
return (mapp->name);
}
}
}
return ("Unknown TlsType_t type specified");
}
char *
__s_get_scope_name(ns_config_t *ptr, ScopeType_t type)
{
register ns_enum_map *mapp;
if (ptr->version == NS_LDAP_V1)
mapp = &ns_scope_enum_v1[0];
else
mapp = &ns_scope_enum_v2[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2SCOPEENUM(mapp->value)) {
return (mapp->name);
}
}
return ("Unknown ScopeType_t type specified");
}
char *
__s_get_pref_name(PrefOnly_t type)
{
register ns_enum_map *mapp = &ns_pref_enum[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2PREFONLYENUM(mapp->value)) {
return (mapp->name);
}
}
return ("Unknown PrefOnly_t type specified");
}
char *
__s_get_searchref_name(ns_config_t *ptr, SearchRef_t type)
{
register ns_enum_map *mapp;
if (ptr->version == NS_LDAP_V1)
mapp = &ns_ref_enum_v1[0];
else
mapp = &ns_ref_enum_v2[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2SEARCHREFENUM(mapp->value)) {
return (mapp->name);
}
}
return ("Unknown SearchRef_t type specified");
}
char *
__s_get_shadowupdate_name(enableShadowUpdate_t type)
{
register ns_enum_map *mapp;
mapp = &ns_shadow_update_enum[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2SHADOWUPDATENUM(mapp->value)) {
return (mapp->name);
}
}
return ("Unknown enableShadowUpdate_t type specified");
}
static char *
__s_get_credlvl_name(ns_config_t *ptr, CredLevel_t type)
{
register ns_enum_map *mapp;
if (ptr->version == NS_LDAP_V2) {
mapp = &ns_cred_enum_v2[0];
for (; mapp->name != NULL; mapp++) {
if (type == INT2CREDLEVELENUM(mapp->value)) {
return (mapp->name);
}
}
}
return ("Unknown CredLevel_t type specified");
}
static void
destroy_param(ns_config_t *ptr, ParamIndexType type)
{
int i, j;
char **ppc;
if (ptr == NULL)
return;
switch (ptr->paramList[type].ns_ptype) {
case CHARPTR:
if (ptr->paramList[type].ns_pc) {
free(ptr->paramList[type].ns_pc);
ptr->paramList[type].ns_pc = NULL;
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
case ARRAYCP:
case SERVLIST:
if (ptr->paramList[type].ns_ppc) {
ppc = ptr->paramList[type].ns_ppc;
j = ptr->paramList[type].ns_acnt;
for (i = 0; i < j && ppc[i] != NULL; i++) {
free((void *)ppc[i]);
}
free((void *)ppc);
ptr->paramList[type].ns_ppc = NULL;
}
break;
case ARRAYAUTH:
case ARRAYCRED:
if (ptr->paramList[type].ns_pi) {
free(ptr->paramList[type].ns_pi);
ptr->paramList[type].ns_pi = NULL;
}
break;
case INT:
ptr->paramList[type].ns_i = 0;
break;
case ATTRMAP:
break;
case OBJMAP:
break;
default:
break;
}
ptr->paramList[type].ns_ptype = NS_UNKNOWN;
}
static void
destroy_config(ns_config_t *ptr)
{
ParamIndexType i;
if (ptr != NULL) {
if (ptr == current_config)
current_config = NULL;
free(ptr->domainName);
ptr->domainName = NULL;
for (i = 0; i <= LAST_VALUE; i++) {
destroy_param(ptr, i);
}
__s_api_destroy_hash(ptr);
free(ptr);
}
}
void
__s_api_destroy_config(ns_config_t *cfg)
{
if (cfg != NULL) {
(void) mutex_lock(&cfg->config_mutex);
cfg->delete = TRUE;
(void) mutex_unlock(&cfg->config_mutex);
__s_api_release_config(cfg);
}
}
static ns_config_t *
get_curr_config_unlocked(ns_config_t *cfg, boolean_t global)
{
ns_config_t *ret;
ret = cfg;
if (cfg != NULL) {
(void) mutex_lock(&cfg->config_mutex);
if (cfg->delete && global == B_TRUE)
ret = NULL;
else
cfg->nUse++;
(void) mutex_unlock(&cfg->config_mutex);
}
return (ret);
}
static void
set_curr_config_global(ns_config_t *ptr)
{
ns_config_t *cfg;
ns_config_t *cur_cfg;
(void) mutex_lock(&ns_parse_lock);
cur_cfg = current_config;
cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
if (cfg != ptr) {
__s_api_destroy_config(cfg);
current_config = ptr;
}
(void) mutex_unlock(&ns_parse_lock);
}
static void
set_curr_config(ns_config_t *ptr)
{
ns_config_t *cfg;
ns_config_t *cur_cfg;
ns_conn_mgmt_t *cmg;
int rc;
rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
if (rc == 0 && cmg != NULL && cmg->config != NULL) {
(void) mutex_lock(&cmg->cfg_lock);
cur_cfg = cmg->config;
cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
if (cfg != ptr) {
__s_api_destroy_config(cfg);
cmg->config = ptr;
}
(void) mutex_unlock(&cmg->cfg_lock);
return;
}
set_curr_config_global(ptr);
}
void
__s_api_release_config(ns_config_t *cfg)
{
if (cfg != NULL) {
(void) mutex_lock(&cfg->config_mutex);
cfg->nUse--;
if (cfg->nUse == 0 && cfg->delete) {
destroy_config(cfg);
} else
(void) mutex_unlock(&cfg->config_mutex);
}
}
void
__s_api_init_config_global(ns_config_t *ptr)
{
set_curr_config_global(ptr);
__s_api_release_config(ptr);
}
void
__s_api_init_config(ns_config_t *ptr)
{
set_curr_config(ptr);
__s_api_release_config(ptr);
}
ns_config_t *
__s_api_create_config(void)
{
ns_config_t *ret;
ret = (ns_config_t *)calloc(1, sizeof (ns_config_t));
if (ret == NULL)
return (NULL);
ret->domainName = __getdomainname();
if (ret->domainName == NULL) {
free(ret);
return (NULL);
}
ret->version = NS_LDAP_V1;
(void) mutex_init(&ret->config_mutex, USYNC_THREAD, NULL);
ret->nUse = 1;
ret->delete = B_FALSE;
return (ret);
}
ns_config_t *
__s_api_get_default_config_global(void)
{
ns_config_t *cfg;
ns_config_t *cur_cfg;
(void) mutex_lock(&ns_parse_lock);
cur_cfg = current_config;
cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
(void) mutex_unlock(&ns_parse_lock);
return (cfg);
}
ns_config_t *
__s_api_get_default_config(void)
{
ns_config_t *cfg;
ns_config_t *cur_cfg;
ns_conn_mgmt_t *cmg;
int rc;
rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
if (rc == 0 && cmg != NULL && cmg->config != NULL) {
(void) mutex_lock(&cmg->cfg_lock);
cur_cfg = cmg->config;
cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
(void) mutex_unlock(&cmg->cfg_lock);
return (cfg);
}
return (__s_api_get_default_config_global());
}
static char *
stripdup(const char *instr)
{
char *pstart = (char *)instr;
char *pend, *ret;
int len;
if (pstart == NULL)
return (NULL);
while (*pstart == SPACETOK)
pstart++;
pend = pstart + strlen(pstart) - 1;
for (; pend >= pstart && *pend == SPACETOK; pend--)
;
len = pend - pstart + 1;
if ((ret = malloc(len + 1)) == NULL)
return (NULL);
if (len != 0) {
(void) strncpy(ret, pstart, len);
}
ret[len] = '\0';
return (ret);
}
ns_parse_status
__s_api_crosscheck(ns_config_t *ptr, char *errstr, int check_dn)
{
int value, j;
time_t tm;
const char *str, *str1;
int i, cnt;
int self, gssapi;
if (ptr == NULL)
return (NS_SUCCESS);
if (ptr->paramList[NS_LDAP_SERVERS_P].ns_ppc == NULL) {
if (ptr->version == NS_LDAP_V1) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_SERVERS_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
} else if (ptr->paramList[NS_LDAP_SERVER_PREF_P].ns_ppc ==
NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_SERVERS_P));
str1 = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_SERVER_PREF_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: "
"Neither '%s' nor '%s' is defined"), str, str1);
return (NS_PARSE_ERR);
}
}
if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc != NULL &&
ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc == NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_CERT_PASS_P));
str1 = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_CERT_PATH_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: %s specified "
"but no value for '%s' found"), str, str1);
return (NS_PARSE_ERR);
}
if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc == NULL &&
ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc != NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_CERT_PATH_P));
str1 = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_CERT_PASS_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: %s specified "
"but no value for '%s' found"), str, str1);
return (NS_PARSE_ERR);
}
if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ppc == NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_SEARCH_BASEDN_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
if (check_dn) {
for (j = 0; ptr->paramList[NS_LDAP_AUTH_P].ns_pi != NULL &&
ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j] != 0; j++) {
value = ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j];
switch (value) {
case NS_LDAP_EA_SIMPLE:
case NS_LDAP_EA_SASL_CRAM_MD5:
case NS_LDAP_EA_SASL_DIGEST_MD5:
case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
case NS_LDAP_EA_TLS_SIMPLE:
case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
if (ptr->paramList[NS_LDAP_BINDDN_P].ns_ppc == NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_BINDDN_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
if (ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ppc
== NULL) {
str = NULL_OR_STR(__s_api_get_configname(
NS_LDAP_BINDPASSWD_P));
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
break;
}
}
}
if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc == NULL) {
tm = conv_time(
defconfig[NS_LDAP_CACHETTL_P].defval.ns_pc);
ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
if (tm != 0) {
tm += time(NULL);
}
ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
}
self = 0;
cnt = ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_acnt;
for (i = 0; i < cnt; i++) {
if (ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_pi[i] ==
NS_LDAP_CRED_SELF)
self++;
}
gssapi = 0;
cnt = ptr->paramList[NS_LDAP_AUTH_P].ns_acnt;
for (i = 0; i < cnt; i++) {
if (ptr->paramList[NS_LDAP_AUTH_P].ns_pi[i] ==
NS_LDAP_EA_SASL_GSSAPI)
gssapi++;
}
if (gssapi == 0 && self > 0) {
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: "
"Credential level self requires "
"authentication method sasl/GSSAPI"));
return (NS_PARSE_ERR);
}
if (gssapi > 0 && self == 0) {
(void) snprintf(errstr, MAXERROR,
gettext("Configuration Error: "
"Authentication method sasl/GSSAPI "
"requires credential level self"));
return (NS_PARSE_ERR);
}
return (NS_SUCCESS);
}
int
__s_api_get_type(const char *value, ParamIndexType *type)
{
int i;
for (i = 0; defconfig[i].name != NULL; i++) {
if (strcasecmp(defconfig[i].name, value) == 0) {
*type = defconfig[i].index;
return (0);
}
}
return (-1);
}
int
__ns_ldap_getParamType(const char *value, ParamIndexType *type)
{
if (value == NULL || type == NULL)
return (-1);
return (__s_api_get_type(value, type));
}
int
__s_api_get_versiontype(ns_config_t *ptr, char *value, ParamIndexType *type)
{
ns_version_t ver;
int i;
if (ptr == NULL)
return (-1);
ver = ptr->version;
for (i = 0; defconfig[i].name != NULL; i++) {
if (strcasecmp(defconfig[i].name, value) == 0) {
if (defconfig[i].version == ver) {
*type = defconfig[i].index;
return (0);
}
}
}
return (-1);
}
int
__s_api_get_profiletype(char *value, ParamIndexType *type)
{
int i;
for (i = 0; defconfig[i].name != NULL; i++) {
if (defconfig[i].profile_name == NULL)
continue;
if (strcasecmp(defconfig[i].profile_name, value) == 0) {
*type = defconfig[i].index;
return (0);
}
}
return (-1);
}
int
__s_api_get_configtype(ParamIndexType type)
{
int i;
for (i = 0; defconfig[i].name != NULL; i++) {
if (defconfig[i].index == type) {
return (defconfig[i].config_type);
}
}
return (-1);
}
const char *
__s_api_get_configname(ParamIndexType type)
{
int i;
for (i = 0; defconfig[i].name != NULL; i++) {
if (defconfig[i].index == type) {
if (defconfig[i].name[0] == '\0')
return (NULL);
else
return (defconfig[i].name);
}
}
return (NULL);
}
static ns_default_config *
get_defconfig(ns_config_t *ptr, ParamIndexType type)
{
ns_version_t ver;
int i;
ver = ptr->version;
for (i = 0; defconfig[i].name != NULL; i++) {
if (defconfig[i].index == type &&
defconfig[i].version == ver) {
return (&defconfig[i]);
}
}
return (NULL);
}
static int
set_default_value(ns_config_t *configptr, char *name,
char *value, ns_ldap_error_t **error)
{
ParamIndexType i;
int ret;
char errstr[MAXERROR];
if (__s_api_get_type(name, &i) < 0) {
(void) snprintf(errstr, sizeof (errstr), gettext(
"Illegal type name (%s).\n"), name);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
NS_LDAP_MEMORY);
return (NS_LDAP_CONFIG);
}
if (i != NS_LDAP_SERVERS_P &&
i != NS_LDAP_SERVICE_AUTH_METHOD_P &&
i != NS_LDAP_SERVICE_CRED_LEVEL_P &&
i != NS_LDAP_SERVICE_SEARCH_DESC_P &&
i != NS_LDAP_SERVER_PREF_P &&
i != NS_LDAP_SEARCH_DN_P) {
if (configptr->paramList[i].ns_ptype != NS_UNKNOWN) {
destroy_param(configptr, i);
}
}
ret = __ns_ldap_setParamValue(configptr, i, value, error);
return (ret);
}
void
__ns_ldap_default_config()
{
ns_config_t *ptr;
ptr = __s_api_create_config();
if (ptr == NULL)
return;
set_curr_config(ptr);
__s_api_release_config(ptr);
}
static ns_config_t *
loadrefresh_config(boolean_t global)
{
ns_config_t *cfg;
ns_config_t *new_cfg;
ns_ldap_error_t *errorp;
(void) mutex_lock(&ns_loadrefresh_lock);
if (global == B_TRUE)
cfg = __s_api_get_default_config_global();
else
cfg = __s_api_get_default_config();
if (!__s_api_isStandalone() && timetorefresh(cfg)) {
new_cfg = LoadCacheConfiguration(cfg, &errorp);
if (new_cfg != NULL && new_cfg != cfg) {
__s_api_release_config(cfg);
if (global == B_TRUE)
set_curr_config_global(new_cfg);
else
set_curr_config(new_cfg);
cfg = new_cfg;
}
if (errorp != NULL)
(void) __ns_ldap_freeError(&errorp);
}
(void) mutex_unlock(&ns_loadrefresh_lock);
return (cfg);
}
ns_config_t *
__s_api_loadrefresh_config_global()
{
return (loadrefresh_config(B_TRUE));
}
ns_config_t *
__s_api_loadrefresh_config()
{
return (loadrefresh_config(B_FALSE));
}
static ns_parse_status
verify_value(ns_config_t *cfg, char *name, char *value, char *errstr)
{
ParamIndexType index = 0;
int found = 0, j;
char *ptr = NULL, *strptr = NULL, buffer[BUFSIZE];
char *rest;
ns_default_config *def = NULL;
if (__s_api_get_type(name, &index) != 0) {
(void) snprintf(errstr, MAXERROR,
gettext("Unknown keyword encountered '%s'."), name);
return (NS_PARSE_ERR);
}
def = get_defconfig(cfg, index);
while (value != NULL && (*value == QUOTETOK || *value == SPACETOK))
value++;
if (strlen(value) > 0)
ptr = value + strlen(value) - 1;
else
ptr = value;
for (; ptr != value && (*ptr == SPACETOK || *ptr == QUOTETOK); ptr--) {
*ptr = '\0';
}
switch (index) {
case NS_LDAP_EXP_P:
case NS_LDAP_CACHETTL_P:
case NS_LDAP_CERT_PATH_P:
case NS_LDAP_CERT_PASS_P:
case NS_LDAP_CERT_NICKNAME_P:
case NS_LDAP_BINDDN_P:
case NS_LDAP_BINDPASSWD_P:
case NS_LDAP_ADMIN_BINDDN_P:
case NS_LDAP_ADMIN_BINDPASSWD_P:
case NS_LDAP_DOMAIN_P:
case NS_LDAP_SEARCH_BASEDN_P:
case NS_LDAP_SEARCH_TIME_P:
case NS_LDAP_PROFILE_P:
case NS_LDAP_AUTH_P:
case NS_LDAP_SEARCH_SCOPE_P:
case NS_LDAP_CREDENTIAL_LEVEL_P:
case NS_LDAP_SERVICE_SEARCH_DESC_P:
case NS_LDAP_BIND_TIME_P:
case NS_LDAP_ATTRIBUTEMAP_P:
case NS_LDAP_OBJECTCLASSMAP_P:
case NS_LDAP_SERVICE_AUTH_METHOD_P:
case NS_LDAP_SERVICE_CRED_LEVEL_P:
case NS_LDAP_HOST_CERTPATH_P:
break;
case NS_LDAP_SEARCH_DN_P:
break;
case NS_LDAP_FILE_VERSION_P:
if (value != NULL &&
strcasecmp(value, NS_LDAP_VERSION_1) != 0 &&
strcasecmp(value, NS_LDAP_VERSION_2) != 0) {
(void) snprintf(errstr, MAXERROR,
gettext("Version mismatch, expected "
"cache version '%s' or '%s' but "
"encountered version '%s'."),
NS_LDAP_VERSION_1,
NS_LDAP_VERSION_2, value);
return (NS_PARSE_ERR);
}
break;
case NS_LDAP_SERVERS_P:
case NS_LDAP_SERVER_PREF_P:
(void) strcpy(buffer, value);
strptr = strtok_r(buffer, ",", &rest);
while (strptr != NULL) {
char *tmp = NULL;
tmp = stripdup(strptr);
if (tmp == NULL || (strchr(tmp, ' ') != NULL)) {
(void) snprintf(errstr, MAXERROR,
gettext("Invalid parameter values "
"'%s' specified for keyword '%s'."),
tmp, name);
free(tmp);
return (NS_PARSE_ERR);
}
free(tmp);
strptr = strtok_r(NULL, ",", &rest);
}
break;
default:
found = 0; j = 0;
while (def->allowed != NULL &&
def->allowed[j].name != NULL && j < DEFMAX) {
if (strcmp(def->allowed[j].name,
value) == 0) {
found = 1;
break;
}
j++;
}
if (!found) {
(void) snprintf(errstr, MAXERROR,
gettext("Invalid option specified for "
"'%s' keyword. '%s' is not a recognized "
"keyword value."), name, value);
return (NS_PARSE_ERR);
}
}
return (NS_SUCCESS);
}
void
__s_api_split_key_value(char *buffer, char **name, char **value)
{
char *ptr;
*name = buffer;
if ((ptr = strchr(buffer, TOKENSEPARATOR)) != NULL) {
*ptr = '\0';
ptr++;
while (*ptr == SPACETOK)
ptr++;
*value = ptr;
}
}
int
__ns_ldap_setParamValue(ns_config_t *ptr, const ParamIndexType type,
const void *data, ns_ldap_error_t **error)
{
ns_default_config *def = NULL;
ns_param_t conf;
ns_mapping_t *map, *rmap;
int i, j, len;
char *cp, *cp2, *end;
char *tcp = NULL;
char errstr[2 * MAXERROR];
char tbuf[100], *ptbuf;
char *sid, *origA, **mapA;
char **attr;
time_t tm;
int free_memory, exitrc;
char **p;
def = get_defconfig(ptr, type);
if (def == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid ParamIndexType (%d)"), type);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
NS_LDAP_MEMORY);
return (NS_LDAP_CONFIG);
}
(void) memset(&conf, 0, sizeof (conf));
cp = (char *)data;
while (cp && (*cp == QUOTETOK || *cp == SPACETOK))
cp++;
end = cp2 = cp + strlen(cp) - 1;
for (; cp2 > cp && (*cp2 == SPACETOK || *cp2 == QUOTETOK); cp2--)
;
if (cp2 != end) {
tcp = (char *)calloc((int)(cp2 - cp + 2), sizeof (char));
if (tcp == NULL)
return (NS_LDAP_MEMORY);
end = cp2;
cp2 = tcp;
while (cp <= end) {
*cp2++ = *cp++;
}
*cp2 = '\0';
cp = tcp;
}
switch (def->data_type) {
case INT:
switch (def->index) {
case NS_LDAP_PREF_ONLY_P:
case NS_LDAP_SEARCH_REF_P:
case NS_LDAP_SEARCH_SCOPE_P:
case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
i = __s_get_enum_value(ptr, cp, def->index);
if (i < 0) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid %s (%d)"), def->name,
def->index);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_i = i;
break;
case NS_LDAP_TRANSPORT_SEC_P:
break;
default:
cp2 = cp;
if ((*cp2 == '+') || (*cp2 == '-'))
cp2++;
for (; *cp2; cp2++) {
if (isdigit(*cp2))
continue;
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid %s (%d)"), def->name,
def->index);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
i = atoi(cp);
conf.ns_i = i;
break;
}
break;
case TIMET:
break;
case CHARPTR:
conf.ns_pc = (char *)strdup(cp);
if (conf.ns_pc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
break;
case SAMLIST:
if ((strchr(cp, COLONTOK)) == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid serviceAuthenticationMethod (%s)"),
cp);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
if (ptr->paramList[type].ns_ptype != SAMLIST) {
conf.ns_ppc = (char **)calloc(2, sizeof (char *));
if (conf.ns_ppc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = 1;
conf.ns_ppc[0] = (char *)strdup(cp);
if (conf.ns_ppc[0] == NULL) {
free(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else {
char *dp, *dpend;
int fnd = 0;
dpend = strchr(cp, COLONTOK);
len = dpend - cp;
dp = (char *)malloc(len+1);
if (dp == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(dp, cp, len+1);
fnd = 0;
for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
dpend = strchr(ptr->paramList[type].ns_ppc[j],
COLONTOK);
if (dpend == NULL)
continue;
i = dpend - ptr->paramList[type].ns_ppc[j];
if (i != len)
continue;
if (strncmp(ptr->paramList[type].ns_ppc[j],
dp, len) == 0) {
conf.ns_acnt =
ptr->paramList[type].ns_acnt;
conf.ns_ppc =
ptr->paramList[type].ns_ppc;
ptr->paramList[type].ns_ppc = NULL;
free(conf.ns_ppc[j]);
conf.ns_ppc[j] = (char *)strdup(cp);
if (conf.ns_ppc[j] == NULL) {
free(dp);
__s_api_free2dArray
(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
free(dp);
if (fnd)
break;
len = ptr->paramList[type].ns_acnt + 1;
if (len > 1) {
p = (char **)dupParam(&ptr->paramList[type]);
if (p == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
conf.ns_ppc =
(char **)realloc(p, (len+1) * sizeof (char *));
if (conf.ns_ppc == NULL) {
__s_api_free2dArray(p);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
conf.ns_ppc[len-1] = (char *)strdup(cp);
if (conf.ns_ppc[len-1] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_ppc[len] = NULL;
}
break;
case SCLLIST:
if ((strchr(cp, COLONTOK)) == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid serviceCredentialLevel (%s)"),
cp);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
if (ptr->paramList[type].ns_ptype != SCLLIST) {
conf.ns_ppc = (char **)calloc(2, sizeof (char *));
if (conf.ns_ppc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = 1;
conf.ns_ppc[0] = (char *)strdup(cp);
if (conf.ns_ppc[0] == NULL) {
free(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else {
char *dp, *dpend;
int fnd = 0;
dpend = strchr(cp, COLONTOK);
len = dpend - cp;
dp = (char *)malloc(len+1);
if (dp == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(dp, cp, len+1);
fnd = 0;
for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
dpend = strchr(ptr->paramList[type].ns_ppc[j],
COLONTOK);
if (dpend == NULL)
continue;
i = dpend - ptr->paramList[type].ns_ppc[j];
if (i != len)
continue;
if (strncmp(ptr->paramList[type].ns_ppc[j],
dp, len) == 0) {
conf.ns_acnt =
ptr->paramList[type].ns_acnt;
conf.ns_ppc =
ptr->paramList[type].ns_ppc;
ptr->paramList[type].ns_ppc = NULL;
free(conf.ns_ppc[j]);
conf.ns_ppc[j] = (char *)strdup(cp);
if (conf.ns_ppc[j] == NULL) {
free(dp);
__s_api_free2dArray
(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
free(dp);
if (fnd)
break;
len = ptr->paramList[type].ns_acnt + 1;
if (len > 1) {
p = (char **)dupParam(&ptr->paramList[type]);
if (p == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
conf.ns_ppc =
(char **)realloc(p, (len+1) * sizeof (char *));
if (conf.ns_ppc == NULL) {
__s_api_free2dArray(p);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
conf.ns_ppc[len-1] = (char *)strdup(cp);
if (conf.ns_ppc[len-1] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_ppc[len] = NULL;
}
break;
case SSDLIST:
if ((strchr(cp, COLONTOK)) == NULL || *cp == COLONTOK) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid serviceSearchDescriptor (%s)"),
cp);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
if (ptr->paramList[type].ns_ptype != SSDLIST) {
conf.ns_ppc = (char **)calloc(2, sizeof (char *));
if (conf.ns_ppc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = 1;
conf.ns_ppc[0] = (char *)strdup(cp);
if (conf.ns_ppc[0] == NULL) {
free(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else {
char *dp, *dpend;
int fnd = 0;
dpend = strchr(cp, COLONTOK);
len = dpend - cp;
dp = (char *)malloc(len+1);
if (dp == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(dp, cp, len+1);
fnd = 0;
for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
dpend = strchr(ptr->paramList[type].ns_ppc[j],
COLONTOK);
if (dpend == NULL)
continue;
i = dpend - ptr->paramList[type].ns_ppc[j];
if (i != len)
continue;
if (strncmp(ptr->paramList[type].ns_ppc[j],
dp, len) == 0) {
conf.ns_acnt =
ptr->paramList[type].ns_acnt;
conf.ns_ppc =
ptr->paramList[type].ns_ppc;
ptr->paramList[type].ns_ppc = NULL;
free(conf.ns_ppc[j]);
conf.ns_ppc[j] = (char *)strdup(cp);
if (conf.ns_ppc[j] == NULL) {
free(dp);
__s_api_free2dArray
(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
free(dp);
if (fnd)
break;
len = ptr->paramList[type].ns_acnt + 1;
if (len > 1) {
p = (char **)dupParam(&ptr->paramList[type]);
if (p == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
conf.ns_ppc =
(char **)realloc(p, (len+1) * sizeof (char *));
if (conf.ns_ppc == NULL) {
__s_api_free2dArray(p);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
conf.ns_ppc[len-1] = (char *)strdup(cp);
if (conf.ns_ppc[len-1] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_ppc[len] = NULL;
}
break;
case ARRAYCP:
len = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == COMMATOK)
len++;
}
if (cp != cp2)
len++;
if (len == 0) {
conf.ns_ppc = (char **)NULL;
conf.ns_acnt = 0;
break;
}
conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
if (conf.ns_ppc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
i = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == COMMATOK) {
j = cp2 - cp + 1;
conf.ns_ppc[i] = (char *)malloc(j + 1);
if (conf.ns_ppc[i] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(conf.ns_ppc[i], cp, j);
cp = cp2+1;
while (*cp == SPACETOK || *cp == COMMATOK)
cp++;
cp2 = cp - 1;
i++;
}
}
j = cp2 - cp + 1;
conf.ns_ppc[i] = (char *)malloc(j + 1);
if (conf.ns_ppc[i] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(conf.ns_ppc[i], cp, j);
break;
case SERVLIST:
len = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
len++;
for (; *(cp2 + 1) == SPACETOK ||
*(cp2 +1) == COMMATOK; cp2++)
;
}
}
if (cp != cp2)
len++;
if (len == 0) {
conf.ns_ppc = (char **)NULL;
conf.ns_acnt = 0;
break;
}
conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
if (conf.ns_ppc == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
i = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
j = cp2 - cp + 1;
conf.ns_ppc[i] = (char *)malloc(j + 1);
if (conf.ns_ppc[i] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(conf.ns_ppc[i], cp, j);
cp = cp2+1;
while (*cp == SPACETOK || *cp == COMMATOK)
cp++;
cp2 = cp - 1;
i++;
}
}
j = cp2 - cp + 1;
conf.ns_ppc[i] = (char *)malloc(j + 1);
if (conf.ns_ppc[i] == NULL) {
__s_api_free2dArray(conf.ns_ppc);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
(void) strlcpy(conf.ns_ppc[i], cp, j);
break;
case ARRAYAUTH:
len = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SEMITOK || *cp2 == COMMATOK)
len++;
}
if (cp != cp2)
len++;
if (len == 0) {
conf.ns_pi = (int *)NULL;
conf.ns_acnt = 0;
break;
}
conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
if (conf.ns_pi == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
i = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SEMITOK || *cp2 == COMMATOK) {
j = cp2 - cp + 1;
if (j > sizeof (tbuf)) {
j = -1;
ptbuf = cp;
} else {
(void) strlcpy(tbuf, cp, j);
j = __s_get_enum_value(ptr, tbuf,
def->index);
ptbuf = tbuf;
}
if (j < 0) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid "
"authenticationMethod (%s)"),
ptbuf);
MKERROR(LOG_ERR, *error,
NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
free(conf.ns_pi);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_pi[i] = j;
cp = cp2+1;
i++;
}
}
j = cp2 - cp + 1;
if (j > sizeof (tbuf)) {
j = -1;
ptbuf = cp;
} else {
(void) strlcpy(tbuf, cp, j);
j = __s_get_enum_value(ptr, tbuf, def->index);
ptbuf = tbuf;
}
if (j < 0) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid authenticationMethod (%s)"), ptbuf);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_pi[i] = j;
break;
case ARRAYCRED:
len = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SPACETOK)
len++;
}
if (cp != cp2)
len++;
if (len == 0) {
conf.ns_pi = (int *)NULL;
conf.ns_acnt = 0;
break;
}
conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
if (conf.ns_pi == NULL) {
if (tcp != NULL)
free(tcp);
return (NS_LDAP_MEMORY);
}
conf.ns_acnt = len;
i = 0;
for (cp2 = cp; *cp2; cp2++) {
if (*cp2 == SPACETOK) {
j = cp2 - cp + 1;
if (j > sizeof (tbuf)) {
j = -1;
ptbuf = cp;
} else {
(void) strlcpy(tbuf, cp, j);
j = __s_get_enum_value(ptr, tbuf,
def->index);
ptbuf = tbuf;
}
if (j < 0) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid credentialLevel (%s)"),
ptbuf);
MKERROR(LOG_ERR, *error,
NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
free(conf.ns_pi);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_pi[i] = j;
cp = cp2+1;
i++;
}
}
j = cp2 - cp + 1;
if (j > sizeof (tbuf)) {
j = -1;
ptbuf = cp;
} else {
(void) strlcpy(tbuf, cp, j);
j = __s_get_enum_value(ptr, tbuf, def->index);
ptbuf = tbuf;
}
if (j < 0) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid credentialLevel (%s)"), ptbuf);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_pi[i] = j;
break;
case ATTRMAP:
case OBJMAP:
i = __s_api_parse_map(cp, &sid, &origA, &mapA);
if (i != NS_HASH_RC_SUCCESS) {
if (i == NS_HASH_RC_NO_MEMORY) {
exitrc = NS_LDAP_MEMORY;
} else {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: "
"invalid schema mapping (%s)"), cp);
exitrc = NS_LDAP_CONFIG;
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
}
if (tcp)
free(tcp);
return (exitrc);
}
for (attr = mapA; *attr; attr++) {
free_memory = 1;
exitrc = NS_LDAP_MEMORY;
rmap = (ns_mapping_t *)calloc(1,
sizeof (ns_mapping_t));
if (rmap) {
rmap->service = strdup(sid);
if (rmap->service) {
rmap->orig = strdup(*attr);
if (rmap->orig) {
rmap->map = (char **)calloc(2,
sizeof (char *));
if (rmap->map) {
(rmap->map)[0] =
strdup(origA);
if ((rmap->map)[0])
free_memory = 0;
}
}
}
}
if (free_memory == 0) {
if (def->data_type == ATTRMAP) {
rmap->type = NS_ATTR_MAP;
i = __s_api_add_map2hash(ptr,
NS_HASH_RAMAP, rmap);
} else {
rmap->type = NS_OBJ_MAP;
i = __s_api_add_map2hash(ptr,
NS_HASH_ROMAP, rmap);
}
if (i != NS_HASH_RC_SUCCESS) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
exitrc = NS_LDAP_INTERNAL;
(void) snprintf(errstr,
sizeof (errstr),
gettext(
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
MKERROR(LOG_ERR, *error,
NS_LDAP_INTERNAL,
strdup(errstr),
NS_LDAP_MEMORY);
break;
case NS_HASH_RC_EXISTED:
exitrc = NS_LDAP_CONFIG;
(void) snprintf(errstr,
sizeof (errstr),
gettext(
"Unable to set value: "
"schema map "
"already existed for "
"(%s, %s)."),
*attr, origA);
MKERROR(LOG_ERR, *error,
NS_CONFIG_SYNTAX,
strdup(errstr),
NS_LDAP_MEMORY);
break;
case NS_HASH_RC_NO_MEMORY:
exitrc = NS_LDAP_MEMORY;
break;
}
free_memory = 1;
}
}
if (free_memory) {
if (tcp)
free(tcp);
free(sid);
free(origA);
__s_api_free2dArray(mapA);
if (rmap) {
if (rmap->service)
free(rmap->service);
if (rmap->orig)
free(rmap->orig);
if (rmap->map) {
if ((rmap->map)[0])
free((rmap->map)[0]);
free(rmap->map);
}
free(rmap);
}
return (exitrc);
}
}
free_memory = 1;
exitrc = NS_LDAP_MEMORY;
map = (ns_mapping_t *)calloc(1,
sizeof (ns_mapping_t));
if (map) {
map->service = strdup(sid);
if (map->service) {
map->orig = strdup(
NS_HASH_SCHEMA_MAPPING_EXISTED);
if (map->orig) {
map->map = (char **)calloc(2,
sizeof (char *));
if (map->map) {
(map->map)[0] =
strdup(sid);
if ((map->map)[0])
free_memory = 0;
}
}
}
}
if (free_memory == 0) {
map->type = NS_ATTR_MAP;
i = __s_api_add_map2hash(ptr,
NS_HASH_RAMAP, map);
if (i != NS_HASH_RC_SUCCESS &&
i != NS_HASH_RC_EXISTED) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
exitrc = NS_LDAP_INTERNAL;
(void) snprintf(errstr,
sizeof (errstr),
gettext(
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
MKERROR(LOG_ERR, *error,
NS_LDAP_INTERNAL,
strdup(errstr),
NS_LDAP_MEMORY);
break;
case NS_HASH_RC_NO_MEMORY:
exitrc = NS_LDAP_MEMORY;
break;
}
free_memory = 1;
} else if (i == NS_HASH_RC_EXISTED) {
if (map->service)
free(map->service);
if (map->orig)
free(map->orig);
if (map->map) {
if ((map->map)[0])
free((map->map)[0]);
free(map->map);
}
free(map);
map = NULL;
}
}
if (free_memory) {
if (tcp)
free(tcp);
free(sid);
free(origA);
__s_api_free2dArray(mapA);
if (map) {
if (map->service)
free(map->service);
if (map->orig)
free(map->orig);
if (map->map) {
if ((map->map)[0])
free((map->map)[0]);
free(map->map);
}
free(map);
}
return (exitrc);
}
free_memory = 1;
exitrc = NS_LDAP_MEMORY;
map = (ns_mapping_t *)calloc(1, sizeof (ns_mapping_t));
if (map) {
map->service = sid;
map->orig = origA;
map->map = mapA;
if (def->data_type == ATTRMAP) {
map->type = NS_ATTR_MAP;
i = __s_api_add_map2hash(ptr,
NS_HASH_AMAP, map);
} else {
map->type = NS_OBJ_MAP;
i = __s_api_add_map2hash(ptr,
NS_HASH_OMAP, map);
}
if (i != NS_HASH_RC_SUCCESS) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
exitrc = NS_LDAP_INTERNAL;
(void) snprintf(errstr,
sizeof (errstr),
gettext(
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
MKERROR(LOG_ERR, *error,
NS_LDAP_INTERNAL,
strdup(errstr),
NS_LDAP_MEMORY);
break;
case NS_HASH_RC_EXISTED:
exitrc = NS_LDAP_CONFIG;
(void) snprintf(errstr,
sizeof (errstr),
gettext(
"Unable to set value: "
"schema map "
"already existed for "
"'%s'."), origA);
MKERROR(LOG_ERR, *error,
NS_CONFIG_SYNTAX,
strdup(errstr),
NS_LDAP_MEMORY);
break;
case NS_HASH_RC_NO_MEMORY:
exitrc = NS_LDAP_MEMORY;
break;
}
free_memory = 1;
} else
free_memory = 0;
}
if (free_memory) {
if (tcp)
free(tcp);
free(sid);
free(origA);
__s_api_free2dArray(mapA);
if (map)
free(map);
return (exitrc);
}
break;
default:
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set value: invalid configuration "
"type (%d)"), def->data_type);
MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
NS_LDAP_MEMORY);
if (tcp != NULL)
free(tcp);
return (NS_LDAP_CONFIG);
}
conf.ns_ptype = def->data_type;
if (tcp != NULL)
free(tcp);
if (def->ns_verify != NULL) {
if ((*def->ns_verify)(type, def, &conf, errstr) != NS_SUCCESS) {
ns_param_t sav_conf;
MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
sav_conf = ptr->paramList[type];
ptr->paramList[type] = conf;
destroy_param(ptr, type);
ptr->paramList[type] = sav_conf;
return (NS_LDAP_CONFIG);
}
}
if (type == NS_LDAP_BINDPASSWD_P ||
type == NS_LDAP_ADMIN_BINDPASSWD_P) {
cp = conf.ns_pc;
cp2 = evalue((char *)cp);
conf.ns_pc = cp2;
free(cp);
cp = NULL;
} else if (type == NS_LDAP_FILE_VERSION_P) {
ptr->version = NS_LDAP_V1;
if (strcasecmp(conf.ns_pc, NS_LDAP_VERSION_2) == 0) {
ptr->version = NS_LDAP_V2;
}
} else if (type == NS_LDAP_CACHETTL_P) {
cp = conf.ns_pc;
tm = conv_time(cp);
ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
if (tm != 0) {
tm += time(NULL);
}
ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
}
destroy_param(ptr, type);
ptr->paramList[type] = conf;
return (NS_LDAP_SUCCESS);
}
int
__ns_ldap_setParam(const ParamIndexType type,
const void *data, ns_ldap_error_t **error)
{
ns_ldap_error_t *errorp;
int ret;
char errstr[2 * MAXERROR];
ns_config_t *cfg;
ns_config_t *cfg_g = (ns_config_t *)-1;
ns_config_t *new_cfg;
boolean_t reinit_connmgmt = B_FALSE;
(void) mutex_lock(&ns_loadrefresh_lock);
cfg = __s_api_get_default_config();
if (cache_server == TRUE) {
if (cfg == NULL) {
__ns_ldap_default_config();
cfg = __s_api_get_default_config();
if (cfg == NULL) {
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_MEMORY);
}
}
} else {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to set parameter from a client in "
"__ns_ldap_setParam()"));
MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX, strdup(errstr),
NS_LDAP_MEMORY);
if (cfg != NULL)
__s_api_release_config(cfg);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
if (!__s_api_isStandalone() &&
cache_server == FALSE && timetorefresh(cfg))
cfg_g = __s_api_get_default_config_global();
if (cfg == cfg_g) {
if (cfg_g != NULL)
__s_api_release_config(cfg_g);
new_cfg = LoadCacheConfiguration(cfg, &errorp);
if (new_cfg != cfg)
__s_api_release_config(cfg);
if (new_cfg == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to load configuration '%s' "
"('%s')."), NSCONFIGFILE,
errorp != NULL && errorp->message != NULL ?
errorp->message : "");
MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
strdup(errstr), NS_LDAP_MEMORY);
if (errorp != NULL)
(void) __ns_ldap_freeError(&errorp);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
if (new_cfg != cfg) {
set_curr_config_global(new_cfg);
cfg = new_cfg;
reinit_connmgmt = B_TRUE;
}
}
(void) mutex_unlock(&ns_loadrefresh_lock);
if (reinit_connmgmt == B_TRUE)
__s_api_reinit_conn_mgmt_new_config(cfg);
ret = __ns_ldap_setParamValue(cfg, type, data, error);
__s_api_release_config(cfg);
return (ret);
}
static void **
dupParam(ns_param_t *ptr)
{
int count, i;
void **dupdata, *ret;
int *intptr;
char *cp, tmbuf[32];
static time_t expire = 0;
ns_auth_t *ap;
switch (ptr->ns_ptype) {
case ARRAYAUTH:
case ARRAYCRED:
case SAMLIST:
case SCLLIST:
case SSDLIST:
case SERVLIST:
case ARRAYCP:
count = ptr->ns_acnt;
if (count == 0)
return (NULL);
break;
case CHARPTR:
case INT:
case TIMET:
count = 1;
}
dupdata = (void **)calloc((count + 1), sizeof (void *));
if (dupdata == NULL)
return (NULL);
switch (ptr->ns_ptype) {
case ARRAYAUTH:
for (i = 0; i < count; i++) {
ap = __s_api_AuthEnumtoStruct(
(EnumAuthType_t)ptr->ns_pi[i]);
if (ap == NULL) {
free(dupdata);
return (NULL);
}
dupdata[i] = ap;
}
break;
case ARRAYCRED:
for (i = 0; i < count; i++) {
intptr = (int *)malloc(sizeof (int));
if (intptr == NULL) {
free(dupdata);
return (NULL);
}
dupdata[i] = (void *)intptr;
*intptr = ptr->ns_pi[i];
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
case SERVLIST:
case ARRAYCP:
for (i = 0; i < count; i++) {
ret = (void *)strdup(ptr->ns_ppc[i]);
if (ret == NULL) {
free(dupdata);
return (NULL);
}
dupdata[i] = ret;
}
break;
case CHARPTR:
if (ptr->ns_pc == NULL) {
free(dupdata);
return (NULL);
}
ret = (void *)strdup(ptr->ns_pc);
if (ret == NULL) {
free(dupdata);
return (NULL);
}
dupdata[0] = ret;
break;
case INT:
intptr = (int *)malloc(sizeof (int));
if (intptr == NULL) {
free(dupdata);
return (NULL);
}
*intptr = ptr->ns_i;
dupdata[0] = (void *)intptr;
break;
case TIMET:
expire = ptr->ns_tm;
tmbuf[31] = '\0';
cp = lltostr((long)expire, &tmbuf[31]);
ret = (void *)strdup(cp);
if (ret == NULL) {
free(dupdata);
return (NULL);
}
dupdata[0] = ret;
break;
}
return (dupdata);
}
int
__ns_ldap_freeParam(void ***data)
{
void **tmp;
int i = 0;
if (*data == NULL)
return (NS_LDAP_SUCCESS);
for (i = 0, tmp = *data; tmp[i] != NULL; i++)
free(tmp[i]);
free(*data);
*data = NULL;
return (NS_LDAP_SUCCESS);
}
int
__ns_ldap_getParam(const ParamIndexType Param,
void ***data, ns_ldap_error_t **error)
{
char errstr[2 * MAXERROR];
ns_ldap_error_t *errorp;
ns_default_config *def;
ns_config_t *cfg;
ns_config_t *cfg_g = (ns_config_t *)-1;
ns_config_t *new_cfg;
boolean_t reinit_connmgmt = B_FALSE;
if (data == NULL)
return (NS_LDAP_INVALID_PARAM);
*data = NULL;
(void) mutex_lock(&ns_loadrefresh_lock);
cfg = __s_api_get_default_config();
if (!__s_api_isStandalone() &&
cache_server == FALSE && timetorefresh(cfg))
cfg_g = __s_api_get_default_config_global();
if (cfg == cfg_g) {
if (cfg_g != NULL)
__s_api_release_config(cfg_g);
new_cfg = LoadCacheConfiguration(cfg, &errorp);
if (new_cfg != cfg)
__s_api_release_config(cfg);
if (new_cfg == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Unable to load configuration "
"'%s' ('%s')."),
NSCONFIGFILE,
errorp != NULL && errorp->message != NULL ?
errorp->message : "");
MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
strdup(errstr), NS_LDAP_MEMORY);
if (errorp != NULL)
(void) __ns_ldap_freeError(&errorp);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
if (new_cfg != cfg) {
set_curr_config_global(new_cfg);
cfg = new_cfg;
reinit_connmgmt = B_TRUE;
}
}
(void) mutex_unlock(&ns_loadrefresh_lock);
if (reinit_connmgmt == B_TRUE)
__s_api_reinit_conn_mgmt_new_config(cfg);
if (cfg == NULL) {
(void) snprintf(errstr, sizeof (errstr),
gettext("No configuration information available."));
MKERROR(LOG_ERR, *error, NS_CONFIG_NOTLOADED,
strdup(errstr), NS_LDAP_MEMORY);
return (NS_LDAP_CONFIG);
}
if (Param == NS_LDAP_DOMAIN_P) {
*data = (void **)calloc(2, sizeof (void *));
if (*data == NULL) {
__s_api_release_config(cfg);
return (NS_LDAP_MEMORY);
}
(*data)[0] = (void *)strdup(cfg->domainName);
if ((*data)[0] == NULL) {
free(*data);
__s_api_release_config(cfg);
return (NS_LDAP_MEMORY);
}
} else if (cfg->paramList[Param].ns_ptype == NS_UNKNOWN) {
def = get_defconfig(cfg, Param);
if (def != NULL)
*data = dupParam(&def->defval);
} else {
*data = dupParam(&(cfg->paramList[Param]));
}
__s_api_release_config(cfg);
return (NS_LDAP_SUCCESS);
}
char *
__s_api_strValue(ns_config_t *cfg, ParamIndexType index, ns_strfmt_t fmt)
{
ns_default_config *def = NULL;
ns_param_t *ptr;
ns_hash_t *hptr;
ns_mapping_t *mptr;
char ibuf[14];
char abuf[64], **cpp;
int count, i;
boolean_t first = B_TRUE;
LineBuf lbuf;
LineBuf *buffer = &lbuf;
char *retstring;
char *sepstr;
if (cfg == NULL)
return (NULL);
if (index == NS_LDAP_EXP_P || index == NS_LDAP_TRANSPORT_SEC_P)
return (NULL);
if (cfg->paramList[index].ns_ptype == NS_UNKNOWN)
return (NULL);
(void) memset((char *)buffer, 0, sizeof (LineBuf));
ptr = &(cfg->paramList[index]);
abuf[0] = '\0';
def = get_defconfig(cfg, index);
if (def == NULL)
return (NULL);
switch (fmt) {
case NS_DOOR_FMT:
(void) strlcpy(abuf, def->name, sizeof (abuf));
(void) strlcat(abuf, EQUALSEP, sizeof (abuf));
break;
case NS_FILE_FMT:
(void) strlcpy(abuf, def->name, sizeof (abuf));
(void) strlcat(abuf, EQUSPSEP, sizeof (abuf));
break;
case NS_LDIF_FMT:
if (def->profile_name == NULL)
return (NULL);
(void) strlcpy(abuf, def->profile_name, sizeof (abuf));
(void) strlcat(abuf, COLSPSEP, sizeof (abuf));
break;
default:
break;
}
if (__print2buf(buffer, abuf, NULL))
goto strValueError;
switch (ptr->ns_ptype) {
case ARRAYAUTH:
count = ptr->ns_acnt;
for (i = 0; i < count; i++) {
sepstr = NULL;
if (i != count-1) {
if (cfg->version == NS_LDAP_V1) {
sepstr = COMMASEP;
} else {
sepstr = SEMISEP;
}
}
if (__print2buf(buffer, __s_get_auth_name(cfg,
(AuthType_t)(ptr->ns_pi[i])), sepstr))
goto strValueError;
}
break;
case ARRAYCRED:
count = ptr->ns_acnt;
for (i = 0; i < count; i++) {
sepstr = NULL;
if (i != count-1) {
sepstr = SPACESEP;
}
if (__print2buf(buffer, __s_get_credlvl_name(cfg,
(CredLevel_t)ptr->ns_pi[i]), sepstr))
goto strValueError;
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
count = ptr->ns_acnt;
for (i = 0; i < count; i++) {
if (__print2buf(buffer, ptr->ns_ppc[i], NULL))
goto strValueError;
if (i == count-1)
continue;
switch (fmt) {
case NS_DOOR_FMT:
if (__print2buf(buffer, DOORLINESEP, NULL) ||
__print2buf(buffer, def->name, EQUALSEP))
goto strValueError;
break;
case NS_FILE_FMT:
if (__print2buf(buffer, "\n", NULL) ||
__print2buf(buffer, def->name, EQUSPSEP))
goto strValueError;
break;
case NS_LDIF_FMT:
if (__print2buf(buffer, "\n", NULL) ||
__print2buf(buffer, def->profile_name,
COLSPSEP))
goto strValueError;
break;
}
}
break;
case ARRAYCP:
count = ptr->ns_acnt;
for (i = 0; i < count; i++) {
sepstr = NULL;
if (i != count-1) {
sepstr = COMMASEP;
}
if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
goto strValueError;
}
break;
case SERVLIST:
count = ptr->ns_acnt;
for (i = 0; i < count; i++) {
sepstr = NULL;
if (i != count-1) {
if (fmt == NS_LDIF_FMT) {
sepstr = SPACESEP;
} else {
sepstr = COMMASEP;
}
}
if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
goto strValueError;
}
break;
case CHARPTR:
if (ptr->ns_pc == NULL)
break;
if (__print2buf(buffer, ptr->ns_pc, NULL))
goto strValueError;
break;
case INT:
switch (def->index) {
case NS_LDAP_PREF_ONLY_P:
if (__print2buf(buffer,
__s_get_pref_name((PrefOnly_t)ptr->ns_i), NULL))
goto strValueError;
break;
case NS_LDAP_SEARCH_REF_P:
if (__print2buf(buffer, __s_get_searchref_name(cfg,
(SearchRef_t)ptr->ns_i), NULL))
goto strValueError;
break;
case NS_LDAP_SEARCH_SCOPE_P:
if (__print2buf(buffer, __s_get_scope_name(cfg,
(ScopeType_t)ptr->ns_i), NULL))
goto strValueError;
break;
case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
if (__print2buf(buffer, __s_get_shadowupdate_name(
(enableShadowUpdate_t)ptr->ns_i), NULL))
goto strValueError;
break;
default:
(void) snprintf(ibuf, sizeof (ibuf),
"%d", ptr->ns_i);
if (__print2buf(buffer, ibuf, NULL))
goto strValueError;
break;
}
break;
case ATTRMAP:
for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
if (hptr->h_type != NS_HASH_AMAP) {
continue;
}
if (!first) {
if (fmt == NS_DOOR_FMT) {
if (__print2buf(buffer, DOORLINESEP,
abuf))
goto strValueError;
} else {
if (__print2buf(buffer, "\n", abuf))
goto strValueError;
}
}
mptr = hptr->h_map;
if (__print2buf(buffer, mptr->service, COLONSEP) ||
__print2buf(buffer, mptr->orig, EQUALSEP))
goto strValueError;
for (cpp = mptr->map; cpp && *cpp; cpp++) {
sepstr = "";
if (cpp != mptr->map)
sepstr = SPACESEP;
if (__print2buf(buffer, sepstr, *cpp))
goto strValueError;
}
first = B_FALSE;
}
break;
case OBJMAP:
for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
if (hptr->h_type != NS_HASH_OMAP) {
continue;
}
if (!first) {
if (fmt == NS_DOOR_FMT) {
if (__print2buf(buffer, DOORLINESEP,
abuf))
goto strValueError;
} else {
if (__print2buf(buffer, "\n", abuf))
goto strValueError;
}
}
mptr = hptr->h_map;
if (__print2buf(buffer, mptr->service, COLONSEP) ||
__print2buf(buffer, mptr->orig, EQUALSEP))
goto strValueError;
for (cpp = mptr->map; cpp && *cpp; cpp++) {
sepstr = "";
if (cpp != mptr->map)
sepstr = SPACESEP;
if (__print2buf(buffer, sepstr, *cpp))
goto strValueError;
}
first = B_FALSE;
}
break;
}
retstring = buffer->str;
return (retstring);
strValueError:
if (buffer->len > 0)
free(buffer->str);
return (NULL);
}
int
__door_getconf(char **buffer, int *buflen, ns_ldap_error_t **error,
int callnumber)
{
typedef union {
ldap_data_t s_d;
char s_b[DOORBUFFERSIZE];
} space_t;
space_t *space;
ldap_data_t *sptr;
int ndata;
int adata;
char errstr[MAXERROR];
char *domainname;
ns_ldap_return_code retCode;
ldap_config_out_t *cfghdr;
*error = NULL;
domainname = __getdomainname();
if (domainname == NULL || buffer == NULL || buflen == NULL ||
(strlen(domainname) >= (sizeof (space_t)
- sizeof (space->s_d.ldap_call.ldap_callnumber)))) {
return (NS_LDAP_OP_FAILED);
}
space = (space_t *)calloc(1, sizeof (space_t));
if (space == NULL)
return (NS_LDAP_MEMORY);
adata = (sizeof (ldap_call_t) + strlen(domainname) +1);
ndata = sizeof (space_t);
space->s_d.ldap_call.ldap_callnumber = callnumber;
(void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname);
free(domainname);
domainname = NULL;
sptr = &space->s_d;
switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) {
case NS_CACHE_SUCCESS:
break;
case NS_CACHE_NOTFOUND:
(void) snprintf(errstr, sizeof (errstr),
gettext("Door call to "
"ldap_cachemgr failed - error: %d."),
space->s_d.ldap_ret.ldap_errno);
MKERROR(LOG_WARNING, *error, NS_CONFIG_CACHEMGR,
strdup(errstr), NS_LDAP_MEMORY);
free(space);
return (NS_LDAP_OP_FAILED);
default:
free(space);
return (NS_LDAP_OP_FAILED);
}
retCode = NS_LDAP_SUCCESS;
cfghdr = &sptr->ldap_ret.ldap_u.config_str;
*buflen = offsetof(ldap_config_out_t, config_str) +
cfghdr->data_size + 1;
*buffer = calloc(*buflen, sizeof (char));
if (*buffer == NULL) {
retCode = NS_LDAP_MEMORY;
} else
(void) memcpy(*buffer, cfghdr, *buflen - 1);
if (sptr != &space->s_d) {
(void) munmap((char *)sptr, ndata);
}
free(space);
return (retCode);
}
static int
__door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error)
{
return (__door_getconf(buffer, buflen, error, GETLDAPCONFIGV1));
}
int
SetDoorInfoToUnixCred(char *buffer, ns_ldap_error_t **errorp,
UnixCred_t **cred)
{
UnixCred_t *ptr;
char errstr[MAXERROR];
char *name, *value, valbuf[BUFSIZE];
char *bufptr = buffer;
char *strptr;
char *rest;
ParamIndexType index = 0;
ldap_config_out_t *cfghdr;
if (errorp == NULL || cred == NULL || *cred == NULL)
return (NS_LDAP_INVALID_PARAM);
*errorp = NULL;
ptr = *cred;
cfghdr = (ldap_config_out_t *)bufptr;
bufptr = (char *)cfghdr->config_str;
strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
for (; ; ) {
if (strptr == NULL)
break;
(void) strlcpy(valbuf, strptr, sizeof (valbuf));
__s_api_split_key_value(valbuf, &name, &value);
if (__ns_ldap_getParamType(name, &index) != 0) {
(void) snprintf(errstr, MAXERROR,
gettext("SetDoorInfoToUnixCred: "
"Unknown keyword encountered '%s'."), name);
MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
return (NS_LDAP_CONFIG);
}
switch (index) {
case NS_LDAP_ADMIN_BINDDN_P:
ptr->userID = (char *)strdup(value);
break;
case NS_LDAP_ADMIN_BINDPASSWD_P:
ptr->passwd = (char *)strdup(value);
break;
default:
(void) snprintf(errstr, MAXERROR,
gettext("SetDoorInfoToUnixCred: "
"Unknown index encountered '%d'."), index);
MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
strdup(errstr), NS_LDAP_MEMORY);
return (NS_LDAP_CONFIG);
}
strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
}
return (NS_LDAP_SUCCESS);
}
static ns_config_t *
SetDoorInfo(char *buffer, ns_ldap_error_t **errorp)
{
ns_config_t *ptr;
char errstr[MAXERROR], errbuf[MAXERROR];
char *name, *value, valbuf[BUFSIZE];
char *strptr;
char *rest;
char *bufptr = buffer;
ParamIndexType i;
int ret;
int first = 1;
int errfnd = 0;
ldap_config_out_t *cfghdr;
if (errorp == NULL)
return (NULL);
*errorp = NULL;
ptr = __s_api_create_config();
if (ptr == NULL) {
return (NULL);
}
cfghdr = (ldap_config_out_t *)bufptr;
ptr->config_cookie = cfghdr->cookie;
bufptr = (char *)cfghdr->config_str;
strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
for (; ; ) {
if (strptr == NULL)
break;
(void) strlcpy(valbuf, strptr, sizeof (valbuf));
__s_api_split_key_value(valbuf, &name, &value);
if (__s_api_get_versiontype(ptr, name, &i) < 0) {
(void) snprintf(errstr, sizeof (errstr),
"%s (%s)\n",
gettext("Illegal profile entry "
"line in configuration."),
name);
errfnd++;
} else if (verify_value(ptr, name,
value, errbuf) != NS_SUCCESS) {
(void) snprintf(errstr, sizeof (errstr),
gettext("%s\n"), errbuf);
errfnd++;
} else if (!first && i == NS_LDAP_FILE_VERSION_P) {
(void) snprintf(errstr, sizeof (errstr),
gettext("Illegal NS_LDAP_FILE_VERSION "
"line in configuration.\n"));
errfnd++;
}
if (errfnd) {
MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
strdup(errstr), NULL);
} else {
ret = set_default_value(ptr, name, value, errorp);
}
if (errfnd || ret != NS_SUCCESS) {
__s_api_destroy_config(ptr);
return (NULL);
}
first = 0;
strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
}
if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
__s_api_destroy_config(ptr);
MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, strdup(errstr),
NULL);
return (NULL);
}
return (ptr);
}
static ns_config_t *
LoadCacheConfiguration(ns_config_t *oldcfg, ns_ldap_error_t **error)
{
char *buffer = NULL;
int buflen = 0;
int ret;
ns_config_t *cfg;
ldap_config_out_t *cfghdr;
ldap_get_chg_cookie_t old_cookie;
ldap_get_chg_cookie_t new_cookie;
*error = NULL;
ret = __door_getldapconfig(&buffer, &buflen, error);
if (ret != NS_LDAP_SUCCESS) {
if (*error != NULL && (*error)->message != NULL)
syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
return (NULL);
}
cfghdr = (ldap_config_out_t *)buffer;
new_cookie = cfghdr->cookie;
if (oldcfg != NULL)
old_cookie = oldcfg->config_cookie;
if (oldcfg != NULL && old_cookie.mgr_pid == new_cookie.mgr_pid &&
old_cookie.seq_num == new_cookie.seq_num) {
free(buffer);
return (oldcfg);
}
cfg = SetDoorInfo(buffer, error);
free(buffer);
if (cfg == NULL && *error != NULL && (*error)->message != NULL)
syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
return (cfg);
}
static time_t
conv_time(char *s)
{
time_t t;
char c;
int l, m;
long tot;
l = strlen(s);
if (l == 0)
return (0);
c = s[--l];
m = 0;
switch (c) {
case 'w':
m = 604800;
break;
case 'd':
m = 86400;
break;
case 'h':
m = 3600;
break;
case 'm':
m = 60;
break;
case 's':
m = 1;
break;
}
if (m != 0)
s[l] = '\0';
else
m = 1;
errno = 0;
tot = atol(s);
if ((0 == tot) && (EINVAL == errno))
return (0);
if (((LONG_MAX == tot) || (LONG_MIN == tot)) && (EINVAL == errno))
return (0);
tot = tot * m;
t = (time_t)tot;
return (t);
}
ns_auth_t *
__s_api_AuthEnumtoStruct(const EnumAuthType_t i)
{
ns_auth_t *ap;
ap = (ns_auth_t *)calloc(1, sizeof (ns_auth_t));
if (ap == NULL)
return (NULL);
switch (i) {
case NS_LDAP_EA_NONE:
break;
case NS_LDAP_EA_SIMPLE:
ap->type = NS_LDAP_AUTH_SIMPLE;
break;
case NS_LDAP_EA_SASL_CRAM_MD5:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
break;
case NS_LDAP_EA_SASL_DIGEST_MD5:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
break;
case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
ap->saslopt = NS_LDAP_SASLOPT_INT;
break;
case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
ap->saslopt = NS_LDAP_SASLOPT_PRIV;
break;
case NS_LDAP_EA_SASL_EXTERNAL:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_EXTERNAL;
break;
case NS_LDAP_EA_SASL_GSSAPI:
ap->type = NS_LDAP_AUTH_SASL;
ap->saslmech = NS_LDAP_SASL_GSSAPI;
ap->saslopt = NS_LDAP_SASLOPT_INT |
NS_LDAP_SASLOPT_PRIV;
break;
case NS_LDAP_EA_TLS_NONE:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_NONE;
break;
case NS_LDAP_EA_TLS_SIMPLE:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SIMPLE;
break;
case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SASL;
ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
break;
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
break;
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
ap->saslopt = NS_LDAP_SASLOPT_INT;
break;
case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SASL;
ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
ap->saslopt = NS_LDAP_SASLOPT_PRIV;
break;
case NS_LDAP_EA_TLS_SASL_EXTERNAL:
ap->type = NS_LDAP_AUTH_TLS;
ap->tlstype = NS_LDAP_TLS_SASL;
ap->saslmech = NS_LDAP_SASL_EXTERNAL;
break;
default:
free(ap);
return (NULL);
}
return (ap);
}
static int
__s_val_postime(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf)
{
char *cp;
long tot;
if (param && param->ns_ptype == CHARPTR && param->ns_pc) {
for (cp = param->ns_pc; cp && *cp; cp++) {
if (*cp >= '0' && *cp <= '9')
continue;
switch (*cp) {
case 'w':
case 'd':
case 'h':
case 'm':
case 's':
if (*(cp+1) == '\0') {
break;
}
default:
(void) strcpy(errbuf, "Illegal time value");
return (NS_PARSE_ERR);
}
}
tot = atol(param->ns_pc);
if (tot >= 0)
return (NS_SUCCESS);
}
(void) snprintf(errbuf, MAXERROR,
gettext("Illegal time value in %s"), def->name);
return (NS_PARSE_ERR);
}
static int
__s_val_basedn(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf)
{
if (param && param->ns_ptype == CHARPTR &&
i == NS_LDAP_SEARCH_BASEDN_P &&
((param->ns_pc == NULL) ||
(*(param->ns_pc) == '\0') ||
(strchr(param->ns_pc, '=') != NULL)))
{
return (NS_SUCCESS);
}
(void) snprintf(errbuf, MAXERROR,
gettext("Non-existent or invalid DN in %s"),
def->name);
return (NS_PARSE_ERR);
}
static int
__s_val_serverList(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf)
{
for (i = 0; i < param->ns_acnt; i++) {
if ((__s_api_isipv4(param->ns_ppc[i])) ||
(__s_api_isipv6(param->ns_ppc[i])) ||
(__s_api_ishost(param->ns_ppc[i]))) {
continue;
}
(void) snprintf(errbuf, MAXERROR,
gettext("Invalid server (%s) in %s"),
param->ns_ppc[i], def->name);
return (NS_PARSE_ERR);
}
return (NS_SUCCESS);
}
static int
__s_val_binddn(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf)
{
char *dntype;
if (param && param->ns_ptype == CHARPTR &&
(i == NS_LDAP_BINDDN_P || i == NS_LDAP_ADMIN_BINDDN_P) &&
((param->ns_pc == NULL) ||
((*(param->ns_pc) != '\0') &&
(strchr(param->ns_pc, '=') != NULL)))) {
return (NS_SUCCESS);
}
if (i == NS_LDAP_BINDDN_P)
dntype = "proxy";
else
dntype = "update";
(void) snprintf(errbuf, MAXERROR,
gettext("NULL or invalid %s bind DN"), dntype);
return (NS_PARSE_ERR);
}
static int
__s_val_bindpw(ParamIndexType i, ns_default_config *def,
ns_param_t *param, char *errbuf)
{
char *pwtype;
if (param && param->ns_ptype == CHARPTR &&
(i == NS_LDAP_BINDPASSWD_P || i == NS_LDAP_ADMIN_BINDPASSWD_P) &&
((param->ns_pc == NULL) ||
(*(param->ns_pc) != '\0'))) {
return (NS_SUCCESS);
}
if (i == NS_LDAP_BINDPASSWD_P)
pwtype = "proxy";
else
pwtype = "admin";
(void) snprintf(errbuf, MAXERROR,
gettext("NULL %s bind password"), pwtype);
return (NS_PARSE_ERR);
}
char *
__s_get_hostcertpath(void)
{
ns_config_t *cfg;
ns_param_t *param;
char *ret = NULL;
cfg = __s_api_get_default_config();
if (cfg != NULL) {
param = &cfg->paramList[NS_LDAP_HOST_CERTPATH_P];
if (param->ns_ptype == CHARPTR)
ret = strdup(param->ns_pc);
__s_api_release_config(cfg);
}
if (ret == NULL)
ret = strdup(NSLDAPDIRECTORY);
return (ret);
}
static void
_free_config()
{
if (current_config != NULL)
destroy_config(current_config);
current_config = NULL;
}