Add the ability to specify name prefixes and suffixes, which apply to users and groups, as part of search descriptors. To make this work, we need to: * Not consult a search descriptor if it specifies a prefix/suffix and the query key doesn't match. We assume that no users or groups in a descriptor which specifies neither a prefix nor a suffix have names that might be mistaken for one which "belongs" to another descriptor. We also need to be able to pass length-counted strings to functions which produce the filter. * Prepend/append the prefix/suffix to all user and group names being handed back from getpw* and getgr*. The various *assign* functions which do the work need to accept a flag to explicitly enable/disable this behavior. * If a group contains a uniqueMember, match its DN to the right search descriptor (currently uses strcmp(), which *can't* be right) and use the prefix/suffix information which it contains. To make this easier, change the list of search descriptors into a doubly-linked list. Configuration: nss_base_passwd dc=example,dc=com?sub??name_prefix=EXAMPLE\ nss_base_group dc=example,dc=com?sub??name_prefix=EXAMPLE\ nss_base_passwd dc=example,dc=com?sub??name_suffix=@example.com nss_base_group dc=example,dc=com?sub??name_suffix=@example.com diff -ur nss_ldap/ldap-alias.c --- nss_ldap/ldap-alias.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-alias.c 2005-11-11 17:18:04.000000000 -0500 @@ -59,21 +59,22 @@ static NSS_STATUS _nss_ldap_parse_alias (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct aliasent *alias = (struct aliasent *) result; NSS_STATUS stat; stat = - _nss_ldap_getrdnvalue (e, ATM (aliases, cn), &alias->alias_name, - &buffer, &buflen); + _nss_ldap_getrdnvalue (e, ATM (aliases, cn), 0, &alias->alias_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrvals (e, AT (rfc822MailMember), NULL, - &alias->alias_members, &buffer, &buflen, + _nss_ldap_assign_attrvals (e, AT (rfc822MailMember), 0, NULL, + &alias->alias_members, sd, &buffer, &buflen, &alias->alias_members_len); alias->alias_local = 0; diff -ur nss_ldap/ldap-alias.h --- nss_ldap/ldap-alias.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-alias.h 2005-11-11 15:55:59.000000000 -0500 @@ -26,6 +26,7 @@ static NSS_STATUS _nss_ldap_parse_alias (LDAPMessage * e, ldap_state_t *, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #if 0 diff -ur nss_ldap/ldap-bp.c --- nss_ldap/ldap-bp.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-bp.c 2005-11-11 17:05:38.000000000 -0500 @@ -67,20 +67,21 @@ static NSS_STATUS _nss_ldap_parse_bp (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct bootparams *bp = (struct bootparams *) result; NSS_STATUS stat; stat = - _nss_ldap_assign_attrval (e, ATM (bootparams, cn), &bp->bp_name, - &buffer, &buflen); + _nss_ldap_assign_attrval (e, ATM (bootparams, cn), 0, &bp->bp_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrvals (e, AT (bootParameter), NULL, - &bp->bp_params, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, AT (bootParameter), 0, NULL, + &bp->bp_params, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; diff -ur nss_ldap/ldap-bp.h --- nss_ldap/ldap-bp.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-bp.h 2005-11-11 15:55:59.000000000 -0500 @@ -34,6 +34,7 @@ static NSS_STATUS _nss_ldap_parse_bp (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-ethers.c --- nss_ldap/ldap-ethers.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-ethers.c 2005-11-11 17:05:28.000000000 -0500 @@ -99,20 +99,21 @@ static NSS_STATUS _nss_ldap_parse_ether (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct ether *ether = (struct ether *) result; char *saddr; NSS_STATUS stat; struct ether_addr *addr; - stat = _nss_ldap_assign_attrval (e, ATM (ethers, cn), - ðer->e_name, &buffer, &buflen); + stat = _nss_ldap_assign_attrval (e, ATM (ethers, cn), 0, + ðer->e_name, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; - stat = _nss_ldap_assign_attrval (e, AT (macAddress), &saddr, - &buffer, &buflen); + stat = _nss_ldap_assign_attrval (e, AT (macAddress), 0, &saddr, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS || ((addr = ether_aton (saddr)) == NULL)) return NSS_NOTFOUND; diff -ur nss_ldap/ldap-ethers.h --- nss_ldap/ldap-ethers.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-ethers.h 2005-11-11 15:55:59.000000000 -0500 @@ -46,6 +46,7 @@ static NSS_STATUS _nss_ldap_parse_ether (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #endif diff -ur nss_ldap/ldap-grp.c --- nss_ldap/ldap-grp.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-grp.c 2005-11-11 17:49:17.000000000 -0500 @@ -283,6 +283,7 @@ size_t * pGroupMembersCount, size_t * pGroupMembersBufferSize, int *pGroupMembersBufferIsMalloced, + ldap_service_search_descriptor_t *sd, char **buffer, size_t * buflen, int *depth, struct name_list **pKnownGroups) /* traversed groups */ @@ -412,7 +413,8 @@ *uid = '\0'; } parseStat = _nss_ldap_dn2uid (*valiter, &groupMembers[i], + sd, LF_NAME, buffer, buflen, &isNestedGroup, &res); if (parseStat == NSS_SUCCESS) @@ -430,6 +432,7 @@ &groupMembers, &i, pGroupMembersBufferSize, pGroupMembersBufferIsMalloced, + sd, buffer, buflen, depth, pKnownGroups); (*depth)--; @@ -456,6 +459,10 @@ for (valiter = uidValues; *valiter != NULL; valiter++) { size_t len = strlen (*valiter) + 1; + if (sd && sd->lsd_name_prefix) + len += strlen(sd->lsd_name_prefix); + if (sd && sd->lsd_name_suffix) + len += strlen(sd->lsd_name_suffix); if (*buflen < len) { stat = NSS_TRYAGAIN; @@ -465,7 +472,13 @@ *buffer += len; *buflen -= len; - memcpy (groupMembers[i++], *valiter, len); + groupMembers[i][0] = '\0'; + if (sd && sd->lsd_name_prefix) + strcat(groupMembers[i], sd->lsd_name_prefix); + strcat (groupMembers[i], *valiter); + if (sd && sd->lsd_name_suffix) + strcat(groupMembers[i], sd->lsd_name_suffix); + i++; } } @@ -567,7 +580,9 @@ static NSS_STATUS _nss_ldap_parse_gr (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, + ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct group *gr = (struct group *) result; char *gid; @@ -583,7 +598,7 @@ #endif /* RFC2307BIS */ stat = - _nss_ldap_assign_attrval (e, ATM (group, gidNumber), &gid, &buffer, + _nss_ldap_assign_attrval (e, ATM (group, gidNumber), 0, &gid, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; @@ -594,21 +609,21 @@ 10); stat = - _nss_ldap_getrdnvalue (e, ATM (group, cn), &gr->gr_name, &buffer, - &buflen); + _nss_ldap_getrdnvalue (e, ATM (group, cn), LF_NAME, &gr->gr_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_userpassword (e, ATM (group, userPassword), + _nss_ldap_assign_userpassword (e, ATM (group, userPassword), 0, &gr->gr_passwd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; #ifndef RFC2307BIS stat = - _nss_ldap_assign_attrvals (e, ATM (group, memberUid), NULL, - &gr->gr_mem, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (group, memberUid), 0, NULL, + &gr->gr_mem, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; #else @@ -620,8 +635,8 @@ stat = do_parse_group_members (e, &groupMembers, &groupMembersCount, &groupMembersBufferSize, - &groupMembersBufferIsMalloced, &buffer, - &buflen, &depth, &knownGroups); + &groupMembersBufferIsMalloced, + sd, &buffer, &buflen, &depth, &knownGroups); if (stat != NSS_SUCCESS) { if (groupMembersBufferIsMalloced) @@ -871,6 +886,7 @@ ent_context_t *ctx = NULL; static const char *no_attrs[] = { NULL }; const char *gidnumber_attrs[2]; + ldap_service_search_descriptor_t *sd; LA_INIT (a); #if defined(HAVE_NSS_H) || defined(HAVE_USERSEC_H) @@ -913,7 +929,7 @@ /* lookup the user's DN. */ stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getpwnam, LM_PASSWD, no_attrs, 1, - &res); + &res, &sd); if (stat == NSS_SUCCESS) { e = _nss_ldap_first_entry (res); diff -ur nss_ldap/ldap-grp.h --- nss_ldap/ldap-grp.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-grp.h 2005-11-11 15:55:59.000000000 -0500 @@ -26,6 +26,7 @@ static NSS_STATUS _nss_ldap_parse_gr (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-hosts.c --- nss_ldap/ldap-hosts.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-hosts.c 2005-11-11 17:27:48.000000000 -0500 @@ -75,9 +75,10 @@ static NSS_STATUS _nss_ldap_parse_hostv4 (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { - return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, + return _nss_ldap_parse_host (e, pvt, result, sd, buffer, buflen, AF_INET); } @@ -85,9 +86,10 @@ static NSS_STATUS _nss_ldap_parse_hostv6 (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { - return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, + return _nss_ldap_parse_host (e, pvt, result, sd, buffer, buflen, AF_INET6); } #endif @@ -95,7 +97,8 @@ static NSS_STATUS _nss_ldap_parse_host (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen, + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen, int af) { /* this code needs reviewing. XXX */ @@ -116,20 +119,20 @@ *addressbuf = *buffer = '\0'; - stat = _nss_ldap_assign_attrval (e, ATM (hosts, cn), &host->h_name, - &buffer, &buflen); + stat = _nss_ldap_assign_attrval (e, ATM (hosts, cn), 0, &host->h_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrvals (e, ATM (hosts, cn), host->h_name, - &host->h_aliases, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (hosts, cn), 0, host->h_name, + &host->h_aliases, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrvals (e, AT (ipHostNumber), NULL, &addresses, - &p_addressbuf, &addresslen, &addresscount); + _nss_ldap_assign_attrvals (e, AT (ipHostNumber), 0, NULL, &addresses, + sd, &p_addressbuf, &addresslen, &addresscount); if (stat != NSS_SUCCESS) return stat; if (addresscount == 0) diff -ur nss_ldap/ldap-hosts.h --- nss_ldap/ldap-hosts.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-hosts.h 2005-11-11 15:55:59.000000000 -0500 @@ -40,6 +40,7 @@ static NSS_STATUS _nss_ldap_parse_host (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen, int af); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-netgrp.c --- nss_ldap/ldap-netgrp.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-netgrp.c 2005-11-11 15:55:59.000000000 -0500 @@ -625,7 +625,8 @@ */ static NSS_STATUS do_parse_innetgr (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { ldap_innetgr_args_t *li_args = (ldap_innetgr_args_t *) result; int count; diff -ur nss_ldap/ldap-network.c --- nss_ldap/ldap-network.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-network.c 2005-11-11 17:01:06.000000000 -0500 @@ -74,7 +74,8 @@ static NSS_STATUS _nss_ldap_parse_net (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { char *tmp; @@ -89,13 +90,13 @@ /* IPv6 support ? XXX */ network->n_addrtype = AF_INET; - stat = _nss_ldap_assign_attrval (e, ATM (networks, cn), &network->n_name, - &buffer, &buflen); + stat = _nss_ldap_assign_attrval (e, ATM (networks, cn), 0, &network->n_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrval (e, AT (ipNetworkNumber), &tmp, &buffer, + _nss_ldap_assign_attrval (e, AT (ipNetworkNumber), 0, &tmp, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; @@ -113,8 +115,8 @@ #endif stat = - _nss_ldap_assign_attrvals (e, ATM (networks, cn), network->n_name, - &network->n_aliases, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (networks, cn), 0, network->n_name, + &network->n_aliases, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; diff -ur nss_ldap/ldap-network.h --- nss_ldap/ldap-network.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-network.h 2005-11-11 15:55:59.000000000 -0500 @@ -26,6 +26,7 @@ static NSS_STATUS _nss_ldap_parse_net (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); diff -ur nss_ldap/ldap-nss.c --- nss_ldap/ldap-nss.c 2005-11-11 17:59:22.000000000 -0500 +++ nss_ldap/ldap-nss.c 2005-11-11 17:53:07.000000000 -0500 @@ -239,14 +239,18 @@ * or exceptional condition. */ static NSS_STATUS do_parse (ent_context_t * ctx, void *result, char *buffer, - size_t buflen, int *errnop, parser_t parser); + size_t buflen, int *errnop, + ldap_service_search_descriptor_t *sd, + parser_t parser); /* * Parse a result, fetching results from the result chain * rather than the server. */ static NSS_STATUS do_parse_s (ent_context_t * ctx, void *result, char *buffer, - size_t buflen, int *errnop, parser_t parser); + size_t buflen, int *errnop, + ldap_service_search_descriptor_t *sd, + parser_t parser); /* * Function to be braced by reconnect harness. Used so we @@ -1785,7 +1789,7 @@ } \ else \ { \ - stat = _nss_ldap_escape_string((component), (escaped_##component), \ + stat = _nss_ldap_escape_string((component), -1, (escaped_##component), \ (sizeof((escaped_##component)))); \ if (stat != NSS_SUCCESS) \ return stat; \ @@ -1862,7 +1866,8 @@ { char buf1[LDAP_FILT_MAXSIZ], buf2[LDAP_FILT_MAXSIZ]; char *filterBufP, filterBuf[LDAP_FILT_MAXSIZ]; - size_t filterSiz; + const char *argStr; + size_t filterSiz, argLen, prefixLen, suffixLen; NSS_STATUS stat; debug ("==> do_filter"); @@ -1881,12 +1886,44 @@ filterBufP = userbuf; filterSiz = userbufSiz; } - + if ((sd != NULL) && (sd->lsd_name_prefix != NULL)) + prefixLen = strlen(sd->lsd_name_prefix); + else + prefixLen = 0; + if ((sd != NULL) && (sd->lsd_name_suffix != NULL)) + suffixLen = strlen(sd->lsd_name_suffix); + else + suffixLen = 0; switch (args->la_type) { case LA_TYPE_STRING: + argStr = args->la_arg1.la_string; + argLen = strlen(argStr); + if (prefixLen > 0) + { + if ((argLen > prefixLen) && + (strncmp(sd->lsd_name_prefix, argStr, prefixLen) == 0)) + { + argLen -= prefixLen; + argStr += prefixLen; + } +#if 1 + else + return NSS_STATUS_NOTFOUND; +#endif + } + if (suffixLen > 0) + { + if ((argLen > suffixLen) && + (strcmp(sd->lsd_name_suffix, argStr + argLen - suffixLen) == 0)) + argLen -= suffixLen; +#if 1 + else + return NSS_STATUS_NOTFOUND; +#endif + } if ((stat = - _nss_ldap_escape_string (args->la_arg1.la_string, buf1, + _nss_ldap_escape_string (argStr, argLen, buf1, sizeof (buf1))) != NSS_SUCCESS) return stat; snprintf (filterBufP, filterSiz, filterprot, buf1); @@ -1896,18 +1933,43 @@ args->la_arg1.la_number); break; case LA_TYPE_STRING_AND_STRING: + argStr = args->la_arg1.la_string; + argLen = strlen(argStr); + if (prefixLen > 0) + { + if ((argLen > prefixLen) && + (strcmp(sd->lsd_name_prefix, argStr + argLen - prefixLen) == 0)) + { + argLen -= prefixLen; + argStr += prefixLen; + } +#if 1 + else + return NSS_STATUS_NOTFOUND; +#endif + } + if (suffixLen > 0) + { + if ((argLen > suffixLen) && + (strcmp(sd->lsd_name_suffix, argStr + argLen - suffixLen) == 0)) + argLen -= suffixLen; +#if 1 + else + return NSS_STATUS_NOTFOUND; +#endif + } if ((stat = - _nss_ldap_escape_string (args->la_arg1.la_string, buf1, + _nss_ldap_escape_string (argStr, argLen, buf1, sizeof (buf1))) != NSS_SUCCESS || (stat = - _nss_ldap_escape_string (args->la_arg2.la_string, buf2, + _nss_ldap_escape_string (args->la_arg2.la_string, -1, buf2, sizeof (buf2)) != NSS_SUCCESS)) return stat; snprintf (filterBufP, filterSiz, filterprot, buf1, buf2); break; case LA_TYPE_NUMBER_AND_STRING: if ((stat = - _nss_ldap_escape_string (args->la_arg2.la_string, buf1, + _nss_ldap_escape_string (args->la_arg2.la_string, -1, buf1, sizeof (buf1))) != NSS_SUCCESS) return stat; snprintf (filterBufP, filterSiz, filterprot, @@ -2352,7 +2414,7 @@ */ static NSS_STATUS do_parse (ent_context_t * ctx, void *result, char *buffer, size_t buflen, - int *errnop, parser_t parser) + int *errnop, ldap_service_search_descriptor_t *sd, parser_t parser) { NSS_STATUS parseStat = NSS_NOTFOUND; @@ -2392,7 +2454,7 @@ * find one which is parseable, or exhaust avialable * entries, whichever is first. */ - parseStat = parser (ctx->ec_res, &ctx->ec_state, result, + parseStat = parser (ctx->ec_res, &ctx->ec_state, result, sd, buffer, buflen); /* hold onto the state if we're out of memory XXX */ @@ -2422,7 +2484,7 @@ */ static NSS_STATUS do_parse_s (ent_context_t * ctx, void *result, char *buffer, size_t buflen, - int *errnop, parser_t parser) + int *errnop, ldap_service_search_descriptor_t *sd, parser_t parser) { NSS_STATUS parseStat = NSS_NOTFOUND; LDAPMessage *e = NULL; @@ -2464,7 +2526,7 @@ * find one which is parseable, or exhaust avialable * entries, whichever is first. */ - parseStat = parser (e, &ctx->ec_state, result, buffer, buflen); + parseStat = parser (e, &ctx->ec_state, result, sd, buffer, buflen); /* hold onto the state if we're out of memory XXX */ ctx->ec_state.ls_retry = (parseStat == NSS_TRYAGAIN ? 1 : 0); @@ -2576,14 +2638,15 @@ const char *filterprot, ldap_map_selector_t sel, const char **user_attrs, - int sizelimit, LDAPMessage ** res) + int sizelimit, LDAPMessage ** res, + ldap_service_search_descriptor_t **res_sd) { char sdBase[LDAP_FILT_MAXSIZ], *base = NULL; char filterBuf[LDAP_FILT_MAXSIZ]; const char **attrs, *filter; int scope; NSS_STATUS stat; - ldap_service_search_descriptor_t *sd = NULL; + ldap_service_search_descriptor_t *sd = *res_sd = NULL; debug ("==> _nss_ldap_search_s"); @@ -2602,7 +2665,7 @@ if (sel < LM_NONE) { - sd = __session.ls_config->ldc_sds[sel]; + sd = *res_sd = __session.ls_config->ldc_sds[sel]; next: if (sd != NULL) { @@ -2644,7 +2707,7 @@ (stat == NSS_SUCCESS && ldap_first_entry (__session.ls_conn, *res) == NULL)) { - sd = sd->lsd_next; + sd = *res_sd = sd->lsd_next; goto next; } } @@ -2907,7 +2970,7 @@ (*ctx)->ec_msgid = msgid; } - stat = do_parse (*ctx, result, buffer, buflen, errnop, parser); + stat = do_parse (*ctx, result, buffer, buflen, errnop, (*ctx)->ec_sd, parser); #ifdef PAGE_RESULTS if (stat == NSS_NOTFOUND) @@ -2957,6 +3020,7 @@ { NSS_STATUS stat = NSS_NOTFOUND; ent_context_t ctx; + ldap_service_search_descriptor_t *sd; _nss_ldap_enter (); @@ -2967,7 +3031,7 @@ ctx.ec_cookie = NULL; #endif /* PAGE_RESULTS */ - stat = _nss_ldap_search_s (args, filterprot, sel, NULL, 1, &ctx.ec_res); + stat = _nss_ldap_search_s (args, filterprot, sel, NULL, 1, &ctx.ec_res, &sd); if (stat != NSS_SUCCESS) { _nss_ldap_leave (); @@ -2985,7 +3049,7 @@ ctx.ec_state.ls_type = LS_TYPE_KEY; ctx.ec_state.ls_info.ls_key = args->la_arg2.la_string; - stat = do_parse_s (&ctx, result, buffer, buflen, errnop, parser); + stat = do_parse_s (&ctx, result, buffer, buflen, errnop, sd, parser); _nss_ldap_ent_context_release (&ctx); @@ -3008,8 +3072,9 @@ NSS_STATUS _nss_ldap_assign_attrvals (LDAPMessage * e, const char *attr, + ldap_assignment_flags_t flags, const char *omitvalue, - char ***valptr, + char ***valptr, ldap_service_search_descriptor_t *sd, char **pbuffer, size_t * pbuflen, size_t * pvalcount) { @@ -3068,6 +3133,10 @@ else { vallen = strlen (*valiter); + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + vallen += strlen (sd->lsd_name_prefix); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + vallen += strlen (sd->lsd_name_suffix); if (buflen < (size_t) (vallen + 1)) { ldap_value_free (vals); @@ -3079,7 +3148,12 @@ buffer += vallen + 1; buflen -= vallen + 1; - strncpy (elt, *valiter, vallen); + *elt = '\0'; + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + strcat (elt, sd->lsd_name_prefix); + strcat (elt, *valiter); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + strcat (elt, sd->lsd_name_suffix); elt[vallen] = '\0'; *p = elt; p++; @@ -3104,7 +3178,9 @@ NSS_STATUS _nss_ldap_assign_attrval (LDAPMessage * e, const char *attr, - char **valptr, char **buffer, size_t * buflen) + ldap_assignment_flags_t flags, + char **valptr, ldap_service_search_descriptor_t *sd, + char **buffer, size_t * buflen) { char **vals; int vallen; @@ -3115,6 +3191,10 @@ if (ovr != NULL) { vallen = strlen (ovr); + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + vallen += strlen (sd->lsd_name_prefix); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + vallen += strlen (sd->lsd_name_suffix); if (*buflen < (size_t) (vallen + 1)) { return NSS_TRYAGAIN; @@ -3122,7 +3202,12 @@ *valptr = *buffer; - strncpy (*valptr, ovr, vallen); + **valptr = '\0'; + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + strcat (*valptr, sd->lsd_name_prefix); + strcat (*valptr, ovr); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + strcat (*valptr, sd->lsd_name_suffix); (*valptr)[vallen] = '\0'; *buffer += vallen + 1; @@ -3145,6 +3230,10 @@ if (def != NULL) { vallen = strlen (def); + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + vallen += strlen (sd->lsd_name_prefix); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + vallen += strlen (sd->lsd_name_suffix); if (*buflen < (size_t) (vallen + 1)) { return NSS_TRYAGAIN; @@ -3152,7 +3241,12 @@ *valptr = *buffer; - strncpy (*valptr, def, vallen); + **valptr = '\0'; + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + strcat (*valptr, sd->lsd_name_prefix); + strcat (*valptr, def); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + strcat (*valptr, sd->lsd_name_suffix); (*valptr)[vallen] = '\0'; *buffer += vallen + 1; @@ -3170,6 +3264,10 @@ #endif /* AT_OC_MAP */ vallen = strlen (*vals); + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + vallen += strlen (sd->lsd_name_prefix); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + vallen += strlen (sd->lsd_name_suffix); if (*buflen < (size_t) (vallen + 1)) { ldap_value_free (vals); @@ -3178,7 +3276,12 @@ *valptr = *buffer; - strncpy (*valptr, *vals, vallen); + **valptr = '\0'; + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + strcat (*valptr, sd->lsd_name_prefix); + strcat (*valptr, *vals); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + strcat (*valptr, sd->lsd_name_suffix); (*valptr)[vallen] = '\0'; *buffer += vallen + 1; @@ -3255,6 +3358,7 @@ NSS_STATUS _nss_ldap_assign_userpassword (LDAPMessage * e, const char *attr, + ldap_assignment_flags_t flags, char **valptr, char **buffer, size_t * buflen) { char **vals; @@ -3662,7 +3766,7 @@ _nss_ldap_enter (); stat = _nss_ldap_search_s (&args, _nss_ldap_filt_getpwnam, - LM_PASSWD, NULL, 1, &res); + LM_PASSWD, NULL, 1, &res, NULL); if (stat == NSS_SUCCESS) { e = _nss_ldap_first_entry (res); diff -ur nss_ldap/ldap-nss.h --- nss_ldap/ldap-nss.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-nss.h 2005-11-11 17:34:43.000000000 -0500 @@ -263,13 +263,17 @@ struct ldap_service_search_descriptor { /* search base, qualified */ - char *lsd_base; + char *lsd_base, **lsd_exploded_base; /* scope */ int lsd_scope; /* filter */ char *lsd_filter; - /* next */ - struct ldap_service_search_descriptor *lsd_next; + /* key prefix */ + char *lsd_name_prefix; + /* key suffix */ + char *lsd_name_suffix; + /* prev/next */ + struct ldap_service_search_descriptor *lsd_prev, *lsd_next; }; typedef struct ldap_service_search_descriptor @@ -434,6 +438,12 @@ typedef enum ldap_args_types ldap_args_types_t; +enum ldap_assignment_flags { + LF_NONE = 0, + LF_NAME = (1 << 0) +}; +typedef enum ldap_assignment_flags ldap_assignment_flags_t; + enum ldap_map_type { MAP_ATTRIBUTE = 0, @@ -606,6 +616,7 @@ #endif typedef NSS_STATUS (*parser_t) (LDAPMessage *, ldap_state_t *, void *, + struct ldap_service_search_descriptor *, char *, size_t); #ifdef HPUX @@ -733,7 +744,8 @@ ldap_map_selector_t sel, /* IN */ const char **user_attrs, /* IN */ int sizelimit, /* IN */ - LDAPMessage ** pRes /* OUT */ ); + LDAPMessage ** pRes, /* OUT */ + ldap_service_search_descriptor_t **pSD/* OUT */); /* * Asynchronous search cover (caller acquires lock). @@ -796,15 +808,19 @@ /* parsing utility functions */ NSS_STATUS _nss_ldap_assign_attrvals (LDAPMessage * e, /* IN */ const char *attr, /* IN */ + ldap_assignment_flags_t flags, /* IN */ const char *omitvalue, /* IN */ char ***valptr, /* OUT */ + ldap_service_search_descriptor_t *sd, /* IN */ char **buffer, /* IN/OUT */ size_t * buflen, /* IN/OUT */ size_t * pvalcount /* OUT */ ); NSS_STATUS _nss_ldap_assign_attrval (LDAPMessage * e, /* IN */ const char *attr, /* IN */ + ldap_assignment_flags_t flags, /* IN */ char **valptr, /* OUT */ + ldap_service_search_descriptor_t *sd, /* IN */ char **buffer, /* IN/OUT */ size_t * buflen /* IN/OUT */ ); @@ -813,6 +829,7 @@ NSS_STATUS _nss_ldap_assign_userpassword (LDAPMessage * e, /* IN */ const char *attr, /* IN */ + ldap_assignment_flags_t flags,/* IN */ char **valptr, /* OUT */ char **buffer, /* IN/OUT */ size_t * buflen); /* IN/OUT */ diff -ur nss_ldap/ldap-proto.c --- nss_ldap/ldap-proto.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-proto.c 2005-11-11 17:14:53.000000000 -0500 @@ -69,7 +69,8 @@ static NSS_STATUS _nss_ldap_parse_proto (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct protoent *proto = (struct protoent *) result; @@ -77,13 +78,13 @@ NSS_STATUS stat; stat = - _nss_ldap_getrdnvalue (e, ATM (protocols, cn), &proto->p_name, - &buffer, &buflen); + _nss_ldap_getrdnvalue (e, ATM (protocols, cn), 0, &proto->p_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrval (e, AT (ipProtocolNumber), &number, &buffer, + _nss_ldap_assign_attrval (e, AT (ipProtocolNumber), 0, &number, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; @@ -91,8 +92,8 @@ proto->p_proto = atoi (number); stat = - _nss_ldap_assign_attrvals (e, ATM (protocols, cn), proto->p_name, - &proto->p_aliases, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (protocols, cn), 0, proto->p_name, + &proto->p_aliases, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; diff -ur nss_ldap/ldap-proto.h --- nss_ldap/ldap-proto.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-proto.h 2005-11-11 15:55:59.000000000 -0500 @@ -33,6 +33,7 @@ static NSS_STATUS _nss_ldap_parse_proto (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-pwd.c --- nss_ldap/ldap-pwd.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-pwd.c 2005-11-11 17:11:34.000000000 -0500 @@ -81,7 +81,8 @@ static NSS_STATUS _nss_ldap_parse_pw (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct passwd *pw = (struct passwd *) result; char *uid, *gid; @@ -104,22 +105,22 @@ else { stat = - _nss_ldap_assign_userpassword (e, ATM (passwd, userPassword), + _nss_ldap_assign_userpassword (e, ATM (passwd, userPassword), 0, &pw->pw_passwd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; } stat = - _nss_ldap_assign_attrval (e, ATM (passwd, uid), &pw->pw_name, &buffer, - &buflen); + _nss_ldap_assign_attrval (e, ATM (passwd, uid), LF_NAME, &pw->pw_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; tmp = tmpbuf; tmplen = sizeof (tmpbuf); stat = - _nss_ldap_assign_attrval (e, AT (uidNumber), &uid, &tmp, &tmplen); + _nss_ldap_assign_attrval (e, AT (uidNumber), 0, &uid, sd, &tmp, &tmplen); if (stat != NSS_SUCCESS) return stat; pw->pw_uid = (*uid == '\0') ? UID_NOBODY : (uid_t) atol (uid); @@ -127,41 +128,41 @@ tmp = tmpbuf; tmplen = sizeof (tmpbuf); stat = - _nss_ldap_assign_attrval (e, ATM (passwd, gidNumber), &gid, &tmp, + _nss_ldap_assign_attrval (e, ATM (passwd, gidNumber), 0, &gid, sd, &tmp, &tmplen); if (stat != NSS_SUCCESS) return stat; pw->pw_gid = (*gid == '\0') ? GID_NOBODY : (gid_t) atol (gid); stat = - _nss_ldap_assign_attrval (e, AT (gecos), &pw->pw_gecos, &buffer, + _nss_ldap_assign_attrval (e, AT (gecos), 0, &pw->pw_gecos, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) { pw->pw_gecos = NULL; stat = - _nss_ldap_assign_attrval (e, ATM (passwd, cn), &pw->pw_gecos, + _nss_ldap_assign_attrval (e, ATM (passwd, cn), 0, &pw->pw_gecos, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; } stat = - _nss_ldap_assign_attrval (e, AT (homeDirectory), &pw->pw_dir, &buffer, - &buflen); + _nss_ldap_assign_attrval (e, AT (homeDirectory), 0, &pw->pw_dir, sd, + &buffer, &buflen); if (stat != NSS_SUCCESS) (void) _nss_ldap_assign_emptystring (&pw->pw_dir, &buffer, &buflen); stat = - _nss_ldap_assign_attrval (e, AT (loginShell), &pw->pw_shell, &buffer, + _nss_ldap_assign_attrval (e, AT (loginShell), 0, &pw->pw_shell, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) (void) _nss_ldap_assign_emptystring (&pw->pw_shell, &buffer, &buflen); #ifdef HAVE_NSSWITCH_H stat = - _nss_ldap_assign_attrval (e, ATM (passwd, description), - &pw->pw_comment, &buffer, &buflen); + _nss_ldap_assign_attrval (e, ATM (passwd, description), 0, + &pw->pw_comment, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) { /* @@ -169,7 +170,7 @@ */ pw->pw_comment = pw->pw_gecos; } - (void) _nss_ldap_assign_emptystring (&pw->pw_age, &buffer, &buflen); + (void) _nss_ldap_assign_emptystring (&pw->pw_age, sd, &buffer, &buflen); #endif /* HAVE_NSSWITCH_H */ return NSS_SUCCESS; diff -ur nss_ldap/ldap-pwd.h --- nss_ldap/ldap-pwd.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-pwd.h 2005-11-11 15:55:59.000000000 -0500 @@ -26,6 +26,7 @@ static NSS_STATUS _nss_ldap_parse_pw (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-rpc.c --- nss_ldap/ldap-rpc.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-rpc.c 2005-11-11 17:14:45.000000000 -0500 @@ -76,7 +76,8 @@ static NSS_STATUS _nss_ldap_parse_rpc (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct rpcent *rpc = (struct rpcent *) result; @@ -84,13 +85,13 @@ NSS_STATUS stat; stat = - _nss_ldap_getrdnvalue (e, ATM (rpc, cn), &rpc->r_name, &buffer, - &buflen); + _nss_ldap_getrdnvalue (e, ATM (rpc, cn), 0, &rpc->r_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrval (e, AT (oncRpcNumber), &number, &buffer, + _nss_ldap_assign_attrval (e, AT (oncRpcNumber), 0, &number, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; @@ -98,8 +99,8 @@ rpc->r_number = atol (number); stat = - _nss_ldap_assign_attrvals (e, ATM (rpc, cn), rpc->r_name, - &rpc->r_aliases, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (rpc, cn), 0, rpc->r_name, + &rpc->r_aliases, sd, &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) return stat; diff -ur nss_ldap/ldap-rpc.h --- nss_ldap/ldap-rpc.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-rpc.h 2005-11-11 15:55:59.000000000 -0500 @@ -33,6 +33,7 @@ static NSS_STATUS _nss_ldap_parse_rpc (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #endif diff -ur nss_ldap/ldap-service.c --- nss_ldap/ldap-service.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-service.c 2005-11-11 17:15:12.000000000 -0500 @@ -74,7 +74,8 @@ static NSS_STATUS _nss_ldap_parse_serv (LDAPMessage * e, ldap_state_t * state, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct servent *service = (struct servent *) result; char *port; @@ -91,8 +92,8 @@ { /* non-deterministic behaviour is ok */ stat = - _nss_ldap_assign_attrval (e, AT (ipServiceProtocol), - &service->s_proto, &buffer, &buflen); + _nss_ldap_assign_attrval (e, AT (ipServiceProtocol), 0, + &service->s_proto, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) { return stat; @@ -159,23 +160,24 @@ } stat = - _nss_ldap_getrdnvalue (e, ATM (services, cn), &service->s_name, - &buffer, &buflen); + _nss_ldap_getrdnvalue (e, ATM (services, cn), 0, &service->s_name, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) { return stat; } stat = - _nss_ldap_assign_attrvals (e, ATM (services, cn), service->s_name, - &service->s_aliases, &buffer, &buflen, NULL); + _nss_ldap_assign_attrvals (e, ATM (services, cn), 0, service->s_name, + &service->s_aliases, sd, + &buffer, &buflen, NULL); if (stat != NSS_SUCCESS) { return stat; } stat = - _nss_ldap_assign_attrval (e, AT (ipServicePort), &port, &buffer, + _nss_ldap_assign_attrval (e, AT (ipServicePort), 0, &port, sd, &buffer, &buflen); if (stat != NSS_SUCCESS) { diff -ur nss_ldap/ldap-service.h --- nss_ldap/ldap-service.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-service.h 2005-11-11 15:55:59.000000000 -0500 @@ -37,6 +37,7 @@ static NSS_STATUS _nss_ldap_parse_serv (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/ldap-spwd.c --- nss_ldap/ldap-spwd.c 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-spwd.c 2005-11-11 17:04:40.000000000 -0500 @@ -65,54 +65,56 @@ static NSS_STATUS _nss_ldap_parse_sp (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) + void *result, ldap_service_search_descriptor_t *sd, + char *buffer, size_t buflen) { struct spwd *sp = (struct spwd *) result; NSS_STATUS stat; char *tmp = NULL; stat = - _nss_ldap_assign_userpassword (e, ATM (shadow, userPassword), + _nss_ldap_assign_userpassword (e, ATM (shadow, userPassword), 0, &sp->sp_pwdp, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrval (e, ATM (shadow, uid), &sp->sp_namp, &buffer, - &buflen); + _nss_ldap_assign_attrval (e, ATM (shadow, uid), 0, &sp->sp_namp, + sd, &buffer, &buflen); if (stat != NSS_SUCCESS) return stat; stat = - _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, + _nss_ldap_assign_attrval (e, AT (shadowLastChange), 0, &tmp, sd, &buffer, &buflen); sp->sp_lstchg = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); + _nss_ldap_assign_attrval (e, AT (shadowMax), 0, &tmp, sd, &buffer, &buflen); sp->sp_max = (stat == NSS_SUCCESS) ? atol (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowMin), &tmp, &buffer, &buflen); + _nss_ldap_assign_attrval (e, AT (shadowMin), 0, &tmp, sd, &buffer, &buflen); sp->sp_min = (stat == NSS_SUCCESS) ? atol (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowWarning), &tmp, &buffer, + _nss_ldap_assign_attrval (e, AT (shadowWarning), 0, &tmp, sd, &buffer, &buflen); sp->sp_warn = (stat == NSS_SUCCESS) ? atol (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowInactive), &tmp, &buffer, + _nss_ldap_assign_attrval (e, AT (shadowInactive), 0, &tmp, sd, &buffer, &buflen); sp->sp_inact = (stat == NSS_SUCCESS) ? atol (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, + _nss_ldap_assign_attrval (e, AT (shadowExpire), 0, &tmp, sd, &buffer, &buflen); sp->sp_expire = (stat == NSS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; stat = - _nss_ldap_assign_attrval (e, AT (shadowFlag), &tmp, &buffer, &buflen); + _nss_ldap_assign_attrval (e, AT (shadowFlag), 0, &tmp, sd, + &buffer, &buflen); sp->sp_flag = (stat == NSS_SUCCESS) ? atol (tmp) : 0; _nss_ldap_shadow_handle_flag(sp); diff -ur nss_ldap/ldap-spwd.h --- nss_ldap/ldap-spwd.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/ldap-spwd.h 2005-11-11 15:55:59.000000000 -0500 @@ -26,6 +26,7 @@ static NSS_STATUS _nss_ldap_parse_sp (LDAPMessage * e, ldap_state_t * pvt, void *result, + ldap_service_search_descriptor_t *sd, char *buffer, size_t buflen); #ifdef HAVE_NSSWITCH_H diff -ur nss_ldap/util.c --- nss_ldap/util.c 2005-11-11 17:59:22.000000000 -0500 +++ nss_ldap/util.c 2005-11-11 17:55:23.000000000 -0500 @@ -60,8 +60,10 @@ static NSS_STATUS do_getrdnvalue (const char *dn, const char *rdntype, - char **rval, char **buffer, - size_t * buflen); + ldap_assignment_flags_t flags, + char **rval, + ldap_service_search_descriptor_t *sd, + char **buffer, size_t * buflen); #ifdef AT_OC_MAP @@ -161,8 +163,49 @@ static int lock_inited = 0; #endif +static ldap_service_search_descriptor_t * +find_matching_sd(ldap_service_search_descriptor_t *sd, const char *dn) +{ + int dn_size, base_size, i, depth; + char **exploded_dn; + if (sd == NULL) + return NULL; + while (sd->lsd_prev != NULL) + sd = sd->lsd_prev; + exploded_dn = ldap_explode_dn(dn, 0); + dn_size = 0; + if (exploded_dn != NULL) + for (dn_size = 0; exploded_dn[dn_size] != NULL; dn_size++) + continue; + while (sd != NULL) + { + base_size = 0; + if (sd->lsd_exploded_base != NULL) + for (base_size = 0; sd->lsd_exploded_base[base_size] != NULL; base_size++) + continue; + depth = dn_size - base_size; + if (depth >= 0) + { + for (i = 0; i < base_size; i++) + if (strcmp(sd->lsd_exploded_base[i], exploded_dn[i + depth]) != 0) + break; /* FIXME: strcmp() *can't* be right */ + if (i == base_size) + { + ldap_value_free (exploded_dn); + return sd; + } + } + sd = sd->lsd_next; + } + ldap_value_free (exploded_dn); + return NULL; +} + NSS_STATUS -_nss_ldap_dn2uid (const char *dn, char **uid, char **buffer, size_t * buflen, +_nss_ldap_dn2uid (const char *dn, char **uid, + ldap_service_search_descriptor_t *sd, + ldap_assignment_flags_t flags, + char **buffer, size_t * buflen, int *pIsNestedGroup, LDAPMessage ** pRes) { NSS_STATUS stat; @@ -205,7 +248,8 @@ } stat = - _nss_ldap_assign_attrval (e, ATM (passwd, uid), uid, + _nss_ldap_assign_attrval (e, ATM (passwd, uid), flags, uid, + find_matching_sd(sd, dn), buffer, buflen); if (stat == NSS_SUCCESS) dn2uid_cache_put (dn, *uid); @@ -223,7 +267,9 @@ NSS_STATUS _nss_ldap_getrdnvalue (LDAPMessage * entry, const char *rdntype, - char **rval, char **buffer, size_t * buflen) + ldap_assignment_flags_t flags, + char **rval, ldap_service_search_descriptor_t *sd, + char **buffer, size_t * buflen) { char *dn; NSS_STATUS status; @@ -234,7 +280,7 @@ return NSS_NOTFOUND; } - status = do_getrdnvalue (dn, rdntype, rval, buffer, buflen); + status = do_getrdnvalue (dn, rdntype, flags, rval, sd, buffer, buflen); #ifdef HAVE_LDAP_MEMFREE ldap_memfree (dn); #else @@ -278,8 +324,9 @@ static NSS_STATUS do_getrdnvalue (const char *dn, - const char *rdntype, - char **rval, char **buffer, size_t * buflen) + const char *rdntype, ldap_assignment_flags_t flags, + char **rval, ldap_service_search_descriptor_t *sd, + char **buffer, size_t * buflen) { char **exploded_dn; char *rdnvalue = NULL; @@ -316,6 +363,10 @@ char *r = *p + rdnavalen; rdnlen = strlen (r); + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + rdnlen += strlen(sd->lsd_name_prefix); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + rdnlen += strlen(sd->lsd_name_suffix); if (*buflen <= rdnlen) { ldap_value_free (exploded_rdn); @@ -323,7 +374,12 @@ return NSS_TRYAGAIN; } rdnvalue = *buffer; - strncpy (rdnvalue, r, rdnlen); + *rdnvalue = '\0'; + if ((flags & LF_NAME) && sd && sd->lsd_name_prefix) + strcat (rdnvalue, sd->lsd_name_prefix); + strcat (rdnvalue, r); + if ((flags & LF_NAME) && sd && sd->lsd_name_suffix) + strcat (rdnvalue, sd->lsd_name_suffix); break; } } @@ -416,11 +472,15 @@ ldap_service_search_descriptor_t **t, *cur; char *base; char *filter, *s; + char *scope_str, *filter_str, *other_args; int scope; t = NULL; filter = NULL; scope = -1; + other_args = NULL; + filter_str = NULL; + scope_str = NULL; if (!strcasecmp (key, NSS_LDAP_KEY_NSS_BASE_PASSWD)) t = &result[LM_PASSWD]; @@ -464,24 +524,37 @@ *buflen -= len + 1; /* probably is some funky escaping needed here. later... */ - s = strchr (base, '?'); - if (s != NULL) + scope_str = strchr (base, '?'); + filter_str = NULL; + other_args = NULL; + if (scope_str != NULL) + { + *scope_str = '\0'; + scope_str++; + filter_str = strchr (scope_str, '?'); + if (filter_str != NULL) + { + *filter_str = '\0'; + filter_str++; + other_args = strchr (filter_str, '?'); + if (other_args != NULL) + { + *other_args = '\0'; + other_args++; + } + } + } + if (scope_str != NULL) { - *s = '\0'; - s++; - if (!strcasecmp (s, "sub")) + if (!strcasecmp (scope_str, "sub")) scope = LDAP_SCOPE_SUBTREE; - else if (!strcasecmp (s, "one")) + else if (!strcasecmp (scope_str, "one")) scope = LDAP_SCOPE_ONELEVEL; - else if (!strcasecmp (s, "base")) + else if (!strcasecmp (scope_str, "base")) scope = LDAP_SCOPE_BASE; - filter = strchr (s, '?'); - if (filter != NULL) - { - *filter = '\0'; - filter++; - } } + if ((filter_str != NULL) && (strlen(filter_str) > 0)) + filter = filter_str; if (bytesleft (*buffer, *buflen, ldap_service_search_descriptor_t) < sizeof (ldap_service_search_descriptor_t)) @@ -498,14 +571,53 @@ else { cur->lsd_next = (ldap_service_search_descriptor_t *) * buffer; + cur->lsd_next->lsd_prev = cur; cur = cur->lsd_next; } cur->lsd_base = base; + cur->lsd_exploded_base = ldap_explode_dn (base, 0); cur->lsd_scope = scope; cur->lsd_filter = filter; + cur->lsd_name_prefix = NULL; + cur->lsd_name_suffix = NULL; cur->lsd_next = NULL; + /* treat everything that's left as a semicolon(";")-separated list of + * key-value pairs */ + if ((other_args != NULL) && (strlen(other_args) > 0)) + { + char *k, *v, *t; + s = other_args; + do + { + t = strchr(s, ';'); + if (t != NULL) + { + *t = '\0'; + t++; + } + k = s; + v = strchr(s, '='); + if (v != NULL) + { + *v = '\0'; + v++; + } + if (strcasecmp(k, "name_prefix") == 0) + cur->lsd_name_prefix = v; + else if (strcasecmp(k, "name_suffix") == 0) + cur->lsd_name_suffix = v; +#if 0 + else if (strcasecmp(k, NSS_LDAP_KEY_BINDDN) == 0) + cur->lsd_binddn = v; + else if (strcasecmp(k, NSS_LDAP_KEY_BINDPW) == 0) + cur->lsd_bindpw = v; +#endif + s = t; + } while ((s != NULL) && (*s != '\0')); + } + *buffer += sizeof (ldap_service_search_descriptor_t); *buflen -= sizeof (ldap_service_search_descriptor_t); @@ -955,14 +1067,15 @@ } NSS_STATUS -_nss_ldap_escape_string (const char *str, char *buf, size_t buflen) +_nss_ldap_escape_string (const char *str, ssize_t slen, + char *buf, size_t buflen) { int ret = NSS_TRYAGAIN; char *p = buf; char *limit = p + buflen - 3; const char *s = str; - while (p < limit && *s) + while (p < limit && ((slen == -1) || (s - str < slen)) && *s) { switch (*s) { @@ -989,7 +1102,7 @@ s++; } - if (*s == '\0') + if ((*s == '\0') || (slen != -1)) { /* got to end */ *p = '\0'; diff -ur nss_ldap/util.h --- nss_ldap/util.h 2004-09-27 22:20:11.000000000 -0400 +++ nss_ldap/util.h 2005-11-11 17:21:52.000000000 -0500 @@ -37,14 +37,19 @@ */ NSS_STATUS _nss_ldap_getrdnvalue (LDAPMessage * entry, const char *rdntype, - char **rval, char **buf, size_t * len); + ldap_assignment_flags_t flags, + char **rval, + ldap_service_search_descriptor_t *sd, + char **buf, size_t * len); #ifdef RFC2307BIS /* * map a distinguished name to a login name, or group entry */ NSS_STATUS _nss_ldap_dn2uid (const char *dn, - char **uid, char **buf, size_t * len, + char **uid, ldap_service_search_descriptor_t *sd, + ldap_assignment_flags_t flags, + char **buf, size_t * len, int *pIsNestedGroup, LDAPMessage ** pRes); #endif /* RFC2307BIS */ @@ -127,7 +132,7 @@ * Escape '*' in a string for use as a filter */ -NSS_STATUS _nss_ldap_escape_string (const char *str, +NSS_STATUS _nss_ldap_escape_string (const char *str, ssize_t slen, char *buf, size_t buflen); #define MAP_H_ERRNO(nss_status, herr) do { \