diff options
Diffstat (limited to 'lib/libc/rpc/netnamer.c')
-rw-r--r-- | lib/libc/rpc/netnamer.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/lib/libc/rpc/netnamer.c b/lib/libc/rpc/netnamer.c new file mode 100644 index 0000000..772160a --- /dev/null +++ b/lib/libc/rpc/netnamer.c @@ -0,0 +1,331 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; +#endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * netname utility routines convert from unix names to network names and + * vice-versa This module is operating system dependent! What we define here + * will work with any unix system that has adopted the sun NIS domain + * architecture. + */ +#include "namespace.h" +#include <sys/param.h> +#include <rpc/rpc.h> +#include <rpc/rpc_com.h> +#ifdef YP +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#endif +#include <ctype.h> +#include <stdio.h> +#include <grp.h> +#include <pwd.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include "un-namespace.h" + +static char *OPSYS = "unix"; +#ifdef YP +static char *NETID = "netid.byname"; +#endif +static char *NETIDFILE = "/etc/netid"; + +static int getnetid( char *, char * ); +static int _getgroups( char *, gid_t * ); + +/* + * Convert network-name into unix credential + */ +int +netname2user(netname, uidp, gidp, gidlenp, gidlist) + char netname[MAXNETNAMELEN + 1]; + uid_t *uidp; + gid_t *gidp; + int *gidlenp; + gid_t *gidlist; +{ + char *p; + int gidlen; + uid_t uid; + long luid; + struct passwd *pwd; + char val[1024]; + char *val1, *val2; + char *domain; + int vallen; + int err; + + if (getnetid(netname, val)) { + char *res = val; + + p = strsep(&res, ":"); + if (p == NULL) + return (0); + *uidp = (uid_t) atol(p); + p = strsep(&res, "\n,"); + if (p == NULL) { + return (0); + } + *gidp = (gid_t) atol(p); + for (gidlen = 0; gidlen < NGRPS; gidlen++) { + p = strsep(&res, "\n,"); + if (p == NULL) + break; + gidlist[gidlen] = (gid_t) atol(p); + } + *gidlenp = gidlen; + + return (1); + } + val1 = strchr(netname, '.'); + if (val1 == NULL) + return (0); + if (strncmp(netname, OPSYS, (val1-netname))) + return (0); + val1++; + val2 = strchr(val1, '@'); + if (val2 == NULL) + return (0); + vallen = val2 - val1; + if (vallen > (1024 - 1)) + vallen = 1024 - 1; + (void) strncpy(val, val1, 1024); + val[vallen] = 0; + + err = __rpc_get_default_domain(&domain); /* change to rpc */ + if (err) + return (0); + + if (strcmp(val2 + 1, domain)) + return (0); /* wrong domain */ + + if (sscanf(val, "%ld", &luid) != 1) + return (0); + uid = luid; + + /* use initgroups method */ + pwd = getpwuid(uid); + if (pwd == NULL) + return (0); + *uidp = pwd->pw_uid; + *gidp = pwd->pw_gid; + *gidlenp = _getgroups(pwd->pw_name, gidlist); + return (1); +} + +/* + * initgroups + */ + +static int +_getgroups(uname, groups) + char *uname; + gid_t groups[NGRPS]; +{ + gid_t ngroups = 0; + struct group *grp; + int i; + int j; + int filter; + + setgrent(); + while ((grp = getgrent())) { + for (i = 0; grp->gr_mem[i]; i++) + if (!strcmp(grp->gr_mem[i], uname)) { + if (ngroups == NGRPS) { +#ifdef DEBUG + fprintf(stderr, + "initgroups: %s is in too many groups\n", uname); +#endif + goto toomany; + } + /* filter out duplicate group entries */ + filter = 0; + for (j = 0; j < ngroups; j++) + if (groups[j] == grp->gr_gid) { + filter++; + break; + } + if (!filter) + groups[ngroups++] = grp->gr_gid; + } + } +toomany: + endgrent(); + return (ngroups); +} + +/* + * Convert network-name to hostname + */ +int +netname2host(netname, hostname, hostlen) + char netname[MAXNETNAMELEN + 1]; + char *hostname; + int hostlen; +{ + int err; + char valbuf[1024]; + char *val; + char *val2; + int vallen; + char *domain; + + if (getnetid(netname, valbuf)) { + val = valbuf; + if ((*val == '0') && (val[1] == ':')) { + (void) strncpy(hostname, val + 2, hostlen); + return (1); + } + } + val = strchr(netname, '.'); + if (val == NULL) + return (0); + if (strncmp(netname, OPSYS, (val - netname))) + return (0); + val++; + val2 = strchr(val, '@'); + if (val2 == NULL) + return (0); + vallen = val2 - val; + if (vallen > (hostlen - 1)) + vallen = hostlen - 1; + (void) strncpy(hostname, val, vallen); + hostname[vallen] = 0; + + err = __rpc_get_default_domain(&domain); /* change to rpc */ + if (err) + return (0); + + if (strcmp(val2 + 1, domain)) + return (0); /* wrong domain */ + else + return (1); +} + +/* + * reads the file /etc/netid looking for a + to optionally go to the + * network information service. + */ +int +getnetid(key, ret) + char *key, *ret; +{ + char buf[1024]; /* big enough */ + char *res; + char *mkey; + char *mval; + FILE *fd; +#ifdef YP + char *domain; + int err; + char *lookup; + int len; +#endif + + fd = fopen(NETIDFILE, "r"); + if (fd == NULL) { +#ifdef YP + res = "+"; + goto getnetidyp; +#else + return (0); +#endif + } + for (;;) { + if (fd == NULL) + return (0); /* getnetidyp brings us here */ + res = fgets(buf, sizeof(buf), fd); + if (res == NULL) { + fclose(fd); + return (0); + } + if (res[0] == '#') + continue; + else if (res[0] == '+') { +#ifdef YP + getnetidyp: + err = yp_get_default_domain(&domain); + if (err) { + continue; + } + lookup = NULL; + err = yp_match(domain, NETID, key, + strlen(key), &lookup, &len); + if (err) { +#ifdef DEBUG + fprintf(stderr, "match failed error %d\n", err); +#endif + continue; + } + lookup[len] = 0; + strcpy(ret, lookup); + free(lookup); + if (fd != NULL) + fclose(fd); + return (2); +#else /* YP */ +#ifdef DEBUG + fprintf(stderr, +"Bad record in %s '+' -- NIS not supported in this library copy\n", + NETIDFILE); +#endif + continue; +#endif /* YP */ + } else { + mkey = strsep(&res, "\t "); + if (mkey == NULL) { + fprintf(stderr, + "Bad record in %s -- %s", NETIDFILE, buf); + continue; + } + do { + mval = strsep(&res, " \t#\n"); + } while (mval != NULL && !*mval); + if (mval == NULL) { + fprintf(stderr, + "Bad record in %s val problem - %s", NETIDFILE, buf); + continue; + } + if (strcmp(mkey, key) == 0) { + strcpy(ret, mval); + fclose(fd); + return (1); + + } + } + } +} |