summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJulian Pullen <Julian.Pullen@Sun.COM>2010-07-02 10:46:04 +0100
committerJulian Pullen <Julian.Pullen@Sun.COM>2010-07-02 10:46:04 +0100
commit9f2fd570dfad3c35512617ae887140b15e3ec4c5 (patch)
tree3c31e673d7b92cdd0719422693002700aa126679 /usr/src
parentb1385420941f689de1d9c1c64d8c6b19b63b5b3e (diff)
downloadillumos-joyent-9f2fd570dfad3c35512617ae887140b15e3ec4c5.tar.gz
6636343 The SSS control generated by "libsldap.so.1" cannot work with Active Directory in VLV searches
6929861 NS switch LDAP enumeration terminates prematurely if LDAP mandatory attributes are missing 6963912 libsldap does not work with the VLV response from Active Directory
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ldap/ns_ldap/ldapaddent.c62
-rw-r--r--usr/src/cmd/ldap/ns_ldap/ldaplist.c59
-rw-r--r--usr/src/lib/libsldap/common/llib-lsldap19
-rw-r--r--usr/src/lib/libsldap/common/mapfile-vers1
-rw-r--r--usr/src/lib/libsldap/common/ns_internal.h22
-rw-r--r--usr/src/lib/libsldap/common/ns_mapping.c57
-rw-r--r--usr/src/lib/libsldap/common/ns_reads.c216
-rw-r--r--usr/src/lib/libsldap/common/ns_sldap.h19
-rw-r--r--usr/src/lib/nsswitch/ldap/common/ldap_common.c198
-rw-r--r--usr/src/lib/nsswitch/ldap/common/ldap_common.h5
10 files changed, 493 insertions, 165 deletions
diff --git a/usr/src/cmd/ldap/ns_ldap/ldapaddent.c b/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
index ac077dcf01..a721ba4308 100644
--- a/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
+++ b/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -68,6 +67,7 @@ static struct ttypelist_t {
/* routine to print ldap containers */
int (*filedbmline)(); /* routine to turn file line into dbm line */
char *objclass; /* Objectclass for the servicetype */
+ char *sortattr; /* Sort attr for enumeration */
} *tt;
char parse_err_msg [PARSE_ERR_MSG_LEN];
@@ -4033,54 +4033,54 @@ filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
static struct ttypelist_t ttypelist[] = {
{ NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
- filedbmline_comment, "iphost" },
+ filedbmline_comment, "iphost", "cn" },
{ NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
- filedbmline_comment, "iphost" },
+ filedbmline_comment, "iphost", "cn" },
{ NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
- filedbmline_comment, "oncrpc" },
+ filedbmline_comment, "oncrpc", "cn" },
{ NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
- filedbmline_comment, "ipprotocol" },
+ filedbmline_comment, "ipprotocol", "cn" },
{ NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
- filedbmline_comment, "ipnetwork" },
+ filedbmline_comment, "ipnetwork", "ipnetworknumber" },
{ NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
- filedbmline_comment, "ipservice" },
+ filedbmline_comment, "ipservice", "cn" },
{ NS_LDAP_TYPE_GROUP, genent_group, dump_group,
- filedbmline_plus, "posixgroup" },
+ filedbmline_plus, "posixgroup", "gidnumber" },
{ NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
- filedbmline_comment, "ipnetwork" },
+ filedbmline_comment, "ipnetwork", "ipnetworknumber"},
{ NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
- filedbmline_comment, "ieee802Device" },
+ filedbmline_comment, "ieee802Device", "cn" },
{ NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
- filedbmline_comment, "nisnetgroup" },
+ filedbmline_comment, "nisnetgroup", "cn" },
{ NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
- filedbmline_comment, "bootableDevice" },
+ filedbmline_comment, "bootableDevice", "cn" },
{ NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
- filedbmline_comment, "niskeyobject" },
+ filedbmline_comment, "niskeyobject", "cn" },
{ NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
- filedbmline_plus, "posixaccount" },
+ filedbmline_plus, "posixaccount", "uid" },
{ NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
- filedbmline_plus, "shadowaccount" },
+ filedbmline_plus, "shadowaccount", "uid" },
{ NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
- filedbmline_plus, "mailGroup" },
+ filedbmline_plus, "mailGroup", "cn" },
{ NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
- filedbmline_comment, "automount" },
+ filedbmline_comment, "automount", "automountKey" },
{ NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
- filedbmline_comment, "SolarisUserAttr" },
+ filedbmline_comment, "SolarisUserAttr", "uid" },
{ NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
- filedbmline_comment, "SolarisProfAttr" },
+ filedbmline_comment, "SolarisProfAttr", "cn" },
{ NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
- filedbmline_comment, "SolarisExecAttr" },
+ filedbmline_comment, "SolarisExecAttr", "cn" },
{ NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
- filedbmline_comment, "SolarisAuthAttr" },
+ filedbmline_comment, "SolarisAuthAttr", "cn" },
{ NS_LDAP_TYPE_AUUSER, genent_audit_user, dump_audit_user,
- filedbmline_comment, "SolarisAuditUser" },
+ filedbmline_comment, "SolarisAuditUser", "uid" },
{ NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb,
- filedbmline_comment, "ipTnetHost" },
+ filedbmline_comment, "ipTnetHost", "ipTnetNumber" },
{ NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp,
- filedbmline_comment, "ipTnetTemplate" },
+ filedbmline_comment, "ipTnetTemplate", "ipTnetTemplateName" },
{ NS_LDAP_TYPE_PROJECT, genent_project, dump_project,
- filedbmline_comment, "SolarisProject" },
- { 0, 0, 0, 0, 0 }
+ filedbmline_comment, "SolarisProject", "SolarisProjectName" },
+ { 0, 0, 0, 0, 0, 0 }
};
@@ -4167,11 +4167,11 @@ dumptable(char *service)
/* Pass cred only if supplied. Cred is not always needed for dump */
if (authority.cred.unix_cred.userID == NULL ||
authority.cred.unix_cred.passwd == NULL)
- rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
- NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
+ rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
+ NULL, NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
else
- rc = __ns_ldap_firstEntry(service, filter, NULL, NULL,
- &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
+ rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
+ NULL, &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
switch (rc) {
case NS_LDAP_SUCCESS:
diff --git a/usr/src/cmd/ldap/ns_ldap/ldaplist.c b/usr/src/cmd/ldap/ns_ldap/ldaplist.c
index a75f39f5dd..cfa74ae7f2 100644
--- a/usr/src/cmd/ldap/ns_ldap/ldaplist.c
+++ b/usr/src/cmd/ldap/ns_ldap/ldaplist.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -40,6 +39,40 @@ extern void printMapping();
int listflag = 0;
+
+
+static struct database_t {
+ const char *database;
+ const char *sortattr;
+}databaselist[] = {
+ { NS_LDAP_TYPE_HOSTS, "cn" },
+ { NS_LDAP_TYPE_IPNODES, "cn" },
+ { NS_LDAP_TYPE_RPC, "cn" },
+ { NS_LDAP_TYPE_PROTOCOLS, "cn" },
+ { NS_LDAP_TYPE_NETWORKS, "ipnetworknumber" },
+ { NS_LDAP_TYPE_SERVICES, "cn" },
+ { NS_LDAP_TYPE_GROUP, "gidnumber" },
+ { NS_LDAP_TYPE_NETMASKS, "ipnetworknumber"},
+ { NS_LDAP_TYPE_ETHERS, "cn" },
+ { NS_LDAP_TYPE_NETGROUP, "cn" },
+ { NS_LDAP_TYPE_BOOTPARAMS, "cn" },
+ { NS_LDAP_TYPE_PUBLICKEY, "cn" },
+ { NS_LDAP_TYPE_PASSWD, "uid" },
+ { NS_LDAP_TYPE_SHADOW, "uid" },
+ { NS_LDAP_TYPE_ALIASES, "cn" },
+ { NS_LDAP_TYPE_AUTOMOUNT, "automountKey" },
+ { NS_LDAP_TYPE_USERATTR, "uid" },
+ { NS_LDAP_TYPE_PROFILE, "cn" },
+ { NS_LDAP_TYPE_EXECATTR, "cn" },
+ { NS_LDAP_TYPE_AUTHATTR, "cn" },
+ { NS_LDAP_TYPE_AUUSER, "uid" },
+ { NS_LDAP_TYPE_TNRHDB, "ipTnetNumber" },
+ { NS_LDAP_TYPE_TNRHTP, "ipTnetTemplateName" },
+ { NS_LDAP_TYPE_PROJECT, "SolarisProjectName" },
+ { 0, 0 }
+};
+
+
void
usage(char *msg) {
if (msg)
@@ -146,11 +179,29 @@ char **err, char *userdata)
ns_ldap_error_t *errorp;
int rc;
char buf[500];
+ const char *sort = NULL;
+ int i;
+
+ if (database) {
+ for (i = 0; databaselist[i].database; i++) {
+ if (strcmp(databaselist[i].database, database) == 0) {
+ sort = databaselist[i].sortattr;
+ break;
+ }
+ if (strcmp(databaselist[i].database,
+ NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
+ strncmp(database, NS_LDAP_TYPE_AUTOMOUNT,
+ sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) {
+ sort = databaselist[i].sortattr;
+ break;
+ }
+ }
+ }
*err = NULL;
buf[0] = '\0';
- rc = __ns_ldap_list(database, (const char *)ldapfilter,
- merge_SSD_filter, (const char **)ldapattribute, NULL,
+ rc = __ns_ldap_list_sort(database, (const char *)ldapfilter,
+ sort, merge_SSD_filter, (const char **)ldapattribute, NULL,
listflag, &result, &errorp, NULL, userdata);
if (rc != NS_LDAP_SUCCESS) {
char *p;
diff --git a/usr/src/lib/libsldap/common/llib-lsldap b/usr/src/lib/libsldap/common/llib-lsldap
index 466116a856..5f59110773 100644
--- a/usr/src/lib/libsldap/common/llib-lsldap
+++ b/usr/src/lib/libsldap/common/llib-lsldap
@@ -22,10 +22,8 @@
/* PROTOLIB1 */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ *Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <sys/types.h>
@@ -50,6 +48,20 @@ int __ns_ldap_list(
int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
const void *userdata);
+int __ns_ldap_list_sort(
+ const char *service,
+ const char *filter,
+ const char *sortattr,
+ int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+ char **realfilter, const void *userdata),
+ const char * const *attribute,
+ const ns_cred_t *cred,
+ const int flags,
+ ns_ldap_result_t ** result,
+ ns_ldap_error_t ** errorp,
+ int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
+ const void *userdata);
+
int __ns_ldap_addAttr(
const char *service,
const char *dn,
@@ -101,6 +113,7 @@ int __ns_ldap_delEntry(
int __ns_ldap_firstEntry(
const char *service,
const char *filter,
+ const char *sortattr,
int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
char **realfilter, const void *userdata),
const char * const *attribute,
diff --git a/usr/src/lib/libsldap/common/mapfile-vers b/usr/src/lib/libsldap/common/mapfile-vers
index e511edf76b..8c88eb55bb 100644
--- a/usr/src/lib/libsldap/common/mapfile-vers
+++ b/usr/src/lib/libsldap/common/mapfile-vers
@@ -55,6 +55,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
__ns_ldap_initAuth;
__ns_ldap_initStandalone;
__ns_ldap_is_shadow_update_enabled;
+ __ns_ldap_list_sort;
__ns_ldap_pingOfflineServers;
__ns_ldap_self_gssapi_config;
__ns_ldap_self_gssapi_only_set;
diff --git a/usr/src/lib/libsldap/common/ns_internal.h b/usr/src/lib/libsldap/common/ns_internal.h
index 7e2bbafaba..8026f150bc 100644
--- a/usr/src/lib/libsldap/common/ns_internal.h
+++ b/usr/src/lib/libsldap/common/ns_internal.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -74,7 +73,6 @@ extern "C" {
#define LISTPAGESIZE 1000
#define ENUMPAGESIZE 100
-#define SORTKEYLIST "cn uid"
#define DEFMAX 8
#define TOKENSEPARATOR '='
@@ -553,6 +551,19 @@ typedef enum {
typedef int ConnectionID;
/*
+ * Server side sort type. Orginally the server side sort
+ * was set to "cn uid". This did not work with AD and
+ * hence single sort attribute was odopted. We dont
+ * know which server side sort will work with the
+ * Directory and hence we discover which method works.
+ */
+typedef enum {
+ SSS_UNKNOWN = 0,
+ SSS_SINGLE_ATTR = 1,
+ SSS_CN_UID_ATTRS = 2
+} ns_srvsidesort_t;
+
+/*
* This structure is used by ns_connect to create and manage
* one or more ldap connections within the library.
*/
@@ -628,6 +639,7 @@ typedef struct ns_ldap_cookie {
char *service;
char *i_filter;
const char * const *i_attr;
+ const char *i_sortattr;
const ns_cred_t *i_auth;
int i_flags;
@@ -651,6 +663,8 @@ typedef struct ns_ldap_cookie {
int listType;
unsigned long index;
LDAPControl **p_serverctrls;
+ ns_srvsidesort_t sortTypeTry;
+ int entryCount;
int scope;
char *basedn;
@@ -825,6 +839,8 @@ int __s_api_parse_map(char *cp, char **sid,
char **origA, char ***mapA);
char **__ns_ldap_mapAttributeList(const char *service,
const char * const *origAttrList);
+char *__ns_ldap_mapAttribute(const char *service,
+ const char *origAttr);
/* internal configuration APIs */
void __ns_ldap_setServer(int set);
diff --git a/usr/src/lib/libsldap/common/ns_mapping.c b/usr/src/lib/libsldap/common/ns_mapping.c
index 686a57ddb9..1ceb035941 100644
--- a/usr/src/lib/libsldap/common/ns_mapping.c
+++ b/usr/src/lib/libsldap/common/ns_mapping.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2000-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
@@ -350,7 +346,7 @@ __s_api_parseASearchDesc(const char *service,
return (NS_LDAP_INVALID_PARAM);
ptr = (ns_ldap_search_desc_t *)
- calloc(1, sizeof (ns_ldap_search_desc_t));
+ calloc(1, sizeof (ns_ldap_search_desc_t));
if (ptr == NULL)
return (NS_LDAP_MEMORY);
@@ -358,7 +354,7 @@ __s_api_parseASearchDesc(const char *service,
/* Get the default scope */
if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
- &paramVal, errorp)) != NS_LDAP_SUCCESS) {
+ &paramVal, errorp)) != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeError(errorp);
__ns_ldap_freeASearchDesc(ptr);
ptr = NULL;
@@ -629,14 +625,14 @@ __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
*cnt = 0;
*max = NS_SDESC_MAX;
*sdlist = (ns_ldap_search_desc_t **)
- calloc(*max, sizeof (ns_ldap_search_desc_t *));
+ calloc(*max, sizeof (ns_ldap_search_desc_t *));
if (*sdlist == NULL)
return (-1);
} else if (*cnt+1 >= *max) {
*max += NS_SDESC_MAX;
tmplist = (ns_ldap_search_desc_t **)
- realloc((void *)(*sdlist),
- *max * sizeof (ns_ldap_search_desc_t *));
+ realloc((void *)(*sdlist),
+ *max * sizeof (ns_ldap_search_desc_t *));
if (tmplist == NULL)
return (-1);
else
@@ -677,7 +673,7 @@ int __ns_ldap_getSearchDescriptors(
*errorp = NULL;
rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
- (void ***)&param, errorp);
+ (void ***)&param, errorp);
if (rc != NS_LDAP_SUCCESS) {
return (rc);
}
@@ -692,7 +688,7 @@ int __ns_ldap_getSearchDescriptors(
(void) snprintf(errstr, sizeof (errstr),
gettext("No configuration information available."));
MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
- NULL);
+ NULL);
return (NS_LDAP_CONFIG);
}
@@ -709,7 +705,7 @@ int __ns_ldap_getSearchDescriptors(
/* Convert a SEARCH_DN to a search descriptor */
for (; *sdl; sdl++) {
ret = (ns_ldap_search_desc_t *)
- calloc(1, sizeof (ns_ldap_search_desc_t));
+ calloc(1, sizeof (ns_ldap_search_desc_t));
if (ret == NULL) {
(void) __ns_ldap_freeSearchDescriptors(&sdlist);
__s_api_free2dArray(sdl_save);
@@ -726,7 +722,7 @@ int __ns_ldap_getSearchDescriptors(
/* default scope */
if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
- &paramVal, errorp)) != NS_LDAP_SUCCESS) {
+ &paramVal, errorp)) != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeASearchDesc(ret);
(void) __ns_ldap_freeSearchDescriptors(&sdlist);
__s_api_free2dArray(sdl_save);
@@ -775,17 +771,17 @@ int __ns_ldap_getSearchDescriptors(
if (rc != NS_LDAP_SUCCESS) {
(void) __ns_ldap_freeSearchDescriptors(&sdlist);
(void) snprintf(errstr, (2 * MAXERROR), gettext(
- "Invalid serviceSearchDescriptor (%s). "
- "Illegal configuration"), *sdl);
+ "Invalid serviceSearchDescriptor (%s). "
+ "Illegal configuration"), *sdl);
(void) __ns_ldap_freeParam(&param);
param = NULL;
MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
- strdup(errstr), NULL);
+ strdup(errstr), NULL);
return (rc);
}
if (ret != NULL) {
rc = __ns_ldap_saveSearchDesc(
- &sdlist, &cnt, &max, ret);
+ &sdlist, &cnt, &max, ret);
}
if (rc < 0) {
(void) __ns_ldap_freeSearchDescriptors(&sdlist);
@@ -1028,3 +1024,24 @@ char **__ns_ldap_mapAttributeList(
}
return (cpp);
}
+
+char *
+__ns_ldap_mapAttribute(
+ const char *service,
+ const char *origAttr)
+{
+ char **npp;
+ char *mappedAttr;
+
+ if (origAttr == NULL)
+ return (NULL);
+
+ npp = __ns_ldap_getMappedAttributes(service, origAttr);
+ if (npp && npp[0]) {
+ mappedAttr = strdup(npp[0]);
+ __s_api_free2dArray(npp);
+ } else {
+ mappedAttr = strdup(origAttr);
+ }
+ return (mappedAttr);
+}
diff --git a/usr/src/lib/libsldap/common/ns_reads.c b/usr/src/lib/libsldap/common/ns_reads.c
index cda5b344fe..61a59e16db 100644
--- a/usr/src/lib/libsldap/common/ns_reads.c
+++ b/usr/src/lib/libsldap/common/ns_reads.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdio.h>
@@ -1746,6 +1745,87 @@ paging_supported(ns_ldap_cookie_t *cookie)
return (0);
}
+typedef struct servicesorttype {
+ char *service;
+ ns_srvsidesort_t type;
+} servicesorttype_t;
+
+static servicesorttype_t *sort_type = NULL;
+static int sort_type_size = 0;
+static int sort_type_hwm = 0;
+static mutex_t sort_type_mutex = DEFAULTMUTEX;
+
+
+static ns_srvsidesort_t
+get_srvsidesort_type(char *service)
+{
+ int i;
+ ns_srvsidesort_t type = SSS_UNKNOWN;
+
+ if (service == NULL)
+ return (type);
+
+ (void) mutex_lock(&sort_type_mutex);
+ if (sort_type != NULL) {
+ for (i = 0; i < sort_type_hwm; i++) {
+ if (strcmp(sort_type[i].service, service) == 0) {
+ type = sort_type[i].type;
+ break;
+ }
+ }
+ }
+ (void) mutex_unlock(&sort_type_mutex);
+ return (type);
+}
+
+static void
+update_srvsidesort_type(char *service, ns_srvsidesort_t type)
+{
+ int i, size;
+ servicesorttype_t *tmp;
+
+ if (service == NULL)
+ return;
+
+ (void) mutex_lock(&sort_type_mutex);
+
+ for (i = 0; i < sort_type_hwm; i++) {
+ if (strcmp(sort_type[i].service, service) == 0) {
+ sort_type[i].type = type;
+ (void) mutex_unlock(&sort_type_mutex);
+ return;
+ }
+ }
+ if (sort_type == NULL) {
+ size = 10;
+ tmp = malloc(size * sizeof (servicesorttype_t));
+ if (tmp == NULL) {
+ (void) mutex_unlock(&sort_type_mutex);
+ return;
+ }
+ sort_type = tmp;
+ sort_type_size = size;
+ } else if (sort_type_hwm >= sort_type_size) {
+ size = sort_type_size + 10;
+ tmp = realloc(sort_type, size * sizeof (servicesorttype_t));
+ if (tmp == NULL) {
+ (void) mutex_unlock(&sort_type_mutex);
+ return;
+ }
+ sort_type = tmp;
+ sort_type_size = size;
+ }
+ sort_type[sort_type_hwm].service = strdup(service);
+ if (sort_type[sort_type_hwm].service == NULL) {
+ (void) mutex_unlock(&sort_type_mutex);
+ return;
+ }
+ sort_type[sort_type_hwm].type = type;
+ sort_type_hwm++;
+
+ (void) mutex_unlock(&sort_type_mutex);
+}
+
static int
setup_vlv_params(ns_ldap_cookie_t *cookie)
{
@@ -1754,11 +1834,35 @@ setup_vlv_params(ns_ldap_cookie_t *cookie)
LDAPControl *sortctrl = NULL;
LDAPControl *vlvctrl = NULL;
LDAPVirtualList vlist;
+ char *sortattr;
int rc;
+ int free_sort = FALSE;
_freeControlList(&cookie->p_serverctrls);
- rc = ldap_create_sort_keylist(&sortkeylist, SORTKEYLIST);
+ if (cookie->sortTypeTry == SSS_UNKNOWN)
+ cookie->sortTypeTry = get_srvsidesort_type(cookie->service);
+ if (cookie->sortTypeTry == SSS_UNKNOWN)
+ cookie->sortTypeTry = SSS_SINGLE_ATTR;
+
+ if (cookie->sortTypeTry == SSS_SINGLE_ATTR) {
+ if ((cookie->i_flags & NS_LDAP_NOMAP) == 0 &&
+ cookie->i_sortattr) {
+ sortattr = __ns_ldap_mapAttribute(cookie->service,
+ cookie->i_sortattr);
+ free_sort = TRUE;
+ } else if (cookie->i_sortattr) {
+ sortattr = (char *)cookie->i_sortattr;
+ } else {
+ sortattr = "cn";
+ }
+ } else {
+ sortattr = "cn uid";
+ }
+
+ rc = ldap_create_sort_keylist(&sortkeylist, sortattr);
+ if (free_sort)
+ free(sortattr);
if (rc != LDAP_SUCCESS) {
(void) ldap_get_option(cookie->conn->ld,
LDAP_OPT_ERROR_NUMBER, &rc);
@@ -1982,9 +2086,21 @@ multi_result(ns_ldap_cookie_t *cookie)
cookie->conn->ld, retCtrls,
&target_posp, &list_size, &errCode);
if (rc == LDAP_SUCCESS) {
- cookie->index = target_posp + LISTPAGESIZE;
- if (cookie->index > list_size) {
- finished = 1;
+ /*
+ * AD does not return valid target_posp
+ * and list_size
+ */
+ if (target_posp != 0 && list_size != 0) {
+ cookie->index =
+ target_posp + LISTPAGESIZE;
+ if (cookie->index > list_size)
+ finished = 1;
+ } else {
+ if (cookie->entryCount < LISTPAGESIZE)
+ finished = 1;
+ else
+ cookie->index +=
+ cookie->entryCount;
}
}
ldap_controls_free(retCtrls);
@@ -2095,8 +2211,11 @@ clear_results(ns_ldap_cookie_t *cookie)
rc = ldap_result(cookie->conn->ld, cookie->msgId, LDAP_MSG_ALL,
(struct timeval *)&cookie->search_timeout,
&cookie->resultMsg);
- if (rc != -1 && rc != 0 && cookie->resultMsg != NULL)
+ if (rc != -1 && rc != 0 && cookie->resultMsg != NULL) {
(void) ldap_msgfree(cookie->resultMsg);
+ cookie->resultMsg = NULL;
+ }
+
/*
* If there was timeout then we will send ABANDON request to
* LDAP server to decrease load.
@@ -2315,6 +2434,7 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle)
cookie->new_state = DO_SEARCH;
break;
case DO_SEARCH:
+ cookie->entryCount = 0;
rc = ldap_search_ext(cookie->conn->ld,
cookie->basedn,
cookie->scope,
@@ -2566,10 +2686,21 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle)
if (rc == LDAP_RES_SEARCH_RESULT) {
rc = ldap_result2error(cookie->conn->ld,
cookie->resultMsg, 0);
+ if (rc == LDAP_ADMINLIMIT_EXCEEDED &&
+ cookie->listType == VLVCTRLFLAG &&
+ cookie->sortTypeTry == SSS_SINGLE_ATTR) {
+ /* Try old "cn uid" server side sort */
+ cookie->sortTypeTry = SSS_CN_UID_ATTRS;
+ cookie->new_state = NEXT_VLV;
+ (void) ldap_msgfree(cookie->resultMsg);
+ cookie->resultMsg = NULL;
+ break;
+ }
if (rc != LDAP_SUCCESS) {
cookie->err_rc = rc;
cookie->new_state = LDAP_ERROR;
(void) ldap_msgfree(cookie->resultMsg);
+ cookie->resultMsg = NULL;
break;
}
cookie->new_state = multi_result(cookie);
@@ -2634,6 +2765,7 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle)
NEXT_SESSION;
break;
}
+
if ((rc == LDAP_CONNECT_ERROR ||
rc == LDAP_SERVER_DOWN) &&
cookie->reinit_on_retriable_err) {
@@ -2657,6 +2789,7 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle)
break;
}
/* else LDAP_RES_SEARCH_ENTRY */
+ cookie->entryCount++;
rc = __s_api_getEntry(cookie);
(void) ldap_msgfree(cookie->resultMsg);
cookie->resultMsg = NULL;
@@ -2664,6 +2797,14 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle)
cookie->new_state = LDAP_ERROR;
break;
}
+ /*
+ * If VLV search was successfull save the server
+ * side sort type tried.
+ */
+ if (cookie->listType == VLVCTRLFLAG)
+ update_srvsidesort_type(cookie->service,
+ cookie->sortTypeTry);
+
cookie->new_state = PROCESS_RESULT;
cookie->next_state = MULTI_RESULT;
break;
@@ -2910,6 +3051,7 @@ ldap_list(
ns_ldap_list_batch_t *batch,
const char *service,
const char *filter,
+ const char *sortattr,
int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
char **realfilter, const void *userdata),
const char * const *attribute,
@@ -3065,6 +3207,7 @@ ldap_list(
cookie->i_filter = strdup(filter);
cookie->i_attr = attribute;
cookie->i_auth = auth;
+ cookie->i_sortattr = sortattr;
if (batch != NULL) {
cookie->batch = batch;
@@ -3128,7 +3271,6 @@ ldap_list(
* mapping as appropriate. The operation may be retried a
* couple of times in error situations.
*/
-
int
__ns_ldap_list(
const char *service,
@@ -3143,6 +3285,40 @@ __ns_ldap_list(
int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
const void *userdata)
{
+ int mod_flags;
+ /*
+ * Strip the NS_LDAP_PAGE_CTRL option as this interface does not
+ * support this. If you want to use this option call the API
+ * __ns_ldap_list_sort() with has the sort attribute.
+ */
+ mod_flags = flags & (~NS_LDAP_PAGE_CTRL);
+
+ return (__ns_ldap_list_sort(service, filter, NULL, init_filter_cb,
+ attribute, auth, mod_flags, rResult, errorp,
+ callback, userdata));
+}
+
+/*
+ * __ns_ldap_list_sort performs one or more LDAP searches to a given
+ * directory server using service search descriptors and schema
+ * mapping as appropriate. The operation may be retried a
+ * couple of times in error situations.
+ */
+int
+__ns_ldap_list_sort(
+ const char *service,
+ const char *filter,
+ const char *sortattr,
+ int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+ char **realfilter, const void *userdata),
+ const char * const *attribute,
+ const ns_cred_t *auth,
+ const int flags,
+ ns_ldap_result_t **rResult, /* return result entries */
+ ns_ldap_error_t **errorp,
+ int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
+ const void *userdata)
+{
ns_conn_user_t *cu = NULL;
int try_cnt = 0;
int rc = NS_LDAP_SUCCESS, trc;
@@ -3151,8 +3327,9 @@ __ns_ldap_list(
if (__s_api_setup_retry_search(&cu, NS_CONN_USER_SEARCH,
&try_cnt, &rc, errorp) == 0)
break;
- rc = ldap_list(NULL, service, filter, init_filter_cb, attribute,
- auth, flags, rResult, errorp, &trc, callback, userdata, cu);
+ rc = ldap_list(NULL, service, filter, sortattr, init_filter_cb,
+ attribute, auth, flags, rResult, errorp, &trc, callback,
+ userdata, cu);
}
return (rc);
@@ -3192,6 +3369,7 @@ __ns_ldap_list_batch_add(
{
ns_conn_user_t *cu;
int rc;
+ int mod_flags;
cu = __s_api_conn_user_init(NS_CONN_USER_SEARCH, NULL, 0);
if (cu == NULL) {
@@ -3200,8 +3378,14 @@ __ns_ldap_list_batch_add(
return (NS_LDAP_MEMORY);
}
- rc = ldap_list(batch, service, filter, init_filter_cb, attribute, auth,
- flags, rResult, errorp, rcp, callback, userdata, cu);
+ /*
+ * Strip the NS_LDAP_PAGE_CTRL option as the batch interface does not
+ * support this.
+ */
+ mod_flags = flags & (~NS_LDAP_PAGE_CTRL);
+
+ rc = ldap_list(batch, service, filter, NULL, init_filter_cb, attribute,
+ auth, mod_flags, rResult, errorp, rcp, callback, userdata, cu);
/*
* Free the conn_user if the cookie was not batched. If the cookie
@@ -3531,6 +3715,7 @@ static int
firstEntry(
const char *service,
const char *filter,
+ const char *sortattr,
int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
char **realfilter, const void *userdata),
const char * const *attribute,
@@ -3683,6 +3868,7 @@ firstEntry(
cookie->i_filter = strdup(filter);
cookie->i_attr = attribute;
+ cookie->i_sortattr = sortattr;
cookie->i_auth = auth;
state = INIT;
@@ -3732,6 +3918,7 @@ int
__ns_ldap_firstEntry(
const char *service,
const char *filter,
+ const char *vlv_sort,
int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
char **realfilter, const void *userdata),
const char * const *attribute,
@@ -3750,8 +3937,9 @@ __ns_ldap_firstEntry(
if (__s_api_setup_retry_search(&cu, NS_CONN_USER_GETENT,
&try_cnt, &rc, errorp) == 0)
break;
- rc = firstEntry(service, filter, init_filter_cb, attribute,
- auth, flags, vcookie, result, errorp, userdata, cu);
+ rc = firstEntry(service, filter, vlv_sort, init_filter_cb,
+ attribute, auth, flags, vcookie, result, errorp, userdata,
+ cu);
}
return (rc);
}
diff --git a/usr/src/lib/libsldap/common/ns_sldap.h b/usr/src/lib/libsldap/common/ns_sldap.h
index a540e7d2f1..434c2806ad 100644
--- a/usr/src/lib/libsldap/common/ns_sldap.h
+++ b/usr/src/lib/libsldap/common/ns_sldap.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -693,6 +692,21 @@ int __ns_ldap_list(
int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
const void *userdata);
+
+int __ns_ldap_list_sort(
+ const char *service,
+ const char *filter,
+ const char *sortattr,
+ int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+ char **realfilter, const void *userdata),
+ const char * const *attribute,
+ const ns_cred_t *cred,
+ const int flags,
+ ns_ldap_result_t ** result,
+ ns_ldap_error_t ** errorp,
+ int (*callback)(const ns_ldap_entry_t *entry, const void *userdata),
+ const void *userdata);
+
int __ns_ldap_list_batch_start(
ns_ldap_list_batch_t **batch);
@@ -768,6 +782,7 @@ int __ns_ldap_delEntry(
int __ns_ldap_firstEntry(
const char *service,
const char *filter,
+ const char *sortattr,
int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
char **realfilter, const void *userdata),
const char * const *attribute,
diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.c b/usr/src/lib/nsswitch/ldap/common/ldap_common.c
index 46284899c8..c4103ef03e 100644
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c
@@ -19,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "ldap_common.h"
#include <malloc.h>
#include <synch.h>
@@ -60,29 +57,42 @@
"(SolarisAttrKeyValue=*))"
#define _F_GETENT_SSD "(%s)"
+/* getent sort attributes */
+#define _A_UID "uid"
+#define _A_GIDNUMBER "gidnumber"
+#define _A_CN "cn"
+#define _A_IPNETWORKNUM "ipnetworknumber"
+#define _A_PROJECTNAM "SolarisProjectName"
+#define _A_IPTNETNUM "ipTnetNumber"
+#define _A_IPTNETTMPLNAM "ipTnetTemplateName"
+
static struct gettablefilter {
char *tablename;
char *tablefilter;
+ char *sortattr;
} gettablefilterent[] = {
- {(char *)_PASSWD, (char *)_F_GETPWENT},
- {(char *)_SHADOW, (char *)_F_GETSPENT},
- {(char *)_GROUP, (char *)_F_GETGRENT},
- {(char *)_HOSTS, (char *)_F_GETHOSTENT},
- {(char *)_NETWORKS, (char *)_F_GETNETENT},
- {(char *)_PROTOCOLS, (char *)_F_GETPROTOENT},
- {(char *)_RPC, (char *)_F_GETRPCENT},
- {(char *)_ALIASES, (char *)_F_GETALIASENT},
- {(char *)_SERVICES, (char *)_F_GETSERVENT},
- {(char *)_AUUSER, (char *)_F_GETAUUSERNAME},
- {(char *)_AUTHATTR, (char *)_F_GETAUTHNAME},
- {(char *)_EXECATTR, (char *)_F_GETEXECNAME},
- {(char *)_PROFATTR, (char *)_F_GETPROFNAME},
- {(char *)_USERATTR, (char *)_F_GETUSERNAME},
- {(char *)_PROJECT, (char *)_F_GETPROJENT},
- {(char *)_PRINTERS, (char *)_F_GETPRINTERENT},
- {(char *)_TNRHDB, (char *)_F_GETTNRHDB},
- {(char *)_TNRHTP, (char *)_F_GETTNRHTP},
- {(char *)NULL, (char *)NULL}
+ {(char *)_PASSWD, (char *)_F_GETPWENT, (char *)_A_UID},
+ {(char *)_SHADOW, (char *)_F_GETSPENT, (char *)_A_UID},
+ {(char *)_GROUP, (char *)_F_GETGRENT, (char *)_A_GIDNUMBER},
+ {(char *)_HOSTS, (char *)_F_GETHOSTENT, (char *)_A_CN},
+ {(char *)_NETWORKS, (char *)_F_GETNETENT,
+ (char *)_A_IPNETWORKNUM},
+ {(char *)_PROTOCOLS, (char *)_F_GETPROTOENT, (char *)_A_CN},
+ {(char *)_RPC, (char *)_F_GETRPCENT, (char *)_A_CN},
+ {(char *)_ALIASES, (char *)_F_GETALIASENT, (char *)_A_CN},
+ {(char *)_SERVICES, (char *)_F_GETSERVENT, (char *)_A_CN},
+ {(char *)_AUUSER, (char *)_F_GETAUUSERNAME,
+ (char *)_A_UID},
+ {(char *)_AUTHATTR, (char *)_F_GETAUTHNAME, (char *)_A_CN},
+ {(char *)_EXECATTR, (char *)_F_GETEXECNAME, (char *)_A_CN},
+ {(char *)_PROFATTR, (char *)_F_GETPROFNAME, (char *)_A_CN},
+ {(char *)_USERATTR, (char *)_F_GETUSERNAME, (char *)_A_UID},
+ {(char *)_PROJECT, (char *)_F_GETPROJENT, (char *)_A_PROJECTNAM},
+ {(char *)_PRINTERS, (char *)_F_GETPRINTERENT, (char *)_A_CN},
+ {(char *)_TNRHDB, (char *)_F_GETTNRHDB, (char *)_A_IPTNETNUM},
+ {(char *)_TNRHTP, (char *)_F_GETTNRHTP,
+ (char *)_A_IPTNETTMPLNAM},
+ {(char *)NULL, (char *)NULL, (char *)NULL}
};
@@ -339,10 +349,12 @@ _nss_ldap_setent(ldap_backend_ptr be, void *a)
if (be->setcalled == 1)
(void) _nss_ldap_endent(be, a);
be->filter = NULL;
+ be->sortattr = NULL;
for (gtf = gettablefilterent; gtf->tablename != (char *)NULL; gtf++) {
if (strcmp(gtf->tablename, be->tablename))
continue;
be->filter = (char *)gtf->tablefilter;
+ be->sortattr = (char *)gtf->sortattr;
break;
}
@@ -372,6 +384,7 @@ _nss_ldap_endent(ldap_backend_ptr be, void *a)
be->setcalled = 0;
be->filter = NULL;
+ be->sortattr = NULL;
if (be->enumcookie != NULL) {
(void) __ns_ldap_endEntry(&be->enumcookie, &error);
(void) __ns_ldap_freeError(&error);
@@ -413,8 +426,8 @@ _nss_ldap_getent(ldap_backend_ptr be, void *a)
next_entry:
if (be->enumcookie == NULL) {
retcode = __ns_ldap_firstEntry(be->tablename,
- be->filter, _merge_SSD_filter, be->attrs, NULL,
- 0, &be->enumcookie,
+ be->filter, be->sortattr, _merge_SSD_filter, be->attrs,
+ NULL, 0, &be->enumcookie,
&be->result, &error, _F_GETENT_SSD);
} else {
if (be->services_cookie == NULL) {
@@ -427,73 +440,86 @@ next_entry:
(void) __ns_ldap_freeError(&error);
(void) _nss_ldap_endent(be, a);
return (retcode);
- } else {
- /* ns_ldap_entry_t -> file format */
- if ((parsestat = be->ldapobj2str(be, argp))
- == NSS_STR_PARSE_SUCCESS) {
- if (argp->buf.result != NULL) {
- /* file format -> struct */
- if (argp->str2ent == NULL) {
- parsestat = NSS_STR_PARSE_PARSE;
- goto error_out;
- }
- parsestat = (*argp->str2ent)(be->buffer,
- be->buflen,
- argp->buf.result,
- argp->buf.buffer,
- argp->buf.buflen);
- if (parsestat == NSS_STR_PARSE_SUCCESS) {
- if (be->buffer != NULL) {
- free(be->buffer);
- be->buffer = NULL;
- be->buflen = 0;
- }
- be->result = NULL;
- argp->returnval = argp->buf.result;
- argp->returnlen = 1; /* irrevelant */
- return ((nss_status_t)NSS_SUCCESS);
+ }
+
+ if (be->result == NULL) {
+ parsestat = NSS_STR_PARSE_NO_RESULT;
+ goto error_out;
+ }
+ /* ns_ldap_entry_t -> file format */
+ if ((parsestat = be->ldapobj2str(be, argp))
+ == NSS_STR_PARSE_SUCCESS) {
+ if (argp->buf.result != NULL) {
+ /* file format -> struct */
+ if (argp->str2ent == NULL) {
+ parsestat = NSS_STR_PARSE_NO_RESULT;
+ goto error_out;
+ }
+ parsestat = (*argp->str2ent)(be->buffer,
+ be->buflen,
+ argp->buf.result,
+ argp->buf.buffer,
+ argp->buf.buflen);
+ if (parsestat == NSS_STR_PARSE_SUCCESS) {
+ if (be->buffer != NULL) {
+ free(be->buffer);
+ be->buffer = NULL;
+ be->buflen = 0;
}
- } else {
- /*
- * nscd is not caching the enumerated
- * entries. This code path would be dormant.
- * Keep this path for the future references.
- */
- argp->returnval = argp->buf.buffer;
- argp->returnlen =
- strlen(argp->buf.buffer) + 1;
+ be->result = NULL;
+ argp->returnval = argp->buf.result;
+ argp->returnlen = 1; /* irrevelant */
+ 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.
+ */
+ argp->returnval = argp->buf.buffer;
+ argp->returnlen =
+ strlen(argp->buf.buffer) + 1;
}
+ }
error_out:
- if (be->buffer != NULL) {
- free(be->buffer);
- be->buffer = NULL;
- be->buflen = 0;
- }
- be->result = NULL;
- if (parsestat == NSS_STR_PARSE_PARSE) {
- argp->returnval = 0;
- (void) _nss_ldap_endent(be, a);
- return ((nss_status_t)NSS_NOTFOUND);
- }
+ if (be->buffer != NULL) {
+ free(be->buffer);
+ be->buffer = NULL;
+ be->buflen = 0;
+ }
+ be->result = NULL;
+ if (parsestat == NSS_STR_PARSE_NO_RESULT) {
+ argp->returnval = 0;
+ (void) _nss_ldap_endent(be, a);
+ return ((nss_status_t)NSS_NOTFOUND);
+ }
- if (parsestat == NSS_STR_PARSE_ERANGE) {
- argp->erange = 1;
- (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.
- */
- goto next_entry;
+ if (parsestat == NSS_STR_PARSE_ERANGE) {
+ argp->erange = 1;
+ (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.
+ */
+ 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.
+ */
+ goto next_entry;
return ((nss_status_t)NSS_SUCCESS);
}
diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.h b/usr/src/lib/nsswitch/ldap/common/ldap_common.h
index 7d9b56613a..690dd15adc 100644
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LDAP_COMMON_H
@@ -69,6 +68,7 @@ extern "C" {
#define _TNRHTP "tnrhtp"
#define NSS_STR_PARSE_NO_ADDR (NSS_STR_PARSE_ERANGE + 100)
+#define NSS_STR_PARSE_NO_RESULT (NSS_STR_PARSE_ERANGE + 101)
#define DOTTEDSUBDOMAIN(string) \
((string != NULL) && (strchr(string, '.') != NULL))
@@ -118,6 +118,7 @@ struct ldap_backend {
char *tablename;
void *enumcookie;
char *filter;
+ char *sortattr;
int setcalled;
const char **attrs;
ns_ldap_result_t *result;