ns_common.c revision c31b4830040ccbc62281ab04a0d8278a6862d5ff
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <netdir.h>
#include <lber.h>
#include <ldap.h>
#include "ns_sldap.h"
#include "ns_internal.h"
#include "ns_cache_door.h"
#define MAXIFS 32
struct ifinfo {
};
static ns_service_map ns_def_map[] = {
{ "shadow", "ou=people,", "passwd" },
{ "user_attr", "ou=people,", "passwd" },
{ "audit_user", "ou=people,", "passwd" },
{ "netmasks", "ou=networks,", "networks" },
{ "ipnodes", "ou=Hosts,", "hosts" },
{ "bootparams", "ou=ethers,", "ethers" },
{ "exec_attr", "ou=SolarisProfAttr,", "prof_attr" },
{ "tnrhdb", "ou=ipTnet,", "tnrhtp" },
};
static char ** sortServerNet(char **srvlist);
/*
* FUNCTION: s_api_printResult
* Given a ns_ldap_result structure print it.
*/
int
{
int i, j, k = 0;
#ifdef DEBUG
#endif
(void) printf("--------------------------------------\n");
(void) printf("No result\n");
return (0);
}
for (i = 0; i < result->entries_count; i++) {
(void) printf("entry %d has attr_count = %d \n", i,
for (j = 0; j < curEntry->attr_count; j++) {
(void) printf("entry %d has attr_pair[%d] = %s \n",
for (k = 0; k < 20 &&
(void) printf("entry %d has attr_pair[%d]->"
"attrvalue[%d] = %s \n", i, j, k,
}
(void) printf("\n--------------------------------------\n");
}
return (1);
}
/*
* FUNCTION: __s_api_getSearchScope
*
* Retrieve the search scope for ldap search from the config module.
*
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_CONFIG
* INPUT: NONE
* OUTPUT: searchScope, errorp
*/
int
int *searchScope,
{
int rc = 0;
int scope = 0;
#ifdef DEBUG
#endif
if (*searchScope == 0) {
return (rc);
}
else
(void) __ns_ldap_freeParam(¶mVal);
} else {
scope = *searchScope;
}
switch (scope) {
case NS_LDAP_SCOPE_ONELEVEL:
break;
case NS_LDAP_SCOPE_BASE:
break;
case NS_LDAP_SCOPE_SUBTREE:
break;
default:
gettext("Invalid search scope!"));
return (NS_LDAP_CONFIG);
}
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: __ns_ldap_dupAuth
*
* Duplicates an authentication structure.
*
* RETURN VALUES: copy of authp or NULL on error
* INPUT: authp
*/
{
#ifdef DEBUG
#endif
return (NULL);
return (NULL);
if (authp->hostcertpath) {
return (NULL);
}
}
(void) __ns_ldap_freeCred(&ap);
return (NULL);
}
}
(void) __ns_ldap_freeCred(&ap);
return (NULL);
}
}
(void) __ns_ldap_freeCred(&ap);
return (NULL);
}
}
return (ap);
}
/*
* FUNCTION: __ns_ldap_freeCred
*
* Frees all the memory associated with a ns_cred_t structure.
*
* RETURN VALUES: NS_LDAP_INVALID_PARAM, NS_LDAP_SUCCESS, NS_LDAP_CONFIG
* INPUT: ns_cred_t
*/
int
{
#ifdef DEBUG
#endif
return (NS_LDAP_INVALID_PARAM);
if (ap->hostcertpath) {
}
}
}
}
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: __s_api_is_auth_matched
*
* Compare an authentication structure.
*
* RETURN VALUES: B_TRUE if matched, B_FALSE otherwise.
* INPUT: auth1, auth2
*/
{
return (B_FALSE);
return (B_FALSE);
return (B_TRUE);
}
/*
* FUNCTION: __s_api_getDNs
*
* Retrieves the default base dn for the given
* service.
*
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_MEMORY, NS_LDAP_CONFIG
* INPUT: service
* OUTPUT: DN, error
*/
typedef int (*pf)(const char *, char **, ns_ldap_error_t **);
int
char *** DN,
const char *service,
ns_ldap_error_t ** error)
{
int rc = 0;
int i, len;
#ifdef DEBUG
#endif
return (rc);
}
if (!paramVal) {
gettext("BaseDN not defined"));
return (NS_LDAP_CONFIG);
}
(void) __ns_ldap_freeParam(¶mVal);
return (NS_LDAP_MEMORY);
}
(void) __ns_ldap_freeParam(¶mVal);
return (NS_LDAP_MEMORY);
}
} else {
if (strcasecmp(service,
ns_def_map[i].service) == 0) {
dns[0] = (char *)
(void) __ns_ldap_freeParam(
¶mVal);
return (NS_LDAP_MEMORY);
}
ns_def_map[i].rdn);
(char *)*paramVal);
break;
}
}
char *p = (char *)*paramVal;
int buflen = 0;
/* automount entries */
if (!buffer) {
(void) __ns_ldap_freeParam(
¶mVal);
return (NS_LDAP_MEMORY);
}
/* shorten name to avoid cstyle error */
if (rc != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeParam(
¶mVal);
return (rc);
}
} else {
/* strlen("nisMapName")+"="+","+'\0' = 13 */
13;
(void) __ns_ldap_freeParam(
¶mVal);
return (NS_LDAP_MEMORY);
}
"nisMapName=%s,%s", service, p);
}
} else {
(void) __ns_ldap_freeParam(¶mVal);
return (NS_LDAP_MEMORY);
}
"%s,%s", service, p);
}
}
}
(void) __ns_ldap_freeParam(¶mVal);
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: __s_api_get_search_DNs_v1
*
* Retrieves the list of search DNS from the V1 profile for the given
* service.
*
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_MEMORY, NS_LDAP_CONFIG
* INPUT: service
* OUTPUT: DN, error
*/
int
char *** DN,
const char *service,
ns_ldap_error_t ** error)
{
int rc = 0;
return (rc);
}
(const char *)service);
break;
}
}
(void) __ns_ldap_freeParam(¶mVal);
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: parseDN
*
* Parse a special formated list(val) into an array of char *.
*
* RETURN VALUE: A char * pointer to the new list of dns.
* INPUT: val, service
*/
static char **
const char *val,
const char *service)
{
const char *temptr;
char *temptr2;
const char *valend;
int valNo = 0;
int valSize = 0;
int i;
char *SSD_service = NULL;
#ifdef DEBUG
#endif
return (NULL);
return (NULL);
/*
* This routine is only called
* to process V1 profile and
* for V1 profile, map service
* to the corresponding SSD_service
* which is associated with a
* real container in the LDAP directory
* tree, e.g., map "shadow" to
* "password". See function
* __s_api_get_SSD_from_SSDtoUse_service
* for similar service to SSD_service
* mapping handling for V2 profile.
*/
if (ns_def_map[i].SSDtoUse_service &&
ns_def_map[i].service) == 0) {
break;
}
}
if (SSD_service == NULL)
return (NULL);
return (NULL);
}
temptr++;
return (NULL);
while (*temptr) {
break;
temptr2++;
break;
valNo++;
}
return (NULL);
return (NULL);
}
temptr++;
return (NULL);
}
return (NULL);
}
}
return (retVal);
}
/*
* __s_api_get_local_interfaces
*
* Returns a pointer to an array of addresses and netmasks of all interfaces
* configured on the system.
*
* NOTE: This function is very IPv4 centric.
*/
static struct ifinfo *
{
struct sockaddr_in *sin;
int fd = 0;
int numifs = 0;
int i, n = 0;
}
}
}
sizeof (struct ifinfo));
}
continue;
continue;
continue;
continue;
i++;
}
return (localinfo);
}
/*
* __s_api_samenet(char *, struct ifinfo *)
*
* Returns 1 if address is on the same subnet of the array of addresses
* passed in.
*
* NOTE: This function is only valid for IPv4 addresses.
*/
static int
{
int answer = 0;
char *addr_raw;
unsigned long iaddr;
int i;
char *s;
/* Remove port number. */
*s = '\0';
/* Loop through interface list to find match. */
answer++;
}
}
}
return (answer);
}
/*
* FUNCTION: __s_api_getServers
*
* Retrieve a list of ldap servers from the config module.
*
* RETURN VALUE: NS_LDAP_SUCCESS, NS_LDAP_CONFIG, NS_LDAP_MEMORY
* INPUT: NONE
* OUTPUT: servers, error
*/
int
char *** servers,
ns_ldap_error_t ** error)
{
char **sortServers = NULL;
char **netservers = NULL;
#ifdef DEBUG
#endif
/* get profile version number */
return (rc);
gettext("No file version"));
return (NS_LDAP_CONFIG);
}
version = 1;
version = 2;
(void) __ns_ldap_freeParam(¶mVal);
return (rc);
/*
* For version 2, default server list could be
* empty.
*/
version == 1) {
return (NS_LDAP_CONFIG);
}
/*
* Get server address(es) and go through them.
*/
/* Sort servers based on network. */
if (*servers) {
if (netservers) {
*servers = netservers;
} else {
return (NS_LDAP_MEMORY);
}
}
/* Get preferred server list and sort servers based on that. */
if (*servers)
return (rc);
}
char **prefServers;
if (*servers)
(void) __ns_ldap_freeParam(¶mVal);
return (rc);
}
prefServers = (char **)paramVal;
if (prefServers) {
*(int *)val[0] == 1)
&err);
else
&err);
if (sortServers) {
if (*servers)
prefServers = NULL;
*servers = sortServers;
} else {
if (*servers)
prefServers = NULL;
}
}
(void) __ns_ldap_freeParam(&val);
}
(void) __ns_ldap_freeParam(¶mVal);
if (err == NS_LDAP_CONFIG) {
gettext("Unable to generate a new server list "
return (err);
}
return (NS_LDAP_MEMORY);
}
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: sortServerNet
* Sort the serverlist based on the distance from client as long
* as the list only contains IPv4 addresses. Otherwise do nothing.
*/
static char **
sortServerNet(char **srvlist)
{
int count = 0;
int all = 0;
int ipv4only = 1;
char **tsrvs;
/* Sanity check. */
return (NULL);
/* Count the number of servers to sort. */
ipv4only = 0;
}
count++;
/* Make room for the returned list of servers. */
return (NULL);
}
/* Make a temporary list of servers. */
return (NULL);
}
/* Filter servers on the same subnet */
while (*tsrvs) {
}
tsrvs++;
}
/* Filter remaining servers. */
while (*tsrvs) {
while (*ttsrvs) {
break;
ttsrvs++;
}
tsrvs++;
}
return (retsrvs);
}
/*
* FUNCTION: sortServerPref
* Sort the serverlist based on the preferred server list.
*
* The sorting algorithm works as follows:
*
* If version 1, if flag is TRUE, find all the servers in both preflist
* and srvlist, then append other servers in srvlist to this list
* and return the list.
* If flag is FALSE, just return srvlist.
* srvlist can not be empty.
*
* If version 2, append all the servers in srvlist
* but not in preflist to preflist, and return the merged list.
* If srvlist is empty, just return preflist.
* If preflist is empty, just return srvlist.
*/
static char **
{
char **tsrvs;
char **retsrvs;
char **dupsrvs;
/* Count the number of servers to sort. */
scount++;
/* Sanity check. */
*error = NS_LDAP_CONFIG;
return (NULL);
}
/* Count the number of preferred servers */
pcount++;
/* Sanity check. */
*error = NS_LDAP_CONFIG;
return (NULL);
}
/* Make room for the returned list of servers */
*error = NS_LDAP_MEMORY;
return (NULL);
}
/*
* if the preferred server list is empty,
* just return a copy of the server list
*/
if (pcount == 0) {
while (*tsrvs)
return (retsrvs);
}
all = 0;
/*
* if the server list is empty,
* just return a copy of the preferred server list
*/
if (scount == 0) {
while (*tsrvs)
return (retsrvs);
}
all = 0;
/* Make room for the servers whose memory needs to be freed */
*error = NS_LDAP_MEMORY;
return (NULL);
}
/*
* If version 1,
* throw out preferred servers not on server list.
* If version 2, make a copy of the preferred server list.
*/
if (version == 1) {
while (*tsrvs) {
while (*ttsrvs) {
break;
ttsrvs++;
}
else
tsrvs++;
}
} else {
while (*tsrvs)
}
/*
* If version 1,
* if PREF_ONLY is false, we append the non-preferred servers
* to bottom of list.
* For version 2, always append.
*/
while (*tsrvs) {
while (*ttsrvs) {
break;
}
ttsrvs++;
}
else
tsrvs++;
}
}
/* free memory for duplicate servers */
if (dup) {
}
return (retsrvs);
}
/*
* FUNCTION: __s_api_removeBadServers
* Contacts the ldap cache manager for marking the
* problem servers as down, so that the server is
* not contacted until the TTL expires.
*/
void
__s_api_removeBadServers(char ** Servers)
{
char **host;
return;
if (__s_api_removeServer(*host) < 0) {
/*
* Couldn't remove server from
* server list. Log a warning.
*/
"not remove %s from servers list", *host);
}
}
}
/*
* FUNCTION: __s_api_free2dArray
*/
void
__s_api_free2dArray(char ** inarray)
{
char **temptr;
return;
}
}
/*
* FUNCTION: __s_api_cp2dArray
*/
char **
__s_api_cp2dArray(char **inarray)
{
char **newarray;
int count;
return (NULL);
;
return (NULL);
return (NULL);
}
}
return (newarray);
}
/*
* FUNCTION: __s_api_isCtrlSupported
* Determines if the passed control is supported by the LDAP sever.
* RETURNS: NS_LDAP_SUCCESS if yes, NS_LDAP_OP_FAIL if not.
*/
int
{
char **ctrl;
int len;
return (NS_LDAP_SUCCESS);
}
return (NS_LDAP_OP_FAILED);
}
/*
* FUNCTION: __s_api_toFollowReferrals
* Determines if need to follow referral for an SLDAP API.
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_INVALID_PARAM, or
* other rc from __ns_ldap_getParam()
* INPUT: flags
* OUTPUT: toFollow, errorp
*/
int
__s_api_toFollowReferrals(const int flags,
int *toFollow,
{
int rc = 0;
int iflags = 0;
#ifdef DEBUG
#endif
/* Either NS_LDAP_NOREF or NS_LDAP_FOLLOWREF not both */
(NS_LDAP_NOREF | NS_LDAP_FOLLOWREF)) {
return (NS_LDAP_INVALID_PARAM);
}
/*
* if the NS_LDAP_NOREF or NS_LDAP_FOLLOWREF is set
* this will take precendence over the values specified
* in the configuration file
*/
} else {
if (rc != NS_LDAP_SUCCESS)
return (rc);
(void) __ns_ldap_freeParam(¶mVal);
if (*errorp)
(void) __ns_ldap_freeError(errorp);
return (NS_LDAP_SUCCESS);
}
(void) __ns_ldap_freeParam(¶mVal);
}
if (iflags & NS_LDAP_NOREF)
else
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: __s_api_addRefInfo
* Insert a referral info into a referral info list.
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_MEMORY, NS_LDAP_OP_FAILED
* INPUT: LDAP URL, pointer to the referral info list,
* search baseDN, search scope, search filter,
* previous connection
*/
int
{
int hostlen;
char *ld_defhost = NULL;
#ifdef DEBUG
#endif
/* sanity check */
return (NS_LDAP_OP_FAILED);
/*
* log error and return NS_LDAP_SUCCESS
* if one of the following:
* 1. non-LDAP URL
* 2. LDAP URL which can not be parsed
*/
if (!ldap_is_ldap_url(url) ||
gettext("Invalid or non-LDAP URL when"
" processing referrals URL"),
url);
if (ludp)
return (NS_LDAP_SUCCESS);
}
sizeof (ns_referral_info_t));
return (NS_LDAP_MEMORY);
}
/*
* we do have a valid URL and we were able to parse it
* however, we still need to find out what hostport to
* use if none were provided in the LDAP URL
* (e.g., ldap:///...)
*/
gettext("no LDAP handle when"
" processing referrals URL"),
url);
return (NS_LDAP_SUCCESS);
} else {
&ld_defhost);
if (ld_defhost == NULL) {
gettext("not able to retrieve default "
"host when processing "
"referrals URL"),
url);
return (NS_LDAP_SUCCESS);
} else {
return (NS_LDAP_MEMORY);
}
}
}
} else {
/*
* add 4 here:
* 1 for the last '\0'.
* 1 for host and prot separator ":"
* and "[" & "]" for possible ipV6 addressing
*/
sizeof (MAXPORTNUMBER_STR) + 4;
return (NS_LDAP_MEMORY);
}
/*
* serverAddr = host:port
* or
* if host is an IPV6 address
* [host]:port
*/
"[%s]:%d",
} else {
"%s:%d",
}
} else {
/* serverAddr = host */
}
}
return (NS_LDAP_MEMORY);
}
} else {
if (baseDN) {
return (NS_LDAP_MEMORY);
}
}
}
if (filter)
else if (ludp->lud_filter)
else
return (NS_LDAP_MEMORY);
}
if (scope)
/* insert the referral info */
if (*head) {
;
} else
return (NS_LDAP_SUCCESS);
}
/*
* FUNCTION: __s_api_deleteRefInfo
* Delete a referral info list.
* INPUT: pointer to the referral info list
*/
void
{
#ifdef DEBUG
#endif
}
}
/*
* FUNCTION: __s_api_get_SSD_from_SSDtoUse_service
*
* Retrieves the Service Search Descriptors which should be used for
* the given service. For example, return all the "passwd" SSDs for
* service "shadow" if no SSD is defined for service "shadow" and
* no filter component is defined in all the "passwd" SSDs. This idea
* of sharing the SSDs defined for some other service is to reduce the
* configuration complexity. For a service, which does not have its own
* entries in the LDAP directory, SSD for it is useless, and should not
* be set. But since this service must share the container with at least
* one other service which does have it own entries, the SSD for
* this other service will be shared by this service.
* This other service is called the SSD-to-use service.
* The static data structure, ns_def_map[], in this file
* defines the SSD-to-use service for all the services supported.
*
* RETURN VALUES: NS_LDAP_SUCCESS, NS_LDAP_MEMORY, NS_LDAP_INVALID_PARAM
* INPUT: service
* OUTPUT: *SSDlist, *errorp if error
*/
int
__s_api_get_SSD_from_SSDtoUse_service(const char *service,
{
int i, rc;
int filter_found = FALSE;
char *SSD_service = NULL;
int auto_service = FALSE;
#ifdef DEBUG
"__s_api_get_SSD_from_SSDtoUse_service START\n");
#endif
return (NS_LDAP_INVALID_PARAM);
return (NS_LDAP_SUCCESS);
auto_service = TRUE;
/*
* First try to return the configured SSDs for the input server
*/
if (rc != NS_LDAP_SUCCESS)
return (rc);
else {
return (NS_LDAP_SUCCESS);
}
/*
* If service == auto_* and SSD is not found,
* then try automount to see if there is an SSD
* for automount.
*/
if (auto_service) {
if (rc != NS_LDAP_SUCCESS)
return (rc);
else {
/*
* If SSDlist is found,
* prepend automountMapName to the basedn
* in the SSDlist
*
*/
errorp);
if (rc != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeSearchDescriptors(
SSDlist);
}
return (rc);
}
}
}
/*
* Find the SSDtoUse service.
* If none found, flag "found" remains FALSE.
*/
if (ns_def_map[i].SSDtoUse_service &&
ns_def_map[i].service) == 0) {
break;
}
}
if (!found)
return (NS_LDAP_SUCCESS);
/*
* return the SSDs for SSD_service only if no optional filter
* component is defined in the SSDs
*/
if (rc != NS_LDAP_SUCCESS) {
return (rc);
} else {
return (NS_LDAP_SUCCESS);
/* check to see if filter defined in SSD */
filter_found = TRUE;
break;
}
}
if (filter_found) {
(void) __ns_ldap_freeSearchDescriptors(SSDlist);
gettext("Service search descriptor for "
"service '%s' contains filter, "
"which can not be used for "
"service '%s'."),
return (NS_LDAP_CONFIG);
}
}
return (NS_LDAP_SUCCESS);
}
/*
* verify addr is an IPv4 address with the optional [:portno]
* RFC2373 & RFC2732 & RFC2396
*/
int
__s_api_isipv4(char *addr)
{
if (!addr)
return (0);
digit++;
continue;
}
if (addr[i] == '.') {
return (0);
digit = 0;
seg++;
continue;
}
if (addr[i] == ':') {
if (digit > 3)
return (0);
port++;
digit = 0;
seg++;
continue;
}
return (0);
}
return (1);
return (0);
}
/*
* verify addr is an IPv6 address with the optional [IPv6]:portno
* RFC2373 & RFC2732 & RFC2396
*/
int
__s_api_isipv6(char *addr)
{
if (!addr)
return (0);
s = addr;
if (addr[0] == '[') {
if (!laddr)
return (0);
/* only 1 ']' should be in an addr */
goto bad;
switch (c1[1]) {
case ':':
port++;
goto bad;
digit++;
}
if (!digit)
goto bad;
c1[0] = '\0';
break;
case '\0':
c1[0] = '\0';
break;
default:
goto bad;
}
s = &laddr[1];
}
for (i = 0; i < strlen(s); i++) {
if (isxdigit(s[i])) {
if (digit == 0)
dc = i;
digit++;
col = 0;
continue;
}
if (s[i] == ':') {
tc++;
goto bad;
digit = 0;
col++;
continue;
}
if (s[i] == '.') {
goto good;
else
goto bad;
}
goto bad;
}
good:
return (1);
bad:
return (0);
}
/*
* verify addr is a valid hostname with the optional [:portno]
* RFC2373 & RFC2732 & RFC2396
*/
int
__s_api_ishost(char *addr)
{
if (!addr)
return (0);
/* must start with alpha character */
return (0);
alpha++;
continue;
}
digit++;
continue;
}
if (addr[i] == '.') {
return (0);
seg++;
continue;
}
if (addr[i] == ':') {
return (0);
port++;
seg++;
continue;
}
return (0);
}
return (1);
return (0);
}
/*
* Prepend automountMapName=auto_xxx to the basedn
* in the SSDlist
*/
const char *service,
{
int i, rc;
return (NS_LDAP_INVALID_PARAM);
if (rc != NS_LDAP_SUCCESS)
return (rc);
}
return (NS_LDAP_SUCCESS);
}
/*
* Prepend automountMapName=auto_xxx to the DN
* Construct a string of
* "automountMapName=auto_xxx,dn"
*
* If automountMapName is mapped to some other attribute,
* then use the mapping in the setup.
*
* If a version 1 profile is in use, use nisMapName for
* backward compatibility (i.e. "nisMapName=auto_xxx,dn").
*/
int
const char *service,
char **dn,
{
char *default_automountmapname = "automountMapName";
char *automountmapname = NULL;
char **mappedattrs = NULL;
return (NS_LDAP_INVALID_PARAM);
if (paramVal)
(void) __ns_ldap_freeParam(¶mVal);
return (rc);
}
(void) __ns_ldap_freeParam(¶mVal);
if (automountmapname == NULL) {
return (NS_LDAP_MEMORY);
}
} else {
(void) __ns_ldap_freeParam(¶mVal);
/* Find mapped attribute name of auto_xxx first */
/*
* if mapped attribute name of auto_xxx is not found,
* find the mapped attribute name of automount
*/
if (mappedattrs == NULL)
"automount", default_automountmapname);
/*
* if mapped attr is not found, use the default automountmapname
*/
if (mappedattrs == NULL) {
if (automountmapname == NULL)
return (NS_LDAP_MEMORY);
} else {
if (mappedattrs[0] != NULL) {
/*
* Copy it from the mapped attr list
* Assume it's 1 to 1 mapping
* 1 to n does not make sense
*/
if (automountmapname == NULL) {
return (NS_LDAP_MEMORY);
}
} else {
/*
* automountmapname is mapped to an empty string
*/
"Attribute automountMapName is "
"mapped to an empty string.\n"));
return (NS_LDAP_CONFIG);
}
}
}
/* automountMapName + "=" + service + "," + dn + '\0' */
return (NS_LDAP_MEMORY);
}
/* free the original dn */
return (NS_LDAP_SUCCESS);
}
/*
* Map the LDAP error code and error message from LDAP server
* to a password status used for password aging/management.
*/
{
if (errmsg) {
if (errnum ==
/*
* case 1 (Bind):
* password expired
*/
return (NS_PASSWD_EXPIRED);
}
if (errnum ==
/*
* case 1.1 (Bind):
* password expired
*/
return (NS_PASSWD_EXPIRED);
/*
* case 2 (Bind):
* Account inactivated
*/
return (NS_PASSWD_EXPIRED);
/*
* case 3 (Modify passwd):
* the user is not allow to change
* password; only admin can change it
*/
return (NS_PASSWD_CHANGE_NOT_ALLOWED);
}
if (errnum ==
/*
* case 4 (Bind):
* the user account is locked due to
* too many login failures.
*/
return (NS_PASSWD_RETRY_EXCEEDED);
/*
* case 5 (Modify passwd):
* syntax error: the new password
* has length less than defined
* minimum
* Not true anymore with strong password
* policies on LDAP server: errmsg that
* contain NS_PWDERR_INVALID_SYNTAX may
* have different meanings.
* To keep compatibility with older password
* policy, check if errmsg is strictly equal
* to NS_PWDERR_INVALID_SYNTAX and if yes only,
* return NS_PASSWD_TOO_SHORT.
*/
NS_PWDERR_INVALID_SYNTAX) == 0)
return (NS_PASSWD_TOO_SHORT);
return (NS_PASSWD_INVALID_SYNTAX);
/*
* case 6 (Modify passwd):
* trivial password: same value as
* that of attribute cn, sn, or uid ...
*/
return (NS_PASSWD_INVALID_SYNTAX);
/*
* case 7 (Modify passwd):
* re-use one of the old passwords
* in history list
*/
return (NS_PASSWD_IN_HISTORY);
/*
* case 8 (Modify passwd):
* password not allowed to be
* changed yet; within minimum
* age
*/
return (NS_PASSWD_WITHIN_MIN_AGE);
}
}
return (NS_PASSWD_GOOD);
}
/*
* Determine if the input OID list contains
* one of the password control OIDs, which are:
* LDAP_CONTROL_PWEXPIRED: 2.16.840.1.113730.3.4.4
* LDAP_CONTROL_PWEXPIRING: 2.16.840.1.113730.3.4.5.
* If yes, return 1, if no, 0.
*/
int
{
char **oid;
return (0);
return (1);
}
}
return (0);
}
/*
* Determine if the input OID list contains LDAP V3 password less
* account management control OID, which is:
* NS_LDAP_ACCOUNT_USABLE_CONTROL:1.3.6.1.4.1.42.2.27.9.5.8
* If yes, return 1, if no, 0.
*/
int
{
char **oid;
return (0);
return (1);
}
}
return (0);
}
/*
* For some databases in name switch, the name and aliases are saved
* as "cn". When the "cn" valuse are retrieved, there is no distinction
* which is the name and which is(are) aliase(s).
* This function is to parse RDN and find the value of the "cn" and
* then find the matching value in "cn" attribute.
* Also see RFC 2307 section 5.6.
*
* Input -
* entry: An LDAP entry
* attrptr: A attribute which value appears in RDN
* This should be "cn" for the name switch for now.
* case_ignore: 0 Case sensitive comparison on the attribute value
* 1 Case insensitive comparison
*
* Return -
* The value of an attrbute which is used as canonical name
* This is read only and the caller should not try to free it.
* If it's a NULL, it could be either an RDN parsing error
* or RDN value does not match any existing "cn" values.
* e.g.
* dn: cn=xx+ipserviceprotocol=udp,......
* cn: aa
* cn: bb
*
* Note:
* format, this function makes no such assumption. If the DN
* is saved as "dn: yy=...+sn=my_canocical_name, ..", then it can still work.
* The comments use "cn" as an example only.
*
*/
typedef int (*cmpfunc)(const char *, const char *);
char *
int case_ignore) {
uint_t i;
char *rdn_attr_value = NULL;
return (NULL);
/* "values" is read-only */
return (NULL);
return (NULL);
return (NULL);
}
/* Assume the rdn is normalized */
/* parse attribute name and value, get attribute name first */
goto cleanup;
}
/* get value */
break;
}
}
if (rdn_attr_value) {
if (case_ignore)
cmp = strcasecmp;
else
/*
* After parsing RDN and find the matching attribute in RDN,
* match rdn value with values in "cn".
*/
for (i = 0; i < attrptr->value_count; i++) {
(*cmp)(rdn_attr_value,
/* RDN "cn" value matches the "cn" value */
break;
}
}
}
return (value);
}
/*
* This function requests a server to be removed from
* the cache manager maintained server list. This is
* done via the door functionality.
* Returns 0 if OK, else a negative value.
*/
int
__s_api_removeServer(const char *server)
{
union {
char s_b[DOORBUFFERSIZE];
} space;
ns_server_info_t r, *ret = &r;
const char *ireq;
int ndata;
int adata;
int len;
int rc;
return (-1);
if (__s_api_isStandalone()) {
/*
* Remove 'server' from the standalone server list.
* __s_api_findRootDSE() is the standalone version
* of getldap_get_serverInfo() used in ldap_cachemgr.
* Request NS_CACHE_NORESP indicates 'server' should
* be removed.
*/
if (__s_api_findRootDSE(ireq,
NULL,
&error) != NS_LDAP_SUCCESS) {
"libsldap (\"standalone\" mode): "
" Unable to remove %s - %s",
(void) __ns_ldap_freeError(&error);
}
return (NS_CACHE_NOSERVER);
}
return (0);
}
return (-1);
return (-1);
len)
return (-1);
return (-1);
/* try to remove the server via the door interface */
/* clean up the door call */
}
return (rc);
}
void
}
if (sinfo->serverFQDN) {
}
}
/*
* Create an ns_ldap_error structure, set status to 'rc',
* and copy in the error message 'msg'.
*/
return (NULL);
return (ep);
}
/*
* Make a copy of the input ns_ldap_error.
*/
char *msg;
return (NULL);
} else
}
}
return (ep);
}