diff options
Diffstat (limited to 'nis')
-rw-r--r-- | nis/Makefile | 2 | ||||
-rw-r--r-- | nis/nss_nis/nis-publickey.c | 234 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-publickey.c | 411 |
3 files changed, 1 insertions, 646 deletions
diff --git a/nis/Makefile b/nis/Makefile index 6ce2199..9ad5e1d 100644 --- a/nis/Makefile +++ b/nis/Makefile @@ -36,7 +36,7 @@ headers := $(wildcard rpcsvc/*.[hx]) # These are the databases available for the nis (and perhaps later nisplus) # service. This must be a superset of the services in nss. databases = proto service hosts network grp pwd rpc ethers \ - spwd netgrp alias publickey + spwd netgrp alias # Specify rules for the nss_* modules. services := nis nisplus diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c deleted file mode 100644 index adbc04b..0000000 --- a/nis/nss_nis/nis-publickey.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Copyright (C) 1996-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. - - 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 - <https://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <syslog.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include <rpc/key_prot.h> -#include <rpc/des_crypt.h> - -#include "nss-nis.h" - -/* If we haven't found the entry, we give a SUCCESS and an empty key back. - Solaris docu says: sizeof (pkey) == HEXKEYBYTES + 1. -*/ -enum nss_status -_nss_nis_getpublickey (const char *netname, char *pkey, int *errnop) -{ - pkey[0] = 0; - - if (netname == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - ++domain; - - char *result; - int len; - int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname), - &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (result != NULL) - { - char *p = strchr (result, ':'); - if (p != NULL) - *p = 0; - strncpy (pkey, result, HEXKEYBYTES + 1); - pkey[HEXKEYBYTES] = '\0'; - free (result); - } - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd, - int *errnop) -{ - skey[0] = 0; - - if (netname == NULL || passwd == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - ++domain; - - char *result; - int len; - int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname), - &result, &len); - - if (__glibc_unlikely (yperr != YPERR_SUCCESS)) - { - enum nss_status retval = yperr2nss (yperr); - - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } - - if (result != NULL) - { - char *p = strchr (result, ':'); - if (p != NULL) - { - char buf[2 * (HEXKEYBYTES + 1)]; - - ++p; - strncpy (buf, p, 2 * (HEXKEYBYTES + 1)); - buf[2 * HEXKEYBYTES + 1] = '\0'; - if (xdecrypt (buf, passwd) - && memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) == 0) - { - buf[HEXKEYBYTES] = '\0'; - strcpy (skey, buf); - } - } - - free (result); - } - return NSS_STATUS_SUCCESS; -} - -/* Parse uid and group information from the passed string. - The format of the string passed is uid:gid,grp,grp, ... */ -static enum nss_status -parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp, - gid_t *gidlist) -{ - char *p, *ep; - int gidlen; - - if (!s || !isdigit (*s)) - { - syslog (LOG_ERR, "netname2user: expecting uid '%s'", s); - return NSS_STATUS_NOTFOUND; /* XXX need a better error */ - } - - /* Fetch the uid */ - *uidp = strtoul (s, NULL, 10); - - if (*uidp == 0) - { - syslog (LOG_ERR, "netname2user: should not have uid 0"); - return NSS_STATUS_NOTFOUND; - } - - /* Now get the group list */ - p = strchr (s, ':'); - if (!p) - { - syslog (LOG_ERR, "netname2user: missing group id list in '%s'", s); - return NSS_STATUS_NOTFOUND; - } - ++p; /* skip ':' */ - if (!p || (!isdigit (*p))) - { - syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", p); - return NSS_STATUS_NOTFOUND; - } - - *gidp = strtoul (p, &ep, 10); - - gidlen = 0; - - /* After strtoul() ep should point to the first invalid character. - This is the marker "," we search for the next value. */ - while (ep != NULL && *ep == ',') - { - ep++; - p = ep; - gidlist[gidlen++] = strtoul (p, &ep, 10); - } - - *gidlenp = gidlen; - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, - gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop) -{ - char *domain = strchr (netname, '@'); - if (domain == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - /* Point past the '@' character */ - ++domain; - char *lookup = NULL; - int len; - int yperr = yp_match (domain, "netid.byname", netname, strlen (netname), - &lookup, &len); - switch (yperr) - { - case YPERR_SUCCESS: - break; /* the successful case */ - case YPERR_DOMAIN: - case YPERR_KEY: - return NSS_STATUS_NOTFOUND; - case YPERR_MAP: - default: - return NSS_STATUS_UNAVAIL; - } - - if (lookup == NULL) - return NSS_STATUS_NOTFOUND; - - - lookup[len] = '\0'; - - enum nss_status err = parse_netid_str (lookup, uidp, gidp, gidlenp, gidlist); - - free (lookup); - - return err; -} diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c deleted file mode 100644 index ebbb3da..0000000 --- a/nis/nss_nisplus/nisplus-publickey.c +++ /dev/null @@ -1,411 +0,0 @@ -/* Copyright (c) 1997-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Thorsten Kukuk <kukuk@suse.de>, 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 - <https://www.gnu.org/licenses/>. */ - -#include <nss.h> -#include <ctype.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <libintl.h> -#include <syslog.h> -#include <rpc/rpc.h> -#include <rpcsvc/nis.h> -#include <rpc/key_prot.h> -extern int xdecrypt (char *, char *); - -#include <nss-nisplus.h> - -/* If we haven't found the entry, we give a SUCCESS and an empty key back. */ -enum nss_status -_nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop) -{ - nis_result *res; - enum nss_status retval; - char buf[NIS_MAXNAMELEN + 2]; - size_t slen; - char *domain, *cptr; - int len; - - pkey[0] = 0; - - if (netname == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - domain = strchr (netname, '@'); - if (!domain) - return NSS_STATUS_UNAVAIL; - domain++; - - slen = snprintf (buf, NIS_MAXNAMELEN, - "[auth_name=%s,auth_type=DES],cred.org_dir.%s", - netname, domain); - - if (slen >= NIS_MAXNAMELEN) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - if (buf[slen - 1] != '.') - { - buf[slen++] = '.'; - buf[slen] = '\0'; - } - - res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, - NULL, NULL); - - if (res == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - retval = niserr2nss (res->status); - - if (retval != NSS_STATUS_SUCCESS) - { - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - if (res->status == NIS_NOTFOUND) - retval = NSS_STATUS_SUCCESS; - nis_freeresult (res); - return retval; - } - - if (NIS_RES_NUMOBJ (res) > 1) - { - /* - * More than one principal with same uid? - * something wrong with cred table. Should be unique - * Warn user and continue. - */ - syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname); - nis_freeresult (res); - return NSS_STATUS_SUCCESS; - } - - len = ENTRY_LEN (NIS_RES_OBJECT (res), 3); - memcpy (pkey, ENTRY_VAL (NIS_RES_OBJECT (res),3), len); - pkey[len] = 0; - cptr = strchr (pkey, ':'); - if (cptr) - cptr[0] = '\0'; - nis_freeresult (res); - - return NSS_STATUS_SUCCESS; -} - - -enum nss_status -_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, - int *errnop) -{ - nis_result *res; - enum nss_status retval; - char buf[NIS_MAXNAMELEN + 2]; - size_t slen; - char *domain, *cptr; - int len; - - skey[0] = 0; - - if (netname == NULL) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - domain = strchr (netname, '@'); - if (!domain) - return NSS_STATUS_UNAVAIL; - domain++; - - slen = snprintf (buf, NIS_MAXNAMELEN, - "[auth_name=%s,auth_type=DES],cred.org_dir.%s", - netname, domain); - - if (slen >= NIS_MAXNAMELEN) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - if (buf[slen - 1] != '.') - { - buf[slen++] = '.'; - buf[slen] = '\0'; - } - - res = nis_list (buf, USE_DGRAM | NO_AUTHINFO | FOLLOW_LINKS | FOLLOW_PATH, - NULL, NULL); - - if (res == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - retval = niserr2nss (res->status); - - if (retval != NSS_STATUS_SUCCESS) - { - if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - nis_freeresult (res); - return retval; - } - - if (NIS_RES_NUMOBJ (res) > 1) - { - /* - * More than one principal with same uid? - * something wrong with cred table. Should be unique - * Warn user and continue. - */ - syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname); - nis_freeresult (res); - return NSS_STATUS_SUCCESS; - } - - len = ENTRY_LEN (NIS_RES_OBJECT (res), 4); - memcpy (buf, ENTRY_VAL (NIS_RES_OBJECT (res), 4), len); - buf[len] = '\0'; - cptr = strchr (buf, ':'); - if (cptr) - cptr[0] = '\0'; - nis_freeresult (res); - - if (!xdecrypt (buf, passwd)) - return NSS_STATUS_SUCCESS; - - if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0) - return NSS_STATUS_SUCCESS; - - buf[HEXKEYBYTES] = 0; - strcpy (skey, buf); - - return NSS_STATUS_SUCCESS; -} - - -/* Parse information from the passed string. - The format of the string passed is gid,grp,grp, ... */ -static enum nss_status -parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist, - int *errnop) -{ - char *ep; - int gidlen; - - if (!s || (!isdigit (*s))) - { - syslog (LOG_ERR, _("netname2user: missing group id list in `%s'"), s); - return NSS_STATUS_NOTFOUND; - } - - *gidp = strtoul (s, &ep, 10); - - gidlen = 0; - - /* After strtoul() ep should point to the marker ',', which means - here starts a new value. - - The Sun man pages show that GIDLIST should contain at least NGRPS - elements. Limiting the number written by this value is the best - we can do. */ - while (ep != NULL && *ep == ',' && gidlen < NGRPS) - { - ep++; - s = ep; - gidlist[gidlen++] = strtoul (s, &ep, 10); - } - *gidlenp = gidlen; - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, - gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop) -{ - char *domain; - nis_result *res; - char sname[NIS_MAXNAMELEN + 2]; /* search criteria + table name */ - size_t slen; - char principal[NIS_MAXNAMELEN + 1]; - int len; - - /* 1. Get home domain of user. */ - domain = strchr (netname, '@'); - if (! domain) - return NSS_STATUS_UNAVAIL; - - ++domain; /* skip '@' */ - - /* 2. Get user's nisplus principal name. */ - slen = snprintf (sname, NIS_MAXNAMELEN, - "[auth_name=%s,auth_type=DES],cred.org_dir.%s", - netname, domain); - - if (slen >= NIS_MAXNAMELEN) - { - *errnop = EINVAL; - return NSS_STATUS_UNAVAIL; - } - - if (sname[slen - 1] != '.') - { - sname[slen++] = '.'; - sname[slen] = '\0'; - } - - /* must use authenticated call here */ - /* XXX but we cant, for now. XXX */ - res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, - NULL, NULL); - if (res == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - switch (res->status) - { - case NIS_SUCCESS: - case NIS_S_SUCCESS: - break; /* go and do something useful */ - case NIS_NOTFOUND: - case NIS_PARTIAL: - case NIS_NOSUCHNAME: - case NIS_NOSUCHTABLE: - nis_freeresult (res); - return NSS_STATUS_NOTFOUND; - case NIS_S_NOTFOUND: - case NIS_TRYAGAIN: - syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"), - nis_sperrno (res->status)); - nis_freeresult (res); - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - default: - syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"), - nis_sperrno (res->status)); - nis_freeresult (res); - return NSS_STATUS_UNAVAIL; - } - - if (NIS_RES_NUMOBJ (res) > 1) - /* - * A netname belonging to more than one principal? - * Something wrong with cred table. should be unique. - * Warn user and continue. - */ - syslog (LOG_ALERT, - _("netname2user: DES entry for %s in directory %s not unique"), - netname, domain); - - len = ENTRY_LEN (NIS_RES_OBJECT (res), 0); - strncpy (principal, ENTRY_VAL (NIS_RES_OBJECT (res), 0), len); - principal[len] = '\0'; - nis_freeresult (res); - - if (principal[0] == '\0') - return NSS_STATUS_UNAVAIL; - - /* - * 3. Use principal name to look up uid/gid information in - * LOCAL entry in **local** cred table. - */ - domain = nis_local_directory (); - if (strlen (principal) + strlen (domain) + 45 > (size_t) NIS_MAXNAMELEN) - { - syslog (LOG_ERR, _("netname2user: principal name `%s' too long"), - principal); - return NSS_STATUS_UNAVAIL; - } - - slen = snprintf (sname, sizeof (sname), - "[cname=%s,auth_type=LOCAL],cred.org_dir.%s", - principal, domain); - - if (sname[slen - 1] != '.') - { - sname[slen++] = '.'; - sname[slen] = '\0'; - } - - /* must use authenticated call here */ - /* XXX but we cant, for now. XXX */ - res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, - NULL, NULL); - if (res == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - switch(res->status) - { - case NIS_NOTFOUND: - case NIS_PARTIAL: - case NIS_NOSUCHNAME: - case NIS_NOSUCHTABLE: - nis_freeresult (res); - return NSS_STATUS_NOTFOUND; - case NIS_S_NOTFOUND: - case NIS_TRYAGAIN: - syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"), - nis_sperrno (res->status)); - nis_freeresult (res); - *errnop = errno; - return NSS_STATUS_TRYAGAIN; - case NIS_SUCCESS: - case NIS_S_SUCCESS: - break; /* go and do something useful */ - default: - syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"), - nis_sperrno (res->status)); - nis_freeresult (res); - return NSS_STATUS_UNAVAIL; - } - - if (NIS_RES_NUMOBJ (res) > 1) - /* - * A principal can have more than one LOCAL entry? - * Something wrong with cred table. - * Warn user and continue. - */ - syslog (LOG_ALERT, - _("netname2user: LOCAL entry for %s in directory %s not unique"), - netname, domain); - /* Fetch the uid */ - *uidp = strtoul (ENTRY_VAL (NIS_RES_OBJECT (res), 2), NULL, 10); - - if (*uidp == 0) - { - syslog (LOG_ERR, _("netname2user: should not have uid 0")); - nis_freeresult (res); - return NSS_STATUS_NOTFOUND; - } - - parse_grp_str (ENTRY_VAL (NIS_RES_OBJECT (res), 3), - gidp, gidlenp, gidlist, errnop); - - nis_freeresult (res); - return NSS_STATUS_SUCCESS; -} |