diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-12-21 20:55:55 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-12-21 20:55:55 +0100 |
commit | fbc5ecfb8cf86d753b7c9a3b5b549a8f279666ab (patch) | |
tree | 5d008fb2963ef8a27da784ba851984f64678e6f0 /nslcd/dnsconfig.c | |
parent | 8366a3eb4a9032ca43cae9fccaa536182dcece04 (diff) |
rename server directory to nslcd
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@196 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd/dnsconfig.c')
-rw-r--r-- | nslcd/dnsconfig.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/nslcd/dnsconfig.c b/nslcd/dnsconfig.c new file mode 100644 index 0000000..12b0997 --- /dev/null +++ b/nslcd/dnsconfig.c @@ -0,0 +1,188 @@ +/* + dnsconfig.c - lookup code for DNS SRV records + This file was part of the nss_ldap library which has been + forked into the nss-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA +*/ + +/* + * Support DNS SRV records. I look up the SRV record for + * _ldap._tcp.gnu.org. + * and build the DN DC=gnu,DC=org. + * Thanks to Assar & co for resolve.[ch]. + */ + +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/param.h> +#include <netdb.h> +#include <syslog.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <string.h> +#ifdef HAVE_LBER_H +#include <lber.h> +#endif +#ifdef HAVE_LDAP_H +#include <ldap.h> +#endif + +#include "ldap-nss.h" +#include "util.h" +#include "resolve.h" +#include "dnsconfig.h" + +#define DC_ATTR "DC" +#define DC_ATTR_AVA DC_ATTR"=" +#define DC_ATTR_AVA_LEN (sizeof(DC_ATTR_AVA) - 1) + +/* map gnu.org into DC=gnu,DC=org */ +static enum nss_status +_nss_ldap_getdnsdn (char *src_domain, + char **rval, char **buffer, size_t * buflen) +{ + char *p; + int len = 0; +#ifdef HAVE_STRTOK_R + char *st = NULL; +#endif + char *bptr; + char *domain, *domain_copy; + + /* we need to take a copy of domain, because strtok() modifies + * it in place. Bad. + */ + domain_copy = strdup (src_domain); + if (domain_copy == NULL) + { + return NSS_STATUS_TRYAGAIN; + } + + domain = domain_copy; + + bptr = *rval = *buffer; + **rval = '\0'; + +#ifndef HAVE_STRTOK_R + while ((p = strtok (domain, "."))) +#else + while ((p = strtok_r (domain, ".", &st))) +#endif + { + len = strlen (p); + + if (*buflen < (size_t) (len + DC_ATTR_AVA_LEN + 1 /* D C = [,|\0] */ )) + { + free (domain_copy); + return NSS_STATUS_TRYAGAIN; + } + + if (domain == NULL) + { + strcpy (bptr, ","); + bptr++; + } + else + { + domain = NULL; + } + + strcpy (bptr, DC_ATTR_AVA); + bptr += DC_ATTR_AVA_LEN; + + strcpy (bptr, p); + bptr += len; /* don't include comma */ + *buffer += len + DC_ATTR_AVA_LEN + 1; + *buflen -= len + DC_ATTR_AVA_LEN + 1; + } + + if (bptr != NULL) + { + (*rval)[bptr - *rval] = '\0'; + } + + free (domain_copy); + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_ldap_mergeconfigfromdns (struct ldap_config * result, + char **buffer, size_t *buflen) +{ + enum nss_status stat = NSS_STATUS_SUCCESS; + struct dns_reply *r; + struct resource_record *rr; + char domain[MAXHOSTNAMELEN + 1]; + char *pDomain; + char uribuf[NSS_BUFSIZ]; + + if ((_res.options & RES_INIT) == 0 && res_init () == -1) + { + return NSS_STATUS_UNAVAIL; + } + + if (result->ldc_srv_domain != NULL) + pDomain = result->ldc_srv_domain; + else + { + snprintf (domain, sizeof (domain), "_ldap._tcp.%s.", _res.defdname); + pDomain = domain; + } + + r = dns_lookup (pDomain, "srv"); + if (r == NULL) + { + return NSS_STATUS_NOTFOUND; + } + + /* XXX sort by priority */ + for (rr = r->head; rr != NULL; rr = rr->next) + { + if (rr->type == T_SRV) + { + snprintf (uribuf, sizeof(uribuf), "ldap%s:%s:%d", + (rr->u.srv->port == LDAPS_PORT) ? "s" : "", + rr->u.srv->target, + rr->u.srv->port); + + stat = _nss_ldap_add_uri (result, uribuf, buffer, buflen); + if (stat != NSS_STATUS_SUCCESS) + { + break; + } + } + } + + dns_free_data (r); + stat = NSS_STATUS_SUCCESS; + + if (result->ldc_base == NULL) + { + stat = _nss_ldap_getdnsdn (_res.defdname, &result->ldc_base, + buffer, buflen); + } + + return stat; +} + |