/*
* 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
*/
/*
*/
/*
* libsldap - library side configuration components
* Routines to manage the config structure
*/
#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 <syslog.h>
#include <netdb.h>
#include <sys/systeminfo.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, \
extern thread_key_t ns_cmgkey;
/*
* Parameter Index Type validation routines
*/
static int
static int
static int
static int
static int
/*
* Forward declarations
*/
static ns_parse_status
static int
ns_ldap_error_t **error);
static void
static int
static ns_config_t *
static boolean_t
static ns_config_t *
static void **
static time_t
conv_time(char *s);
/*
* Structures used in enum <-> string mapping routines
*/
{ -1, NULL },
};
"sasl/DIGEST-MD5:auth-int" },
"sasl/DIGEST-MD5:auth-conf" },
"tls:sasl/DIGEST-MD5:auth-int" },
"tls:sasl/DIGEST-MD5:auth-conf" },
{ -1, NULL },
};
/* V1 ONLY */
{ -1, NULL },
};
/* V2 ONLY */
{ -1, NULL },
};
{ -1, NULL },
};
{ -1, NULL },
};
{ -1, NULL },
};
{ -1, NULL },
};
{ -1, NULL },
};
{ -1, NULL },
};
static int ns_def_auth_v1[] = {
0
};
static int ns_def_auth_v2[] = {
0
};
static int ns_def_cred_v1[] = {
0
};
static int ns_def_cred_v2[] = {
0
};
/*
* The next macro places an integer in the first sizeof(int) bytes of a
* void pointer location. For 32-bit, it is the same as "(void *) i". It
* is used to solve a problem found during 64-bit testing. The problem
* was that for a configuration parameter such as NS_LDAP_SEARCH_REF_P,
* which is of type INT and has defined default value, an int
* variable(ns_param.ns_pu.i) defined inside an union(ns_pu) structure, is
* used to access the defined default value. This requires the default
* value to be in the first sizeof(int) bytes of the union element. If
* just using "(void *) intval" to declare the default value in the
* following defconfig[] structure, the intval data will be placed is the
* last sizeof(int) bytes. In which case, when accessing via ns_pu_i in
* a 64-bit system, ZERO will be returned as the default value, not the
* defined one.
*
* Note since amd64 is little-endian, the problem is not an issue.
* INT2VOIDPTR will just leave the data (i) unchanged.
*/
#if defined(__amd64)
#define INT2VOIDPTR(i) (void *)i
#else
#define INT2VOIDPTR(i) \
(void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
#endif
/*
* The default configuration table
* Version 1 entries are first, V2 entries follow.
*/
/* optional V1 profile */
{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
NULL, /* No version number defined in V1 */
{ CHARPTR, 0, (void *)NS_LDAP_VERSION_1 },
/* ---------- V1 profile ---------- */
{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
__s_val_binddn, NULL },
{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
__s_val_bindpw, NULL },
{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
__s_val_basedn, NULL },
{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
NULL, ns_auth_enum_v1 },
{"NS_LDAP_TRANSPORT_SEC", NS_LDAP_TRANSPORT_SEC_P,
NULL, ns_sec_enum_v1 },
{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
NULL, ns_ref_enum_v1 },
{"NS_LDAP_DOMAIN", NS_LDAP_DOMAIN_P,
NULL, /* not defined in the Profile */
{"NS_LDAP_EXP", NS_LDAP_EXP_P,
NULL, /* initialized by code to time+NS_LDAP_CACHETTL */
{ INT, 0, 0 },
{"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P,
{"NS_LDAP_CERT_PASS", NS_LDAP_CERT_PASS_P,
{"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P,
{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
NULL, ns_scope_enum_v1 },
{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
{"NS_LDAP_PREF_ONLY", NS_LDAP_PREF_ONLY_P,
NULL, ns_pref_enum },
{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
__s_val_postime, NULL },
{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
/* This configuration option is not visible in V1 */
{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
NULL, /* No version defined in V1 */
{ ARRAYCRED, 0, (void *)&ns_def_cred_v1[0] },
/* ---------- V2 profile ---------- */
{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
NULL, /* No version number defined in V1 */
{ CHARPTR, 0, (void *)NS_LDAP_VERSION_2 },
{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
NULL, /* not defined in the Profile */
__s_val_binddn, NULL },
{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
NULL, /* not defined in the Profile */
__s_val_bindpw, NULL },
{"NS_LDAP_ENABLE_SHADOW_UPDATE", NS_LDAP_ENABLE_SHADOW_UPDATE_P,
NULL, /* not defined in the Profile */
{"NS_LDAP_ADMIN_BINDDN", NS_LDAP_ADMIN_BINDDN_P,
NULL, /* not defined in the Profile */
__s_val_binddn, NULL },
{"NS_LDAP_ADMIN_BINDPASSWD", NS_LDAP_ADMIN_BINDPASSWD_P,
NULL, /* not defined in the Profile */
__s_val_bindpw, NULL },
{"NS_LDAP_EXP", NS_LDAP_EXP_P,
NULL, /* initialized by code to time+NS_LDAP_CACHETTL */
{ INT, 0, 0 },
{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
__s_val_basedn, NULL },
{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
NULL, ns_scope_enum_v2 },
{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
NULL, ns_auth_enum_v2 },
{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
{ ARRAYCRED, 0, (void *)&ns_def_cred_v2[0] },
NULL, ns_cred_enum_v2 },
{"NS_LDAP_SERVICE_SEARCH_DESC", NS_LDAP_SERVICE_SEARCH_DESC_P,
{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
NULL, ns_ref_enum_v2 },
{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
__s_val_postime, NULL },
{"NS_LDAP_ATTRIBUTEMAP", NS_LDAP_ATTRIBUTEMAP_P,
{"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P,
{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
{"NS_LDAP_SERVICE_AUTH_METHOD", NS_LDAP_SERVICE_AUTH_METHOD_P,
{"NS_LDAP_SERVICE_CRED_LEVEL", NS_LDAP_SERVICE_CRED_LEVEL_P,
{"NS_LDAP_HOST_CERTPATH", NS_LDAP_HOST_CERTPATH_P,
NULL, /* not defined in the Profile */
{ CHARPTR, 0, (void *)NSLDAPDIRECTORY },
/* array terminator [not an entry] */
NULL,
{ NS_UNKNOWN, 0, NULL },
};
static char *
{
/*
* The sysinfo man page recommends using a buffer size
* of 257 bytes. MAXHOSTNAMELEN is 256. So add 1 here.
*/
int status;
if (status < 0)
return (NULL);
/* error: not enough space to hold returned value */
return (NULL);
}
void
{
cache_server = set;
}
static boolean_t
{
return (B_TRUE);
else
return (B_TRUE);
}
int
{
char *pend;
int len;
return (-1);
/* skip leading spaces */
pstart++;
/* skip trailing spaces */
;
if (len == 0)
return (-1);
switch (i) {
case NS_LDAP_AUTH_P:
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:
mapp = &ns_scope_enum_v1[0];
else
mapp = &ns_scope_enum_v2[0];
break;
case NS_LDAP_SEARCH_REF_P:
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;
mapp = &ns_shadow_update_enum[0];
break;
return (-1);
else
mapp = &ns_cred_enum_v2[0];
break;
mapp = &ns_auth_enum_v2[0];
break;
mapp = &ns_cred_enum_v2[0];
break;
default:
return (-1);
}
}
}
return (-1);
}
char *
{
mapp = &ns_auth_enum_v1[0];
else
mapp = &ns_auth_enum_v2[0];
}
}
return ("Unknown AuthType_t type specified");
}
char *
{
mapp = &ns_sec_enum_v1[0];
}
}
}
return ("Unknown TlsType_t type specified");
}
char *
{
mapp = &ns_scope_enum_v1[0];
else
mapp = &ns_scope_enum_v2[0];
}
}
return ("Unknown ScopeType_t type specified");
}
char *
{
}
}
return ("Unknown PrefOnly_t type specified");
}
char *
{
mapp = &ns_ref_enum_v1[0];
else
mapp = &ns_ref_enum_v2[0];
}
}
return ("Unknown SearchRef_t type specified");
}
char *
{
mapp = &ns_shadow_update_enum[0];
}
}
return ("Unknown enableShadowUpdate_t type specified");
}
static char *
{
mapp = &ns_cred_enum_v2[0];
}
}
}
return ("Unknown CredLevel_t type specified");
}
static void
{
int i, j;
char **ppc;
return;
/*
* This routine is not lock protected because
* the config param it may be destroying is not
* necessarily THE config. Mutex protect elsewhere.
*/
case CHARPTR:
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
case ARRAYCP:
case SERVLIST:
}
}
break;
case ARRAYAUTH:
case ARRAYCRED:
}
break;
case INT:
break;
case ATTRMAP:
break;
case OBJMAP:
break;
default:
break;
}
}
static void
{
if (ptr == current_config)
for (i = 0; i <= LAST_VALUE; i++) {
destroy_param(ptr, i);
}
}
}
/*
* Marks the ns_config_t to be deleted and then releases it. (If no other
* caller is using, then __s_api_release_config will destroy it.)
*
* Note that __s_api_destroy_config should only be called if the caller has
* created the ns_config_t with __s_api_create_config (with the exception
* of set_curr_config). The ns_config_t should be private to the caller.
*
* This function should not be called with the current_config except by
* set_curr_config which locks ns_parse_lock to ensure that no thread
* will be waiting on current_config->config_mutex. This ensures that
* no caller with be waiting on cfg->config_mutex while it is being
* destroyed by __s_api_release_config.
*/
void
{
}
}
/*
* Increment the configuration use count by one - assumes ns_parse_lock has
* been obtained.
*/
static ns_config_t *
{
/*
* allow access to per connection management (non-global)
* config so operations on connection being closed can still
* be completed
*/
else
}
return (ret);
}
/*
* set_curr_config_global sets the current global config to the
* specified ns_config_t. Note that this function is similar
* to the project private function __s_api_init_config_global
* except that it does not release the new ns_config_t.
*/
static void
{
(void) mutex_lock(&ns_parse_lock);
}
(void) mutex_unlock(&ns_parse_lock);
}
/*
* set_curr_config sets the current config or the per connection
* management one to the specified ns_config_t. Note that this function
* is similar to the project private function __s_api_init_config
* except that it does not release the new ns_config_t. Also note
* that if there's no per connection management one to set, the
* global current config will be set.
*/
static void
{
int rc;
/* set the per connection management config if possible */
}
return;
}
/* else set the global current config */
}
/*
* Decrements the ns_config_t usage count by one. Delete if delete flag
* is set and no other callers are using.
*/
void
{
} else
}
}
/*
* __s_api_init_config function destroys the previous global configuration
* sets the new global configuration and then releases it
*/
void
{
}
/*
* __s_api_init_config function destroys the previous configuration
* sets the new configuration and then releases it. The configuration
* may be the global one or the per connection management one.
*/
void
{
}
/*
* Create an ns_config_t, set the usage count to one
*/
__s_api_create_config(void)
{
return (NULL);
return (NULL);
}
return (ret);
}
/*
* __s_api_get_default_config_global returns the current global config
*/
{
(void) mutex_lock(&ns_parse_lock);
(void) mutex_unlock(&ns_parse_lock);
return (cfg);
}
/*
* __s_api_get_default_config returns the current global config or the
* per connection management one.
*/
{
int rc;
/* get the per connection management config if available */
return (cfg);
}
/* else get the global current config */
return (__s_api_get_default_config_global());
}
static char *
{
int len;
return (NULL);
/* remove leading spaces */
pstart++;
/* remove trailing spaces */
;
return (NULL);
if (len != 0) {
}
return (ret);
}
/*
* Note that __s_api_crosscheck is assumed to be called with an ns_config_t
* that is properly protected - so that it will not change during the
* duration of the call
*/
/* Size of errstr needs to be MAXERROR */
{
int value, j;
int i, cnt;
return (NS_SUCCESS);
/* check for no server specified */
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
NULL) {
gettext("Configuration Error: "
return (NS_PARSE_ERR);
}
}
gettext("Configuration Error: %s specified "
return (NS_PARSE_ERR);
}
gettext("Configuration Error: %s specified "
return (NS_PARSE_ERR);
}
/* check if search basedn has been specified */
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
if (check_dn) {
/* check for auth value....passwd/bindn if necessary */
switch (value) {
case NS_LDAP_EA_SIMPLE:
case NS_LDAP_EA_SASL_CRAM_MD5:
case NS_LDAP_EA_TLS_SIMPLE:
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
== NULL) {
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
break;
}
}
}
/*
* Check for shadow update credentials if shadow update is enabled
*/
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
gettext("Configuration Error: No entry for "
"'%s' found"), str);
return (NS_PARSE_ERR);
}
}
/*
* If NS_LDAP_CACHETTL is not specified,
* init NS_LDAP_EXP_P here. Otherwise,
* ldap_cachemgr will never refresh the profile.
* Set it to current time + default
* NS_LDAP_CACHETTL
*/
if (tm != 0) {
}
}
/*
* If credential level self is defined, there should be
*/
self = 0;
for (i = 0; i < cnt; i++) {
self++;
}
gssapi = 0;
for (i = 0; i < cnt; i++) {
gssapi++;
}
gettext("Configuration Error: "
"Credential level self requires "
return (NS_PARSE_ERR);
}
gettext("Configuration Error: "
"requires credential level self"));
return (NS_PARSE_ERR);
}
return (NS_SUCCESS);
}
int
{
int i;
return (0);
}
}
return (-1);
}
/*
* Externally defined version of get_type.
* Includes extra error checking
*/
int
{
return (-1);
}
int
{
int i;
return (-1);
return (0);
}
}
}
return (-1);
}
int
{
int i;
continue;
return (0);
}
}
return (-1);
}
int
{
int i;
return (defconfig[i].config_type);
}
}
return (-1);
}
const char *
{
int i;
return (NULL);
else
}
}
return (NULL);
}
static ns_default_config *
{
int i;
return (&defconfig[i]);
}
}
return (NULL);
}
static int
{
int ret;
if (__s_api_get_type(name, &i) < 0) {
"Illegal type name (%s).\n"), name);
NULL);
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) {
destroy_param(configptr, i);
}
}
return (ret);
}
/*
* Initialize config to a default state
* By default leave configuration empty
* getParam will automatically get the
* appropriate default value if none exists
*/
void
{
ptr = __s_api_create_config();
return;
}
/*
* Get the current configuration pointer and return it.
* If necessary initialize or refresh the current
* configuration as applicable. If global is set, returns
* the global one.
*/
static ns_config_t *
{
/* We want to refresh only one configuration at a time */
(void) mutex_lock(&ns_loadrefresh_lock);
else
/* (re)initialize configuration if necessary */
else
}
(void) __ns_ldap_freeError(&errorp);
}
(void) mutex_unlock(&ns_loadrefresh_lock);
return (cfg);
}
/*
* Get the current global configuration pointer and return it.
* If necessary initialize or refresh the current
* configuration as applicable.
*/
{
return (loadrefresh_config(B_TRUE));
}
/*
* Get the current configuration pointer and return it.
* If necessary initialize or refresh the current
* configuration as applicable. The configuration may
* be the global one or the per connection management one.
*/
{
return (loadrefresh_config(B_FALSE));
}
/*
* In general this routine is not very usefull. Individual routines can be
* created to do this job. Once that is done, this function can be removed.
* Size of errstr buffer needs to be MAXERROR.
*/
static ns_parse_status
{
int found = 0, j;
char *rest;
return (NS_PARSE_ERR);
}
/* eat up beginning quote, if any */
value++;
else
*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_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_BIND_TIME_P:
case NS_LDAP_ATTRIBUTEMAP_P:
case NS_LDAP_OBJECTCLASSMAP_P:
case NS_LDAP_HOST_CERTPATH_P:
break;
case NS_LDAP_SEARCH_DN_P:
/* depreciated because of service descriptors */
/* Parse as appropriate at descriptor create time */
break;
case NS_LDAP_FILE_VERSION_P:
gettext("Version mismatch, expected "
"cache version '%s' or '%s' but "
"encountered version '%s'."),
return (NS_PARSE_ERR);
}
break;
case NS_LDAP_SERVERS_P:
case NS_LDAP_SERVER_PREF_P:
gettext("Invalid parameter values "
"'%s' specified for keyword '%s'."),
return (NS_PARSE_ERR);
}
}
break;
default:
found = 0; j = 0;
value) == 0) {
found = 1;
break;
}
j++;
}
if (!found) {
gettext("Invalid option specified for "
"'%s' keyword. '%s' is not a recognized "
return (NS_PARSE_ERR);
}
}
return (NS_SUCCESS);
}
void
{
char *ptr;
/* split into name value pair */
*ptr = '\0';
ptr++;
/* trim whitespace */
ptr++;
}
}
/*
* Set a parameter value in a generic configuration structure
* Assume any necessary locks are in place. This routine would
* be better named: __ns_ldap_translateString2Param
*
* This routine translates external string format into internal
* param format and saves the result in the param table.
*/
int
{
int i, j, len;
char **attr;
char **p;
/* Find ParamIndexType default configuration data */
gettext("Unable to set value: "
"invalid ParamIndexType (%d)"), type);
NULL);
return (NS_LDAP_CONFIG);
}
/* data is actually const char */
/* eat up beginning quote, if any */
cp++;
;
/* data is const, must duplicate */
return (NS_LDAP_MEMORY);
}
*cp2 = '\0';
}
/* Parse data according to type */
case INT:
case NS_LDAP_PREF_ONLY_P:
case NS_LDAP_SEARCH_REF_P:
case NS_LDAP_SEARCH_SCOPE_P:
if (i < 0) {
gettext("Unable to set value: "
return (NS_LDAP_CONFIG);
}
break;
case NS_LDAP_TRANSPORT_SEC_P: /* ignore TRANSPORT_SEC */
break;
default:
cp2++;
continue;
gettext("Unable to set value: "
return (NS_LDAP_CONFIG);
}
break;
}
break;
case TIMET:
/* Do nothing with a TIMET. Initialize it below */
break;
case CHARPTR:
return (NS_LDAP_MEMORY);
}
break;
case SAMLIST:
/* first check to see if colon (:) is there */
gettext("Unable to set value: "
"invalid serviceAuthenticationMethod (%s)"),
cp);
return (NS_LDAP_CONFIG);
}
/* Appends an entry to the existing list */
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
} else {
int fnd = 0;
/* Attempt to replace if possible */
return (NS_LDAP_MEMORY);
}
fnd = 0;
COLONTOK);
continue;
if (i != len)
continue;
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
if (fnd)
break; /* Replaced completed */
/* Append */
if (len > 1) {
if (p == NULL) {
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
}
break;
case SCLLIST:
/* first check to see if colon (:) is there */
gettext("Unable to set value: "
"invalid serviceCredentialLevel (%s)"),
cp);
return (NS_LDAP_CONFIG);
}
/* Appends an entry to the existing list */
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
} else {
int fnd = 0;
/* Attempt to replace if possible */
return (NS_LDAP_MEMORY);
}
fnd = 0;
COLONTOK);
continue;
if (i != len)
continue;
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
if (fnd)
break; /* Replaced completed */
/* Append */
if (len > 1) {
if (p == NULL) {
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
}
break;
case SSDLIST:
/*
* first check to see if colon (:) is there,
* if so, make sure the serviceId is specified,
* i.e., colon is not the first character
*/
gettext("Unable to set value: "
"invalid serviceSearchDescriptor (%s)"),
cp);
return (NS_LDAP_CONFIG);
}
/* Appends an entry to the existing list */
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
} else {
int fnd = 0;
/* Attempt to replace if possible */
return (NS_LDAP_MEMORY);
}
fnd = 0;
COLONTOK);
continue;
if (i != len)
continue;
return (NS_LDAP_MEMORY);
}
fnd = 1;
break;
}
}
if (fnd)
break; /* Replaced completed */
/* Append */
if (len > 1) {
if (p == NULL) {
return (NS_LDAP_MEMORY);
}
} else
p = NULL;
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
}
break;
case ARRAYCP:
len = 0;
len++;
}
len++;
if (len == 0) {
break;
}
return (NS_LDAP_MEMORY);
}
i = 0;
return (NS_LDAP_MEMORY);
}
cp++;
i++;
}
}
return (NS_LDAP_MEMORY);
}
break;
case SERVLIST:
len = 0;
len++;
;
}
}
len++;
if (len == 0) {
break;
}
return (NS_LDAP_MEMORY);
}
i = 0;
return (NS_LDAP_MEMORY);
}
cp++;
i++;
}
}
return (NS_LDAP_MEMORY);
}
break;
case ARRAYAUTH:
len = 0;
len++;
}
len++;
if (len == 0) {
break;
}
return (NS_LDAP_MEMORY);
}
i = 0;
if (j > sizeof (tbuf)) {
j = -1;
} else {
}
if (j < 0) {
gettext("Unable to set value: "
"invalid "
"authenticationMethod (%s)"),
ptbuf);
return (NS_LDAP_CONFIG);
}
i++;
}
}
if (j > sizeof (tbuf)) {
j = -1;
} else {
}
if (j < 0) {
gettext("Unable to set value: "
"invalid authenticationMethod (%s)"), ptbuf);
return (NS_LDAP_CONFIG);
}
break;
case ARRAYCRED:
len = 0;
len++;
}
len++;
if (len == 0) {
break;
}
return (NS_LDAP_MEMORY);
}
i = 0;
if (j > sizeof (tbuf)) {
j = -1;
} else {
}
if (j < 0) {
gettext("Unable to set value: "
"invalid credentialLevel (%s)"),
ptbuf);
return (NS_LDAP_CONFIG);
}
i++;
}
}
if (j > sizeof (tbuf)) {
j = -1;
} else {
}
if (j < 0) {
gettext("Unable to set value: "
"invalid credentialLevel (%s)"), ptbuf);
return (NS_LDAP_CONFIG);
}
break;
case ATTRMAP:
case OBJMAP:
if (i != NS_HASH_RC_SUCCESS) {
if (i == NS_HASH_RC_NO_MEMORY) {
} else {
gettext("Unable to set value: "
"invalid schema mapping (%s)"), cp);
}
if (tcp)
return (exitrc);
}
/*
* Add reverse map first.
* There could be more than one.
*/
free_memory = 1;
sizeof (ns_mapping_t));
if (rmap) {
sizeof (char *));
free_memory = 0;
}
}
}
}
if (free_memory == 0) {
i = __s_api_add_map2hash(ptr,
} else {
i = __s_api_add_map2hash(ptr,
}
if (i != NS_HASH_RC_SUCCESS) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
sizeof (errstr),
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
NULL);
break;
case NS_HASH_RC_EXISTED:
sizeof (errstr),
"Unable to set value: "
"schema map "
"already existed for "
"(%s, %s)."),
NULL);
break;
case NS_HASH_RC_NO_MEMORY:
break;
}
free_memory = 1;
}
}
if (free_memory) {
if (tcp)
if (rmap) {
}
}
return (exitrc);
}
}
/*
* For performance gain,
* add a "schema mapping existed" indicator
* for the given service if not already added.
* This dummy map needs not be removed, if
* the next real map add operation fails.
* since the caller, e.g. ldap_cachemgr.
* should exit anyway.
*/
free_memory = 1;
sizeof (ns_mapping_t));
if (map) {
sizeof (char *));
free_memory = 0;
}
}
}
}
if (free_memory == 0) {
/*
* add to reverse map,
* so that "ldapclient list"
* would not show it
*/
i = __s_api_add_map2hash(ptr,
NS_HASH_RAMAP, map);
/*
* ignore "map already existed" error,
* just need one per service.
* Need however to free memory allocated
* for map.
*/
if (i != NS_HASH_RC_SUCCESS &&
i != NS_HASH_RC_EXISTED) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
sizeof (errstr),
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
NULL);
break;
case NS_HASH_RC_NO_MEMORY:
break;
}
free_memory = 1;
} else if (i == NS_HASH_RC_EXISTED) {
}
}
}
if (free_memory) {
if (tcp)
if (map) {
}
}
return (exitrc);
}
/*
* add the real schema map
*/
free_memory = 1;
if (map) {
i = __s_api_add_map2hash(ptr,
NS_HASH_AMAP, map);
} else {
i = __s_api_add_map2hash(ptr,
NS_HASH_OMAP, map);
}
if (i != NS_HASH_RC_SUCCESS) {
switch (i) {
case NS_HASH_RC_CONFIG_ERROR:
sizeof (errstr),
"Unable to set value: "
"no configuration info "
"for schema map "
"update (%s)"), cp);
NULL);
break;
case NS_HASH_RC_EXISTED:
sizeof (errstr),
"Unable to set value: "
"schema map "
"already existed for "
"'%s'."), origA);
NULL);
break;
case NS_HASH_RC_NO_MEMORY:
break;
}
free_memory = 1;
} else
free_memory = 0;
}
if (free_memory) {
if (tcp)
if (map)
return (exitrc);
}
break;
default:
/* This should never happen. */
gettext("Unable to set value: invalid configuration "
NULL);
return (NS_LDAP_CONFIG);
}
/* Individually written verify routines here can replace */
/* verify_value. Verify conf (data) as appropriate here */
return (NS_LDAP_CONFIG);
}
}
/* post evaluate the data */
/*
* if this is for setting a password,
* encrypt the password first.
* NOTE evalue() is smart and will just return
* the value passed if it is already encrypted.
*
* Init NS_LDAP_EXP_P here when CACHETTL is updated
*/
if (type == NS_LDAP_BINDPASSWD_P ||
} else if (type == NS_LDAP_FILE_VERSION_P) {
}
} else if (type == NS_LDAP_CACHETTL_P) {
if (tm != 0) {
}
}
/* Everything checks out move new values into param */
return (NS_LDAP_SUCCESS);
}
/*
* Set a parameter value in the 'config' configuration structure
* Lock as appropriate
*/
int
{
int ret;
/* We want to refresh only one configuration at a time */
(void) mutex_lock(&ns_loadrefresh_lock);
if (cache_server == TRUE) {
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_MEMORY);
}
}
} else {
/*
* This code always return error here on client side,
* this needs to change once libsldap is used by more
* applications that need to set parameters.
*/
gettext("Unable to set parameter from a client in "
"__ns_ldap_setParam()"));
NULL);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
/* (re)initialize configuration if necessary */
if (!__s_api_isStandalone() &&
/* only (re)initialize the global configuration */
gettext("Unable to load configuration '%s' "
"('%s')."), NSCONFIGFILE,
(void) __ns_ldap_freeError(&errorp);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
}
}
(void) mutex_unlock(&ns_loadrefresh_lock);
if (reinit_connmgmt == B_TRUE)
/* translate input and save in the parameter list */
return (ret);
}
/*
* Make a copy of a parameter entry
*/
static void **
{
int count, i;
int *intptr;
case ARRAYAUTH:
case ARRAYCRED:
case SAMLIST:
case SCLLIST:
case SSDLIST:
case SERVLIST:
case ARRAYCP:
if (count == 0)
return (NULL);
break;
case CHARPTR:
case INT:
case TIMET:
count = 1;
}
return (NULL);
case ARRAYAUTH:
for (i = 0; i < count; i++) {
return (NULL);
}
}
break;
case ARRAYCRED:
for (i = 0; i < count; i++) {
return (NULL);
}
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
case SERVLIST:
case ARRAYCP:
for (i = 0; i < count; i++) {
return (NULL);
}
}
break;
case CHARPTR:
return (NULL);
}
return (NULL);
}
break;
case INT:
return (NULL);
}
break;
case TIMET:
return (NULL);
}
break;
}
return (dupdata);
}
int
{
void **tmp;
int i = 0;
return (NS_LDAP_SUCCESS);
return (NS_LDAP_SUCCESS);
}
/*
* Get the internal format for a parameter value. This
* routine makes a copy of an internal param value from
* the currently active parameter list and returns it.
*/
int
{
return (NS_LDAP_INVALID_PARAM);
/* We want to refresh only one configuration at a time */
(void) mutex_lock(&ns_loadrefresh_lock);
/* (re)initialize configuration if necessary */
if (!__s_api_isStandalone() &&
/* only (re)initialize the global configuration */
gettext("Unable to load configuration "
"'%s' ('%s')."),
(void) __ns_ldap_freeError(&errorp);
(void) mutex_unlock(&ns_loadrefresh_lock);
return (NS_LDAP_CONFIG);
}
}
}
(void) mutex_unlock(&ns_loadrefresh_lock);
if (reinit_connmgmt == B_TRUE)
gettext("No configuration information available."));
return (NS_LDAP_CONFIG);
}
if (Param == NS_LDAP_DOMAIN_P) {
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_MEMORY);
}
/* get default */
} else {
}
return (NS_LDAP_SUCCESS);
}
/*
* This routine takes a parameter in internal format and
* translates it into a variety of string formats for various
* named: __ns_ldap_translateParam2String
*/
char *
{
int count, i;
char *retstring;
char *sepstr;
return (NULL);
/* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
return (NULL);
/* Return nothing if the value is the default */
return (NULL);
abuf[0] = '\0';
/* get default */
return (NULL);
switch (fmt) {
case NS_DOOR_FMT:
break;
case NS_FILE_FMT:
break;
case NS_LDIF_FMT:
/* If no LDIF attr exists ignore the entry */
return (NULL);
break;
default:
break;
}
goto strValueError;
case ARRAYAUTH:
for (i = 0; i < count; i++) {
if (i != count-1) {
} else {
}
}
goto strValueError;
}
break;
case ARRAYCRED:
for (i = 0; i < count; i++) {
if (i != count-1) {
}
goto strValueError;
}
break;
case SAMLIST:
case SCLLIST:
case SSDLIST:
for (i = 0; i < count; i++) {
goto strValueError;
if (i == count-1)
continue;
/* Separate items */
switch (fmt) {
case NS_DOOR_FMT:
goto strValueError;
break;
case NS_FILE_FMT:
goto strValueError;
break;
case NS_LDIF_FMT:
COLSPSEP))
goto strValueError;
break;
}
}
break;
case ARRAYCP:
for (i = 0; i < count; i++) {
if (i != count-1) {
}
goto strValueError;
}
break;
case SERVLIST:
for (i = 0; i < count; i++) {
if (i != count-1) {
if (fmt == NS_LDIF_FMT) {
} else {
}
}
goto strValueError;
}
break;
case CHARPTR:
break;
goto strValueError;
break;
case INT:
case NS_LDAP_PREF_ONLY_P:
if (__print2buf(buffer,
goto strValueError;
break;
case NS_LDAP_SEARCH_REF_P:
goto strValueError;
break;
case NS_LDAP_SEARCH_SCOPE_P:
goto strValueError;
break;
goto strValueError;
break;
default:
goto strValueError;
break;
}
break;
case ATTRMAP:
continue;
}
if (!first) {
/* print abuf as "separator" */
if (fmt == NS_DOOR_FMT) {
abuf))
goto strValueError;
} else {
goto strValueError;
}
}
goto strValueError;
/* print *cpp as "separator" */
sepstr = "";
goto strValueError;
}
}
break;
case OBJMAP:
continue;
}
if (!first) {
/* print abuf as "separator" */
if (fmt == NS_DOOR_FMT) {
abuf))
goto strValueError;
} else {
goto strValueError;
}
}
goto strValueError;
/* print *cpp as "separator" */
sepstr = "";
goto strValueError;
}
}
break;
}
return (retstring);
return (NULL);
}
/* shared by __door_getldapconfig() and __door_getadmincred() */
int
int callnumber)
{
typedef union {
} space_t;
int ndata;
int adata;
char *domainname;
return (NS_LDAP_OP_FAILED);
}
return (NS_LDAP_MEMORY);
domainname = NULL;
case NS_CACHE_SUCCESS:
break;
case NS_CACHE_NOTFOUND:
gettext("Door call to "
"ldap_cachemgr failed - error: %d."),
return (NS_LDAP_OP_FAILED);
default:
return (NS_LDAP_OP_FAILED);
}
/* copy info from door call to buffer here */
} else
}
return (retCode);
}
static int
{
}
/*
* SetDoorInfoToUnixCred parses ldapcachemgr configuration information
* for Admin credentials.
*/
int
UnixCred_t **cred)
{
char *strptr;
char *rest;
return (NS_LDAP_INVALID_PARAM);
for (; ; ) {
break;
gettext("SetDoorInfoToUnixCred: "
"Unknown keyword encountered '%s'."), name);
return (NS_LDAP_CONFIG);
}
switch (index) {
case NS_LDAP_ADMIN_BINDDN_P:
break;
break;
default:
gettext("SetDoorInfoToUnixCred: "
"Unknown index encountered '%d'."), index);
return (NS_LDAP_CONFIG);
}
}
return (NS_LDAP_SUCCESS);
}
/*
* SetDoorInfo parses ldapcachemgr configuration information
* and verifies that the profile is version 1 or version 2 based.
* version 2 profiles must have a version number as the first profile
* attribute in the configuration.
*/
static ns_config_t *
{
char *strptr;
char *rest;
int ret;
int errfnd = 0;
return (NULL);
ptr = __s_api_create_config();
return (NULL);
}
/* get config cookie from the header */
for (; ; ) {
break;
/* Use get_versiontype and check for V1 vs V2 prototypes */
"%s (%s)\n",
gettext("Illegal profile entry "
"line in configuration."),
name);
errfnd++;
/* Write verify routines and get rid of verify_value here */
errfnd++;
} else if (!first && i == NS_LDAP_FILE_VERSION_P) {
gettext("Illegal NS_LDAP_FILE_VERSION "
"line in configuration.\n"));
errfnd++;
}
if (errfnd) {
} else {
}
return (NULL);
}
first = 0;
}
NULL);
return (NULL);
}
return (ptr);
}
static ns_config_t *
{
int buflen = 0;
int ret;
if (ret != NS_LDAP_SUCCESS) {
return (NULL);
}
/* No need to reload configuration if config cookie is the same */
return (oldcfg);
}
/* now convert from door format */
return (cfg);
}
/*
* converts the time string into seconds. The time string can be specified
* using one of the following time units:
* #s (# of seconds)
* #m (# of minutes)
* #h (# of hours)
* #d (# of days)
* #w (# of weeks)
* NOTE: you can only specify one the above. No combination of the above
* units is allowed. If no unit specified, it will default to "seconds".
*/
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': /* weeks */
m = 604800;
break;
case 'd': /* days */
m = 86400;
break;
case 'h': /* hours */
m = 3600;
break;
case 'm': /* minutes */
m = 60;
break;
case 's': /* seconds */
m = 1;
break;
/* the default case is set to "second" */
}
if (m != 0)
s[l] = '\0';
else
m = 1;
errno = 0;
return (0);
return (0);
return (t);
}
{
return (NULL);
switch (i) {
case NS_LDAP_EA_NONE:
break;
case NS_LDAP_EA_SIMPLE:
break;
case NS_LDAP_EA_SASL_CRAM_MD5:
break;
break;
break;
break;
case NS_LDAP_EA_SASL_EXTERNAL:
break;
case NS_LDAP_EA_SASL_GSSAPI:
break;
case NS_LDAP_EA_TLS_NONE:
break;
case NS_LDAP_EA_TLS_SIMPLE:
break;
break;
break;
break;
break;
break;
default:
/* should never get here */
return (NULL);
}
return (ap);
}
/*
* Parameter Index Type validation routines
*/
/* Validate a positive integer */
/* Size of errbuf needs to be MAXERROR */
/* ARGSUSED */
static int
{
char *cp;
long tot;
continue;
switch (*cp) {
case 'w': /* weeks */
case 'd': /* days */
case 'h': /* hours */
case 'm': /* minutes */
case 's': /* seconds */
break;
}
default:
return (NS_PARSE_ERR);
}
}
/* Valid form: [0-9][0-9]*[wdhms]* */
if (tot >= 0)
return (NS_SUCCESS);
}
return (NS_PARSE_ERR);
}
/* Validate the Base DN */
/* It can be empty (RootDSE request) or needs to have an '=' */
/* Size of errbuf needs to be MAXERROR */
/* ARGSUSED */
static int
{
i == NS_LDAP_SEARCH_BASEDN_P &&
{
return (NS_SUCCESS);
}
gettext("Non-existent or invalid DN in %s"),
return (NS_PARSE_ERR);
}
/* Validate the serverList */
/* For each server in list, check if valid IP or hostname */
/* Size of errbuf needs to be MAXERROR */
/* ARGSUSED */
static int
{
continue;
}
/* err */
gettext("Invalid server (%s) in %s"),
return (NS_PARSE_ERR);
}
return (NS_SUCCESS);
}
/* Check for a BINDDN */
/* It can not be empty and needs to have an '=' */
/* Size of errbuf needs to be MAXERROR */
/* ARGSUSED */
static int
{
char *dntype;
(i == NS_LDAP_BINDDN_P || i == NS_LDAP_ADMIN_BINDDN_P) &&
return (NS_SUCCESS);
}
if (i == NS_LDAP_BINDDN_P)
dntype = "proxy";
else
dntype = "update";
return (NS_PARSE_ERR);
}
/* Check for a BINDPASSWD */
/* The string can not be NULL or empty */
/* Size of errbuf needs to be MAXERROR */
/* ARGSUSED */
static int
{
char *pwtype;
(i == NS_LDAP_BINDPASSWD_P || i == NS_LDAP_ADMIN_BINDPASSWD_P) &&
return (NS_SUCCESS);
}
if (i == NS_LDAP_BINDPASSWD_P)
pwtype = "proxy";
else
pwtype = "admin";
return (NS_PARSE_ERR);
}
/*
* __s_get_hostcertpath returns either the configured host certificate path
* does not use __ns_ldap_getParam because it may be called during connection
* setup. This can fail due to insufficient memory.
*/
char *
__s_get_hostcertpath(void)
{
}
return (ret);
}
static void
{
if (current_config != NULL)
}