diff options
Diffstat (limited to 'REORG.TODO/hesiod')
-rw-r--r-- | REORG.TODO/hesiod/Depend | 2 | ||||
-rw-r--r-- | REORG.TODO/hesiod/Makefile | 41 | ||||
-rw-r--r-- | REORG.TODO/hesiod/README.hesiod | 155 | ||||
-rw-r--r-- | REORG.TODO/hesiod/Versions | 14 | ||||
-rw-r--r-- | REORG.TODO/hesiod/hesiod.c | 443 | ||||
-rw-r--r-- | REORG.TODO/hesiod/hesiod.h | 50 | ||||
-rw-r--r-- | REORG.TODO/hesiod/hesiod_p.h | 56 | ||||
-rw-r--r-- | REORG.TODO/hesiod/nss_hesiod/hesiod-grp.c | 262 | ||||
-rw-r--r-- | REORG.TODO/hesiod/nss_hesiod/hesiod-proto.c | 142 | ||||
-rw-r--r-- | REORG.TODO/hesiod/nss_hesiod/hesiod-pwd.c | 110 | ||||
-rw-r--r-- | REORG.TODO/hesiod/nss_hesiod/hesiod-service.c | 145 |
11 files changed, 1420 insertions, 0 deletions
diff --git a/REORG.TODO/hesiod/Depend b/REORG.TODO/hesiod/Depend new file mode 100644 index 0000000000..0554b47da6 --- /dev/null +++ b/REORG.TODO/hesiod/Depend @@ -0,0 +1,2 @@ +nss +resolv diff --git a/REORG.TODO/hesiod/Makefile b/REORG.TODO/hesiod/Makefile new file mode 100644 index 0000000000..3c967441e1 --- /dev/null +++ b/REORG.TODO/hesiod/Makefile @@ -0,0 +1,41 @@ +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C 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 +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# +# Sub-makefile for hesiod portion of the library. +# +subdir := hesiod + +include ../Makeconfig + +extra-libs := libnss_hesiod +extra-libs-others = $(extra-libs) + +subdir-dirs = nss_hesiod +vpath %.c nss_hesiod + +libnss_hesiod-routines := hesiod hesiod-grp hesiod-proto \ + hesiod-pwd hesiod-service +# Build only shared library +libnss_hesiod-inhibit-o = $(filter-out .os,$(object-suffixes)) + +include ../Rules + +# The Hesiod NSS module also needs the resolver and some help from +# the file service. +$(objpfx)libnss_hesiod.so: $(common-objpfx)resolv/libresolv.so \ + $(common-objpfx)nss/libnss_files.so diff --git a/REORG.TODO/hesiod/README.hesiod b/REORG.TODO/hesiod/README.hesiod new file mode 100644 index 0000000000..259ce8d447 --- /dev/null +++ b/REORG.TODO/hesiod/README.hesiod @@ -0,0 +1,155 @@ +The GNU C library contains an NSS module for the Hesiod name service. +Hesiod is a general name service for a variety of applications and is +based on the Berkeley Internet Name Daemon (BIND). + +Introduction +============ + +The Hesiod NSS module implements access to all relevant standard +Hesiod types, which means that Hesiod can be used for the `group', +`passwd' and `services' databases. There is however a restriction. +In the same way that it is impossible to use `gethostent()' to iterate +over all the data provided by DNS, it is not possible to scan the +entire Hesiod database by means of `getgrent()', `getpwent()' and +`getservent()'. Besides, Hesiod only provides support for looking up +services by name and not for looking them up by port. In essence this +means that the Hesiod name service is only consulted as a result of +one of the following function calls: + + * getgrname(), getgrgid() + * getpwname(), getpwuid() + * getservbyname() + +and their reentrant counterparts. + + +Configuring your systems +======================== + +Configuring your systems to make use the Hesiod name service requires +one or more of the following steps, depending on whether you are +already running Hesiod in your network. + +Configuring NSS +--------------- + +First you should modify the file `/etc/nsswitch.conf' to tell +NSS for which database you want to use the Hesiod name service. If +you want to use Hesiod for all databases it can handle your +configuration file could look like this: + + # /etc/nsswitch.conf + # + # Example configuration of GNU Name Service Switch functionality. + # + + passwd: db files hesiod + group: db files hesiod + shadow: db files + + hosts: files dns + networks: files dns + + protocols: db files + services: db files hesiod + ethers: db files + rpc: db files + +For more information on NSS, please refer to the `The GNU C Library +Reference Manual'. + + +Configuring Hesiod +------------------ + +Next, you will have to configure Hesiod. If you are already running +Hesiod in your network, you probably already have a file named +`hesiod.conf' on your machines (probably as `/etc/hesiod.conf' or +`/usr/local/etc/hesiod.conf'). The Hesiod NSS module looks for +`/etc/hesiod.conf' by default. If there is no configuration file you +will want to create your own. It should look something like: + + rhs=.your.domain + lhs=.ns + classes=in,hs + +The optional classes settings specifies which DNS classes Hesiod +should do lookups in. Possible values are IN (the preferred class) +and HS (the deprecated class, still used by some sites). +You may specify both classes separated by a comma to try one class +first and then the other if no entry is available in the first +class. The default value of the classes variable is `IN,HS'. + +The value of rhs can be overridden by the environment variable +`HES_DOMAIN'. + +Configuring your name servers +----------------------------- + +In addition, if you are not already running Hesiod in your network, +you need to create Hesiod information on your central name servers. +You need to run `named' from BIND 4.9 or higher on these servers, and +make them authoritative for the domain `ns.your.domain' with a line in +`/etc/named.boot' reading something like: + + primary ns.your.domain named.hesiod + +or if you are using the new BIND 8.1 or higher add something to +`/etc/named.conf' like: + + zone "ns.your.domain" { + type master; + file "named.hesiod"; + }; + +Then in the BIND working directory (usually `/var/named') create the +file `named.hesiod' containing data that looks something like: + + ; SOA and NS records. + @ IN SOA server1.your.domain admin-address.your.domain ( + 40000 ; serial - database version number + 1800 ; refresh - sec servers + 300 ; retry - for refresh + 3600000 ; expire - unrefreshed data + 7200 ) ; min + NS server1.your.domain + NS server2.your.domain + + ; Actual Hesiod data. + libc.group TXT "libc:*:123:gnu,gnat" + 123.gid CNAME libc.group + gnu.passwd TXT "gnu:*:4567:123:GNU:/home/gnu:/bin/bash" + 456.uid CNAME mark.passwd + nss.service TXT "nss tcp 789 switch sw " + nss.service TXT "nss udp 789 switch sw" + +where `libc' is an example of a group, `gnu' an example of an user, +and `nss' an example of a service. Note that the format used to +describe services differs from the format used in `/etc/services'. +For more information on `named' refer to the `Name Server Operations +Guide for BIND' that is included in the BIND distribution. + + +Security +======== + +Note that the information stored in the Hesiod database in principle +is publicly available. Care should be taken with including vulnerable +information like encrypted passwords in the Hesiod database. There +are some ways to improve security by using features provided by +`named' (see the discussion about `secure zones' in the BIND +documentation), but one should keep in mind that Hesiod was never +intended to distribute passwords. In the origional design +authenticating users was the job of the Kerberos service. + + +More information +================ + +For more information on the Hesiod name service take a look at some of +the papers in ftp://athena-dist.mit.edu:/pub/ATHENA/usenix and the +documentation that accompanies the source code for the Hesiod name +service library in ftp://athena-dist.mit.edu:/pub/ATHENA/hesiod. + +There is a mailing list at MIT for Hesiod users, hesiod@mit.edu. To +get yourself on or off the list, send mail to hesiod-request@mit.edu. diff --git a/REORG.TODO/hesiod/Versions b/REORG.TODO/hesiod/Versions new file mode 100644 index 0000000000..1255b6825c --- /dev/null +++ b/REORG.TODO/hesiod/Versions @@ -0,0 +1,14 @@ +libnss_hesiod { + GLIBC_PRIVATE { + _nss_hesiod_setpwent; _nss_hesiod_endpwent; + _nss_hesiod_getpwnam_r; _nss_hesiod_getpwuid_r; + _nss_hesiod_setgrent; _nss_hesiod_endgrent; + _nss_hesiod_getgrnam_r; _nss_hesiod_getgrgid_r; + _nss_hesiod_setservent; _nss_hesiod_endservent; + _nss_hesiod_getservbyname_r; + _nss_hesiod_initgroups_dyn; + _nss_hesiod_getservbyport_r; + _nss_hesiod_setprotoent; _nss_hesiod_endprotoent; + _nss_hesiod_getprotobyname_r; _nss_hesiod_getprotobynumber_r; + } +} diff --git a/REORG.TODO/hesiod/hesiod.c b/REORG.TODO/hesiod/hesiod.c new file mode 100644 index 0000000000..9b54d1cb6b --- /dev/null +++ b/REORG.TODO/hesiod/hesiod.c @@ -0,0 +1,443 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>. + */ + +/* + * hesiod.c --- the core portion of the hesiod resolver. + * + * This file is derived from the hesiod library from Project Athena; + * It has been extensively rewritten by Theodore Ts'o to have a more + * thread-safe interface. + */ + +/* Imports */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> + +#include <errno.h> +#include <netdb.h> +#include <resolv.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "hesiod.h" +#include "hesiod_p.h" + +#define _PATH_HESIOD_CONF "/etc/hesiod.conf" + +/* Forward */ + +static int parse_config_file(struct hesiod_p *ctx, const char *filename); +static char ** get_txt_records(struct hesiod_p *ctx, int class, + const char *name); + +/* Public */ + +/* + * This function is called to initialize a hesiod_p. + */ +int +hesiod_init(void **context) { + struct hesiod_p *ctx; + const char *configname; + char *cp; + + ctx = malloc(sizeof(struct hesiod_p)); + if (ctx == 0) + return (-1); + + ctx->LHS = NULL; + ctx->RHS = NULL; + /* Set default query classes. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; + + configname = __libc_secure_getenv("HESIOD_CONFIG"); + if (!configname) + configname = _PATH_HESIOD_CONF; + if (parse_config_file(ctx, configname) < 0) { + goto cleanup; + } + /* + * The default RHS can be overridden by an environment + * variable. + */ + if ((cp = __libc_secure_getenv("HES_DOMAIN")) != NULL) { + free(ctx->RHS); + ctx->RHS = malloc(strlen(cp)+2); + if (!ctx->RHS) + goto cleanup; + if (cp[0] == '.') + strcpy(ctx->RHS, cp); + else { + ctx->RHS[0] = '.'; + strcpy(ctx->RHS + 1, cp); + } + } + + /* + * If there is no default hesiod realm set, we return an + * error. + */ + if (!ctx->RHS) { + __set_errno(ENOEXEC); + goto cleanup; + } + + *context = ctx; + return (0); + + cleanup: + hesiod_end(ctx); + return (-1); +} + +/* + * This function deallocates the hesiod_p + */ +void +hesiod_end(void *context) { + struct hesiod_p *ctx = (struct hesiod_p *) context; + int save_errno = errno; + + free(ctx->RHS); + free(ctx->LHS); + free(ctx); + __set_errno(save_errno); +} + +/* + * This function takes a hesiod (name, type) and returns a DNS + * name which is to be resolved. + */ +char * +hesiod_to_bind(void *context, const char *name, const char *type) { + struct hesiod_p *ctx = (struct hesiod_p *) context; + char *bindname; + char **rhs_list = NULL; + const char *RHS, *cp; + char *endp; + + /* Decide what our RHS is, and set cp to the end of the actual name. */ + if ((cp = strchr(name, '@')) != NULL) { + if (strchr(cp + 1, '.')) + RHS = cp + 1; + else if ((rhs_list = hesiod_resolve(context, cp + 1, + "rhs-extension")) != NULL) + RHS = *rhs_list; + else { + __set_errno(ENOENT); + return (NULL); + } + } else { + RHS = ctx->RHS; + cp = name + strlen(name); + } + + /* + * Allocate the space we need, including up to three periods and + * the terminating NUL. + */ + if ((bindname = malloc((cp - name) + strlen(type) + strlen(RHS) + + (ctx->LHS ? strlen(ctx->LHS) : 0) + 4)) == NULL) { + if (rhs_list) + hesiod_free_list(context, rhs_list); + return NULL; + } + + /* Now put together the DNS name. */ + endp = (char *) __mempcpy (bindname, name, cp - name); + *endp++ = '.'; + endp = (char *) __stpcpy (endp, type); + if (ctx->LHS) { + if (ctx->LHS[0] != '.') + *endp++ = '.'; + endp = __stpcpy (endp, ctx->LHS); + } + if (RHS[0] != '.') + *endp++ = '.'; + strcpy (endp, RHS); + + if (rhs_list) + hesiod_free_list(context, rhs_list); + + return (bindname); +} + +/* + * This is the core function. Given a hesiod (name, type), it + * returns an array of strings returned by the resolver. + */ +char ** +hesiod_resolve(void *context, const char *name, const char *type) { + struct hesiod_p *ctx = (struct hesiod_p *) context; + char *bindname = hesiod_to_bind(context, name, type); + char **retvec; + + if (bindname == NULL) + return (NULL); + + retvec = get_txt_records(ctx, ctx->classes[0], bindname); + + if (retvec == NULL && (errno == ENOENT || errno == ECONNREFUSED) && ctx->classes[1]) + retvec = get_txt_records(ctx, ctx->classes[1], bindname); + + + free(bindname); + return (retvec); +} + +void +hesiod_free_list(void *context, char **list) { + char **p; + + for (p = list; *p; p++) + free(*p); + free(list); +} + +/* + * This function parses the /etc/hesiod.conf file + */ +static int +parse_config_file(struct hesiod_p *ctx, const char *filename) { + char buf[MAXDNAME+7]; + FILE *fp; + + /* + * Clear the existing configuration variable, just in case + * they're set. + */ + free(ctx->RHS); + free(ctx->LHS); + ctx->RHS = ctx->LHS = 0; + /* Set default query classes. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; + + /* + * Now open and parse the file... + */ + if (!(fp = fopen(filename, "rce"))) + return (-1); + + while (fgets(buf, sizeof(buf), fp) != NULL) { + char *key, *data, *cp, **cpp; + + cp = buf; + if (*cp == '#' || *cp == '\n' || *cp == '\r') + continue; + while(*cp == ' ' || *cp == '\t') + cp++; + key = cp; + while(*cp != ' ' && *cp != '\t' && *cp != '=') + cp++; + *cp++ = '\0'; + + while(*cp == ' ' || *cp == '\t' || *cp == '=') + cp++; + data = cp; + while(*cp != ' ' && *cp != '\n' && *cp != '\r') + cp++; + *cp++ = '\0'; + + cpp = NULL; + if (strcasecmp(key, "lhs") == 0) + cpp = &ctx->LHS; + else if (strcasecmp(key, "rhs") == 0) + cpp = &ctx->RHS; + if (cpp) { + *cpp = strdup(data); + if (!*cpp) + goto cleanup; + } else if (strcasecmp(key, "classes") == 0) { + int n = 0; + while (*data && n < 2) { + cp = strchrnul(data, ','); + if (*cp != '\0') + *cp++ = '\0'; + if (strcasecmp(data, "IN") == 0) + ctx->classes[n++] = C_IN; + else if (strcasecmp(data, "HS") == 0) + ctx->classes[n++] = C_HS; + data = cp; + } + if (n == 0) { + /* Restore the default. Better than + nother at all. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; + } else if (n == 1 + || ctx->classes[0] == ctx->classes[1]) + ctx->classes[1] = 0; + } + } + fclose(fp); + return (0); + + cleanup: + fclose(fp); + free(ctx->RHS); + free(ctx->LHS); + ctx->RHS = ctx->LHS = 0; + return (-1); +} + +/* + * Given a DNS class and a DNS name, do a lookup for TXT records, and + * return a list of them. + */ +static char ** +get_txt_records(struct hesiod_p *ctx, int class, const char *name) { + struct { + int type; /* RR type */ + int class; /* RR class */ + int dlen; /* len of data section */ + u_char *data; /* pointer to data */ + } rr; + HEADER *hp; + u_char qbuf[MAX_HESRESP], abuf[MAX_HESRESP]; + u_char *cp, *erdata, *eom; + char *dst, *edst, **list; + int ancount, qdcount; + int i, j, n, skip; + + /* + * Construct the query and send it. + */ + n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0, + NULL, qbuf, MAX_HESRESP); + if (n < 0) { + __set_errno(EMSGSIZE); + return (NULL); + } + n = res_send(qbuf, n, abuf, MAX_HESRESP); + if (n < 0) { + __set_errno(ECONNREFUSED); + return (NULL); + } + if (n < HFIXEDSZ) { + __set_errno(EMSGSIZE); + return (NULL); + } + + /* + * OK, parse the result. + */ + hp = (HEADER *) abuf; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + cp = abuf + sizeof(HEADER); + eom = abuf + n; + + /* Skip query, trying to get to the answer section which follows. */ + for (i = 0; i < qdcount; i++) { + skip = dn_skipname(cp, eom); + if (skip < 0 || cp + skip + QFIXEDSZ > eom) { + __set_errno(EMSGSIZE); + return (NULL); + } + cp += skip + QFIXEDSZ; + } + + list = malloc((ancount + 1) * sizeof(char *)); + if (!list) + return (NULL); + j = 0; + for (i = 0; i < ancount; i++) { + skip = dn_skipname(cp, eom); + if (skip < 0) { + __set_errno(EMSGSIZE); + goto cleanup; + } + cp += skip; + if (cp + 3 * INT16SZ + INT32SZ > eom) { + __set_errno(EMSGSIZE); + goto cleanup; + } + rr.type = ns_get16(cp); + cp += INT16SZ; + rr.class = ns_get16(cp); + cp += INT16SZ + INT32SZ; /* skip the ttl, too */ + rr.dlen = ns_get16(cp); + cp += INT16SZ; + if (rr.dlen == 0 || cp + rr.dlen > eom) { + __set_errno(EMSGSIZE); + goto cleanup; + } + rr.data = cp; + cp += rr.dlen; + if (rr.class != class || rr.type != T_TXT) + continue; + if (!(list[j] = malloc(rr.dlen))) + goto cleanup; + dst = list[j++]; + edst = dst + rr.dlen; + erdata = rr.data + rr.dlen; + cp = rr.data; + while (cp < erdata) { + n = (unsigned char) *cp++; + if (cp + n > eom || dst + n > edst) { + __set_errno(EMSGSIZE); + goto cleanup; + } + memcpy(dst, cp, n); + cp += n; + dst += n; + } + if (cp != erdata) { + __set_errno(EMSGSIZE); + goto cleanup; + } + *dst = '\0'; + } + list[j] = NULL; + if (j == 0) { + __set_errno(ENOENT); + goto cleanup; + } + return (list); + + cleanup: + for (i = 0; i < j; i++) + free(list[i]); + free(list); + return (NULL); +} diff --git a/REORG.TODO/hesiod/hesiod.h b/REORG.TODO/hesiod/hesiod.h new file mode 100644 index 0000000000..2cb640a7df --- /dev/null +++ b/REORG.TODO/hesiod/hesiod.h @@ -0,0 +1,50 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>. + */ + +#ifndef _HESIOD_H_INCLUDED +#define _HESIOD_H_INCLUDED + +int hesiod_init (void **context) attribute_hidden; +void hesiod_end (void *context) attribute_hidden; +char * hesiod_to_bind (void *context, const char *name, + const char *type) attribute_hidden; +char ** hesiod_resolve (void *context, const char *name, + const char *type) attribute_hidden; +void hesiod_free_list (void *context, char **list) attribute_hidden; + +#endif /*_HESIOD_H_INCLUDED*/ diff --git a/REORG.TODO/hesiod/hesiod_p.h b/REORG.TODO/hesiod/hesiod_p.h new file mode 100644 index 0000000000..7ed70158d9 --- /dev/null +++ b/REORG.TODO/hesiod/hesiod_p.h @@ -0,0 +1,56 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>. + */ + +/* + * hesiod_p.h -- private definitions for the hesiod library + */ + +#ifndef _HESIOD_P_H_INCLUDED +#define _HESIOD_P_H_INCLUDED + +#define DEF_LHS ".ns" /* file is not */ + /* present. */ +struct hesiod_p { + char * LHS; /* normally ".ns" */ + char * RHS; /* AKA the default hesiod domain */ + int classes[2]; /* The class search order. */ +}; + +#define MAX_HESRESP 1024 + +#endif /*_HESIOD_P_H_INCLUDED*/ diff --git a/REORG.TODO/hesiod/nss_hesiod/hesiod-grp.c b/REORG.TODO/hesiod/nss_hesiod/hesiod-grp.c new file mode 100644 index 0000000000..a04f530945 --- /dev/null +++ b/REORG.TODO/hesiod/nss_hesiod/hesiod-grp.c @@ -0,0 +1,262 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <ctype.h> +#include <errno.h> +#include <grp.h> +#include <hesiod.h> +#include <nss.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> + +/* Get the declaration of the parser function. */ +#define ENTNAME grent +#define STRUCTURE group +#define EXTERN_PARSER +#include <nss/nss_files/files-parse.c> + +enum nss_status +_nss_hesiod_setgrent (int stayopen) +{ + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_endgrent (void) +{ + return NSS_STATUS_SUCCESS; +} + +static enum nss_status +lookup (const char *name, const char *type, struct group *grp, + char *buffer, size_t buflen, int *errnop) +{ + struct parser_data *data = (void *) buffer; + size_t linebuflen; + void *context; + char **list; + int parse_res; + size_t len; + int olderr = errno; + + if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); + if (list == NULL) + { + int err = errno; + hesiod_end (context); + __set_errno (olderr); + return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + + linebuflen = buffer + buflen - data->linebuffer; + len = strlen (*list) + 1; + if (linebuflen < len) + { + hesiod_free_list (context, list); + hesiod_end (context); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + memcpy (data->linebuffer, *list, len); + hesiod_free_list (context, list); + hesiod_end (context); + + parse_res = _nss_files_parse_grent (buffer, grp, data, buflen, errnop); + if (parse_res < 1) + { + __set_errno (olderr); + return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; + } + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_getgrnam_r (const char *name, struct group *grp, + char *buffer, size_t buflen, int *errnop) +{ + return lookup (name, "group", grp, buffer, buflen, errnop); +} + +enum nss_status +_nss_hesiod_getgrgid_r (gid_t gid, struct group *grp, + char *buffer, size_t buflen, int *errnop) +{ + char gidstr[21]; /* We will probably never have a gid_t with more + than 64 bits. */ + + snprintf (gidstr, sizeof gidstr, "%d", gid); + + return lookup (gidstr, "gid", grp, buffer, buflen, errnop); +} + +static int +internal_gid_in_list (const gid_t *list, const gid_t g, long int len) +{ + while (len > 0) + { + if (*list == g) + return 1; + --len; + ++list; + } + return 0; +} + +static enum nss_status +internal_gid_from_group (void *context, const char *groupname, gid_t *group) +{ + char **grp_res; + enum nss_status status = NSS_STATUS_NOTFOUND; + + grp_res = hesiod_resolve (context, groupname, "group"); + if (grp_res != NULL && *grp_res != NULL) + { + char *p = *grp_res; + + /* Skip to third field. */ + while (*p != '\0' && *p != ':') + ++p; + if (*p != '\0') + ++p; + while (*p != '\0' && *p != ':') + ++p; + if (*p != '\0') + { + char *endp; + char *q = ++p; + long int val; + + while (*q != '\0' && *q != ':') + ++q; + + val = strtol (p, &endp, 10); + if (sizeof (gid_t) == sizeof (long int) || (gid_t) val == val) + { + *group = val; + if (endp == q && endp != p) + status = NSS_STATUS_SUCCESS; + } + } + hesiod_free_list (context, grp_res); + } + return status; +} + +enum nss_status +_nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, + long int *size, gid_t **groupsp, long int limit, + int *errnop) +{ + enum nss_status status = NSS_STATUS_SUCCESS; + char **list = NULL; + char *p; + void *context; + gid_t *groups = *groupsp; + int save_errno; + + if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, user, "grplist"); + + if (list == NULL) + { + hesiod_end (context); + return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + + save_errno = errno; + + p = *list; + while (*p != '\0') + { + char *endp; + char *q; + long int val; + + status = NSS_STATUS_NOTFOUND; + + q = p; + while (*q != '\0' && *q != ':' && *q != ',') + ++q; + + if (*q != '\0') + *q++ = '\0'; + + __set_errno (0); + val = strtol (p, &endp, 10); + /* Test whether the number is representable in a variable of + type `gid_t'. If not ignore the number. */ + if ((sizeof (gid_t) == sizeof (long int) || (gid_t) val == val) + && errno == 0) + { + if (*endp == '\0' && endp != p) + { + group = val; + status = NSS_STATUS_SUCCESS; + } + else + status = internal_gid_from_group (context, p, &group); + + if (status == NSS_STATUS_SUCCESS + && !internal_gid_in_list (groups, group, *start)) + { + if (__glibc_unlikely (*start == *size)) + { + /* Need a bigger buffer. */ + gid_t *newgroups; + long int newsize; + + if (limit > 0 && *size == limit) + /* We reached the maximum. */ + goto done; + + if (limit <= 0) + newsize = 2 * *size; + else + newsize = MIN (limit, 2 * *size); + + newgroups = realloc (groups, newsize * sizeof (*groups)); + if (newgroups == NULL) + goto done; + *groupsp = groups = newgroups; + *size = newsize; + } + + groups[(*start)++] = group; + } + } + + p = q; + } + + __set_errno (save_errno); + + done: + hesiod_free_list (context, list); + hesiod_end (context); + + return NSS_STATUS_SUCCESS; +} diff --git a/REORG.TODO/hesiod/nss_hesiod/hesiod-proto.c b/REORG.TODO/hesiod/nss_hesiod/hesiod-proto.c new file mode 100644 index 0000000000..6af32aad35 --- /dev/null +++ b/REORG.TODO/hesiod/nss_hesiod/hesiod-proto.c @@ -0,0 +1,142 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <hesiod.h> +#include <netdb.h> +#include <netinet/in.h> +#include <nss.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Declare a parser for Hesiod protocol entries. Although the format + of the entries is identical to those in /etc/protocols, here is no + predefined parser for us to use. */ + +#define ENTNAME protoent + +struct protoent_data {}; + +#define TRAILING_LIST_MEMBER p_aliases +#define TRAILING_LIST_SEPARATOR_P isspace +#include <nss/nss_files/files-parse.c> +LINE_PARSER +("#", + STRING_FIELD (result->p_name, isspace, 1); + INT_FIELD (result->p_proto, isspace, 1, 10,); + ) + +enum nss_status +_nss_hesiod_setprotoent (int stayopen) +{ + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_endprotoent (void) +{ + return NSS_STATUS_SUCCESS; +} + +static enum nss_status +lookup (const char *name, const char *type, struct protoent *proto, + char *buffer, size_t buflen, int *errnop) +{ + struct parser_data *data = (void *) buffer; + size_t linebuflen; + void *context; + char **list, **item; + int parse_res; + int found; + int olderr = errno; + + if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); + if (list == NULL) + { + int err = errno; + hesiod_end (context); + __set_errno (olderr); + return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + + linebuflen = buffer + buflen - data->linebuffer; + + item = list; + found = 0; + do + { + size_t len = strlen (*item) + 1; + + if (linebuflen < len) + { + hesiod_free_list (context, list); + hesiod_end (context); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + memcpy (data->linebuffer, *item, len); + + parse_res = parse_line (buffer, proto, data, buflen, errnop); + if (parse_res == -1) + { + hesiod_free_list (context, list); + hesiod_end (context); + return NSS_STATUS_TRYAGAIN; + } + + if (parse_res > 0) + found = 1; + + ++item; + } + while (*item != NULL && !found); + + hesiod_free_list (context, list); + hesiod_end (context); + + if (found == 0) + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_getprotobyname_r (const char *name, struct protoent *proto, + char *buffer, size_t buflen, int *errnop) +{ + return lookup (name, "protocol", proto, buffer, buflen, errnop); +} + +enum nss_status +_nss_hesiod_getprotobynumber_r (const int protocol, struct protoent *proto, + char *buffer, size_t buflen, int *errnop) +{ + char protostr[21]; + + snprintf (protostr, sizeof protostr, "%d", protocol); + + return lookup (protostr, "protonum", proto, buffer, buflen, errnop); +} diff --git a/REORG.TODO/hesiod/nss_hesiod/hesiod-pwd.c b/REORG.TODO/hesiod/nss_hesiod/hesiod-pwd.c new file mode 100644 index 0000000000..8309af245d --- /dev/null +++ b/REORG.TODO/hesiod/nss_hesiod/hesiod-pwd.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <hesiod.h> +#include <pwd.h> +#include <nss.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Get the declaration of the parser function. */ +#define ENTNAME pwent +#define STRUCTURE passwd +#define EXTERN_PARSER +#include <nss/nss_files/files-parse.c> + +enum nss_status +_nss_hesiod_setpwent (int stayopen) +{ + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_endpwent (void) +{ + return NSS_STATUS_SUCCESS; +} + +static enum nss_status +lookup (const char *name, const char *type, struct passwd *pwd, + char *buffer, size_t buflen, int *errnop) +{ + struct parser_data *data = (void *) buffer; + size_t linebuflen; + void *context; + char **list; + int parse_res; + size_t len; + int olderr = errno; + + if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); + if (list == NULL) + { + int err = errno; + hesiod_end (context); + __set_errno (olderr); + return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + + linebuflen = buffer + buflen - data->linebuffer; + len = strlen (*list) + 1; + if (linebuflen < len) + { + hesiod_free_list (context, list); + hesiod_end (context); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + memcpy (data->linebuffer, *list, len); + hesiod_free_list (context, list); + hesiod_end (context); + + parse_res = _nss_files_parse_pwent (buffer, pwd, data, buflen, errnop); + if (parse_res < 1) + { + __set_errno (olderr); + return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; + } + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_getpwnam_r (const char *name, struct passwd *pwd, + char *buffer, size_t buflen, int *errnop) +{ + return lookup (name, "passwd", pwd, buffer, buflen, errnop); +} + +enum nss_status +_nss_hesiod_getpwuid_r (uid_t uid, struct passwd *pwd, + char *buffer, size_t buflen, int *errnop) +{ + char uidstr[21]; /* We will probably never have a gid_t with more + than 64 bits. */ + + snprintf (uidstr, sizeof uidstr, "%d", uid); + + return lookup (uidstr, "uid", pwd, buffer, buflen, errnop); +} diff --git a/REORG.TODO/hesiod/nss_hesiod/hesiod-service.c b/REORG.TODO/hesiod/nss_hesiod/hesiod-service.c new file mode 100644 index 0000000000..1942188517 --- /dev/null +++ b/REORG.TODO/hesiod/nss_hesiod/hesiod-service.c @@ -0,0 +1,145 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <hesiod.h> +#include <netdb.h> +#include <netinet/in.h> +#include <nss.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Hesiod uses a format for service entries that differs from the + traditional format. We therefore declare our own parser. */ + +#define ENTNAME servent + +struct servent_data {}; + +#define TRAILING_LIST_MEMBER s_aliases +#define TRAILING_LIST_SEPARATOR_P isspace +#include <nss/nss_files/files-parse.c> +#define ISSC_OR_SPACE(c) ((c) == ';' || isspace (c)) +LINE_PARSER +("#", + STRING_FIELD (result->s_name, ISSC_OR_SPACE, 1); + STRING_FIELD (result->s_proto, ISSC_OR_SPACE, 1); + INT_FIELD (result->s_port, ISSC_OR_SPACE, 10, 0, htons); + ) + +enum nss_status +_nss_hesiod_setservent (int stayopen) +{ + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_endservent (void) +{ + return NSS_STATUS_SUCCESS; +} + +static enum nss_status +lookup (const char *name, const char *type, const char *protocol, + struct servent *serv, char *buffer, size_t buflen, int *errnop) +{ + struct parser_data *data = (void *) buffer; + size_t linebuflen; + void *context; + char **list, **item; + int parse_res; + int found; + int olderr = errno; + + if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); + if (list == NULL) + { + int err = errno; + hesiod_end (context); + __set_errno (olderr); + return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + + linebuflen = buffer + buflen - data->linebuffer; + + item = list; + found = 0; + do + { + size_t len = strlen (*item) + 1; + + if (linebuflen < len) + { + hesiod_free_list (context, list); + hesiod_end (context); + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + memcpy (data->linebuffer, *item, len); + + parse_res = parse_line (buffer, serv, data, buflen, errnop); + if (parse_res == -1) + { + hesiod_free_list (context, list); + hesiod_end (context); + return NSS_STATUS_TRYAGAIN; + } + + if (parse_res > 0) + found = protocol == NULL || strcasecmp (serv->s_proto, protocol) == 0; + + ++item; + } + while (*item != NULL && !found); + + hesiod_free_list (context, list); + hesiod_end (context); + + if (found == 0) + { + __set_errno (olderr); + return NSS_STATUS_NOTFOUND; + } + + return NSS_STATUS_SUCCESS; +} + +enum nss_status +_nss_hesiod_getservbyname_r (const char *name, const char *protocol, + struct servent *serv, + char *buffer, size_t buflen, int *errnop) +{ + return lookup (name, "service", protocol, serv, buffer, buflen, errnop); +} + +enum nss_status +_nss_hesiod_getservbyport_r (const int port, const char *protocol, + struct servent *serv, + char *buffer, size_t buflen, int *errnop) +{ + char portstr[6]; /* Port numbers are restricted to 16 bits. */ + + snprintf (portstr, sizeof portstr, "%d", ntohs (port)); + + return lookup (portstr, "port", protocol, serv, buffer, buflen, errnop); +} |