/*
* 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
*/
/*
*/
#include "ldap_common.h"
#include <malloc.h>
#include <synch.h>
#include <syslog.h>
#include <thread.h>
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
/* getent attributes filters */
#define _F_GETPROFNAME \
"(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*)))"
"(SolarisAttrKeyValue=*))"
/* getent sort attributes */
static struct gettablefilter {
char *tablename;
char *tablefilter;
char *sortattr;
} gettablefilterent[] = {
{(char *)_NETWORKS, (char *)_F_GETNETENT,
(char *)_A_IPNETWORKNUM},
{(char *)_AUUSER, (char *)_F_GETAUUSERNAME,
(char *)_A_UID},
{(char *)_TNRHTP, (char *)_F_GETTNRHTP,
(char *)_A_IPTNETTMPLNAM},
};
/* Use this attribute to ask for server type from libsldap. */
static const char *_extra_info_attr[] = {
"__ns_ldap_op_attr_server_type",
(char *)NULL
};
{
switch (rc) {
case NS_LDAP_SUCCESS:
return (NSS_SUCCESS);
case NS_LDAP_PARTIAL:
return (NSS_TRYAGAIN);
case NS_LDAP_NOTFOUND:
/*
* If LDAP server is down or unreachable, the error value
* is not null and we fall thru to default case and return
* error code as unavailable, else return NOTFOUND.
*/
return (NSS_NOTFOUND);
case NS_LDAP_INTERNAL:
default:
return (NSS_UNAVAIL);
}
}
/* ARGSUSED */
char **realfilter, const void *userdata),
const void *userdata)
{
int callbackstat = 0;
int rc;
#ifdef DEBUG
#endif /* DEBUG */
}
} else {
}
if (rc != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeError(&error);
return (rc);
}
(void) __ns_ldap_freeError(&error);
/* callback function */
if ((callbackstat =
goto error_out;
}
/*
* publickey does not have a front end marshaller and expects
* a string to be returned in NSS.
* No need to convert file format -> struct.
*
*/
return (NSS_SUCCESS);
}
/*
* Assume the switch engine wants the returned data in the file
* format when argp->buf.result == NULL.
* The front-end marshaller str2ether(ethers) uses
* ent (argp->buf.result) and buffer (argp->buf.buffer)
* for different purpose so ethers has to be treated differently.
*/
/* file format -> struct */
goto error_out;
}
if (callbackstat == NSS_STR_PARSE_SUCCESS) {
} else {
}
}
return ((nss_status_t)NSS_SUCCESS);
}
} else {
/* return file format in argp->buf.buffer */
if (*p == '#')
}
return ((nss_status_t)NSS_SUCCESS);
}
}
}
/* error */
if (callbackstat == NSS_STR_PARSE_PARSE) {
return ((nss_status_t)NSS_NOTFOUND);
}
if (callbackstat == NSS_STR_PARSE_ERANGE) {
return ((nss_status_t)NSS_NOTFOUND);
}
if (callbackstat == NSS_STR_PARSE_NO_ADDR) {
/* No IPV4 address is found */
return ((nss_status_t)NSS_NOTFOUND);
}
return ((nss_status_t)NSS_UNAVAIL);
}
/*
* This function is similar to _nss_ldap_lookup except it does not
* do a callback. It is only used by getnetgrent.c
*/
/* ARGSUSED */
char **realfilter, const void *userdata),
const void *userdata)
{
int rc;
#ifdef DEBUG
#endif /* DEBUG */
userdata)) != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeError(&error);
return (rc);
}
return ((nss_status_t)NSS_SUCCESS);
}
/*
*
*/
void
{
#ifdef DEBUG
#endif /* DEBUG */
}
}
}
}
/*
* _nss_ldap_destr will free all smalloc'ed variable strings and structures
* before exiting this nsswitch shared backend library. This function is
* called before returning control back to nsswitch.
*/
/*ARGSUSED1*/
{
#ifdef DEBUG
#endif /* DEBUG */
(void) _clean_ldap_backend(be);
return ((nss_status_t)NSS_SUCCESS);
}
/*
* _nss_ldap_setent called before _nss_ldap_getent. This function is
* required by POSIX.
*/
{
#ifdef DEBUG
#endif /* DEBUG */
(void) _nss_ldap_endent(be, a);
continue;
break;
}
/*
* To process group membership or nested group,
* need to know server specific functionality,
* so ask for extra info server type.
* getgrent.c does not have enumeration specific
* code, so need to set it here.
*/
return ((nss_status_t)NSS_SUCCESS);
}
/*
* _nss_ldap_endent called after _nss_ldap_getent. This function is
* required by POSIX.
*/
/*ARGSUSED1*/
{
#ifdef DEBUG
#endif /* DEBUG */
(void) __ns_ldap_freeError(&error);
}
}
}
}
}
return ((nss_status_t)NSS_SUCCESS);
}
/*
*
*/
{
int parsestat = 0;
int retcode = 0;
#ifdef DEBUG
#endif /* DEBUG */
(void) _nss_ldap_setent(be, a);
&be->extra_info);
/*
* Try one more time if ldap rc is LDAP_INAPPROPRIATE_MATCHING.
* Set flag to NS_LDAP_NO_PAGE_CTRL just in case the failure
* was due to no ordering rules.
*/
(void) __ns_ldap_freeError(&error);
&be->extra_info);
}
} else {
}
}
if (retcode != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeError(&error);
(void) _nss_ldap_endent(be, a);
/* filter-out invalid errno values */
return (retcode);
}
goto error_out;
}
/* ns_ldap_entry_t -> file format */
== NSS_STR_PARSE_SUCCESS) {
/* file format -> struct */
goto error_out;
}
if (parsestat == NSS_STR_PARSE_SUCCESS) {
}
return ((nss_status_t)NSS_SUCCESS);
}
} else {
/*
* nscd is not caching the enumerated
* entries. This code path would be dormant.
* Keep this path for the future references.
*/
}
}
}
if (parsestat == NSS_STR_PARSE_NO_RESULT) {
(void) _nss_ldap_endent(be, a);
/* no result is not an error */
errno = 0;
return ((nss_status_t)NSS_NOTFOUND);
}
if (parsestat == NSS_STR_PARSE_ERANGE) {
(void) _nss_ldap_endent(be, a);
return ((nss_status_t)NSS_NOTFOUND);
}
if (parsestat == NSS_STR_PARSE_NO_ADDR) {
/*
* No IPV4 address is found in the current entry.
* It indicates that the entry contains IPV6 addresses
* only. Instead of calling _nss_ldap_endent to
* terminate, get next entry to continue enumeration.
* If it returned NSS_NOTFOUND here,
* gethostent() would return NULL
* and the enumeration would stop prematurely.
*/
errno = 0;
goto next_entry;
}
if (parsestat == NSS_STR_PARSE_PARSE) {
/*
* There has been a parse error. Most likely some
* mandatory attributes are missing. Ignore the error
* and get the next entry. If we returned an error the
* enumeration would stop prematurely.
*/
errno = 0;
goto next_entry;
}
return ((nss_status_t)NSS_SUCCESS);
}
/*
*
*/
{
#ifdef DEBUG
#endif /* DEBUG */
return (NULL);
return (NULL);
}
return ((nss_backend_t *)be);
}
/*
*
*/
int
{
char *dot;
return (-1);
return (0);
}
*dot = '\0';
return (0);
}
/*
*
*/
int
{
/* sanity check */
return (-1);
/* is afterdot a substring of domain? */
return (-1);
if (domainlen == subdomainlen)
return (1);
if (subdomainlen > domainlen)
return (-1);
return (-1);
return (1);
}
/*
* case sensitive name compare routine
*/
static int
{
int res;
if (res < 0)
res = -1;
else if (res > 0)
res = 1;
return (res);
}
/*
* Add an entry to the list implemented with avl tree. Create the
* list if not already exists. Return NSS_LDAP_LIST_EXISTED if
* an entry with the same key has already been added.
*/
{
int klen;
return (NSS_LDAP_LIST_NOKEY);
/* check for existing match */
return (NSS_LDAP_LIST_EXISTED);
}
/* If list not yet created, do so. */
1);
return (NSS_LDAP_LIST_MEMORY);
sizeof (_nss_ldap_list_entry_t),
}
/* Add an entry to list */
if ((ep = (_nss_ldap_list_entry_t *)
return (NSS_LDAP_LIST_MEMORY);
return (NSS_LDAP_LIST_MEMORY);
}
/* add the entry to the avl tree */
return (NSS_LDAP_LIST_SUCCESS);
}
void
{
return;
}
avl_destroy(*list);
}
/*
* Walk a list and write the key of each entry to a buffer (*buffer).
* Keys are separated by ','. If not enough space in the buffer,
* returns NSS_LDAP_LIST_ERANGE. Otherwise, NSS_LDAP_LIST_SUCCESS.
*/
{
int len = 0;
char *s = "";
return (NSS_LDAP_LIST_NOLIST);
return (NSS_LDAP_LIST_ERANGE);
s = ",";
}
return (NSS_LDAP_LIST_SUCCESS);
}
/*
* get_server_type() checks the value of the server type attribute in
* the extra info 'entry' and returns the corresponding server type.
*/
{
if (server_type != NULL)
return (NS_LDAP_SERVERTYPE_UNKNOWN);
return (NS_LDAP_SERVERTYPE_UNKNOWN);
if (server_type != NULL)
return (NS_LDAP_SERVERTYPE_ODSEE);
}
if (server_type != NULL)
return (NS_LDAP_SERVERTYPE_AD);
}
0) {
if (server_type != NULL)
return (NS_LDAP_SERVERTYPE_OPENLDAP);
}
if (server_type != NULL)
return (NS_LDAP_SERVERTYPE_OID);
}
return (NS_LDAP_SERVERTYPE_UNKNOWN);
}