netnamer.c revision 261046
1133808Spjd/*- 2133808Spjd * Copyright (c) 2009, Sun Microsystems, Inc. 3133808Spjd * All rights reserved. 4133808Spjd * 5133808Spjd * Redistribution and use in source and binary forms, with or without 6133808Spjd * modification, are permitted provided that the following conditions are met: 7133808Spjd * - Redistributions of source code must retain the above copyright notice, 8133808Spjd * this list of conditions and the following disclaimer. 9133808Spjd * - Redistributions in binary form must reproduce the above copyright notice, 10133808Spjd * this list of conditions and the following disclaimer in the documentation 11133808Spjd * and/or other materials provided with the distribution. 12133808Spjd * - Neither the name of Sun Microsystems, Inc. nor the names of its 13133808Spjd * contributors may be used to endorse or promote products derived 14133808Spjd * from this software without specific prior written permission. 15133808Spjd * 16133808Spjd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17133808Spjd * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18133808Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19133808Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20133808Spjd * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21133808Spjd * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22133808Spjd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23133808Spjd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24133808Spjd * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25133808Spjd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26133808Spjd * POSSIBILITY OF SUCH DAMAGE. 27133808Spjd */ 28133808Spjd 29133808Spjd#if defined(LIBC_SCCS) && !defined(lint) 30133808Spjdstatic char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; 31133808Spjd#endif 32133808Spjd#include <sys/cdefs.h> 33133808Spjd__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/netnamer.c 261046 2014-01-22 23:45:27Z mav $"); 34133808Spjd 35133808Spjd/* 36133808Spjd * netname utility routines convert from unix names to network names and 37133808Spjd * vice-versa This module is operating system dependent! What we define here 38133808Spjd * will work with any unix system that has adopted the sun NIS domain 39133808Spjd * architecture. 40133808Spjd */ 41133808Spjd#include "namespace.h" 42133808Spjd#include <sys/param.h> 43133808Spjd#include <rpc/rpc.h> 44133808Spjd#include <rpc/rpc_com.h> 45133808Spjd#ifdef YP 46133808Spjd#include <rpcsvc/yp_prot.h> 47133808Spjd#include <rpcsvc/ypclnt.h> 48133808Spjd#endif 49133808Spjd#include <ctype.h> 50133808Spjd#include <stdio.h> 51133808Spjd#include <grp.h> 52133808Spjd#include <pwd.h> 53133808Spjd#include <string.h> 54133808Spjd#include <stdlib.h> 55133808Spjd#include <unistd.h> 56133808Spjd#include "un-namespace.h" 57133808Spjd 58133808Spjdstatic char *OPSYS = "unix"; 59133808Spjd#ifdef YP 60133808Spjdstatic char *NETID = "netid.byname"; 61133808Spjd#endif 62133808Spjdstatic char *NETIDFILE = "/etc/netid"; 63133808Spjd 64133808Spjdstatic int getnetid( char *, char * ); 65133808Spjdstatic int _getgroups( char *, gid_t * ); 66133808Spjd 67133808Spjd/* 68133808Spjd * Convert network-name into unix credential 69133808Spjd */ 70133808Spjdint 71133808Spjdnetname2user(netname, uidp, gidp, gidlenp, gidlist) 72133808Spjd char netname[MAXNETNAMELEN + 1]; 73133808Spjd uid_t *uidp; 74133808Spjd gid_t *gidp; 75133808Spjd int *gidlenp; 76133808Spjd gid_t *gidlist; 77133808Spjd{ 78133808Spjd char *p; 79133808Spjd int gidlen; 80133808Spjd uid_t uid; 81133808Spjd long luid; 82133808Spjd struct passwd *pwd; 83133808Spjd char val[1024]; 84133808Spjd char *val1, *val2; 85133808Spjd char *domain; 86133808Spjd int vallen; 87133808Spjd int err; 88133808Spjd 89133808Spjd if (getnetid(netname, val)) { 90133808Spjd char *res = val; 91133808Spjd 92133808Spjd p = strsep(&res, ":"); 93133808Spjd if (p == NULL) 94133808Spjd return (0); 95133808Spjd *uidp = (uid_t) atol(p); 96134124Spjd p = strsep(&res, "\n,"); 97134168Spjd if (p == NULL) { 98134168Spjd return (0); 99134168Spjd } 100133808Spjd *gidp = (gid_t) atol(p); 101133808Spjd for (gidlen = 0; gidlen < NGRPS; gidlen++) { 102133808Spjd p = strsep(&res, "\n,"); 103133808Spjd if (p == NULL) 104133808Spjd break; 105133808Spjd gidlist[gidlen] = (gid_t) atol(p); 106133808Spjd } 107133808Spjd *gidlenp = gidlen; 108133808Spjd 109133808Spjd return (1); 110133808Spjd } 111133808Spjd val1 = strchr(netname, '.'); 112133808Spjd if (val1 == NULL) 113133808Spjd return (0); 114133808Spjd if (strncmp(netname, OPSYS, (val1-netname))) 115133808Spjd return (0); 116133808Spjd val1++; 117133808Spjd val2 = strchr(val1, '@'); 118133808Spjd if (val2 == NULL) 119133808Spjd return (0); 120133808Spjd vallen = val2 - val1; 121133808Spjd if (vallen > (1024 - 1)) 122133808Spjd vallen = 1024 - 1; 123133808Spjd (void) strncpy(val, val1, 1024); 124133808Spjd val[vallen] = 0; 125133808Spjd 126133808Spjd err = __rpc_get_default_domain(&domain); /* change to rpc */ 127133808Spjd if (err) 128133808Spjd return (0); 129133808Spjd 130133808Spjd if (strcmp(val2 + 1, domain)) 131133808Spjd return (0); /* wrong domain */ 132133808Spjd 133134124Spjd if (sscanf(val, "%ld", &luid) != 1) 134134124Spjd return (0); 135134124Spjd uid = luid; 136134124Spjd 137134124Spjd /* use initgroups method */ 138134124Spjd pwd = getpwuid(uid); 139134124Spjd if (pwd == NULL) 140134124Spjd return (0); 141134124Spjd *uidp = pwd->pw_uid; 142134124Spjd *gidp = pwd->pw_gid; 143134124Spjd *gidlenp = _getgroups(pwd->pw_name, gidlist); 144134124Spjd return (1); 145134124Spjd} 146134124Spjd 147134124Spjd/* 148134124Spjd * initgroups 149134168Spjd */ 150134168Spjd 151134168Spjdstatic int 152134168Spjd_getgroups(uname, groups) 153134168Spjd char *uname; 154134168Spjd gid_t groups[NGRPS]; 155134168Spjd{ 156134168Spjd gid_t ngroups = 0; 157134168Spjd struct group *grp; 158134168Spjd int i; 159134168Spjd int j; 160134168Spjd int filter; 161134168Spjd 162134168Spjd setgrent(); 163134168Spjd while ((grp = getgrent())) { 164134168Spjd for (i = 0; grp->gr_mem[i]; i++) 165134168Spjd if (!strcmp(grp->gr_mem[i], uname)) { 166134124Spjd if (ngroups == NGRPS) { 167134124Spjd#ifdef DEBUG 168134124Spjd fprintf(stderr, 169133808Spjd "initgroups: %s is in too many groups\n", uname); 170133808Spjd#endif 171133808Spjd goto toomany; 172133808Spjd } 173133808Spjd /* filter out duplicate group entries */ 174133808Spjd filter = 0; 175133808Spjd for (j = 0; j < ngroups; j++) 176133808Spjd if (groups[j] == grp->gr_gid) { 177133808Spjd filter++; 178134168Spjd break; 179134168Spjd } 180134168Spjd if (!filter) 181134168Spjd groups[ngroups++] = grp->gr_gid; 182134168Spjd } 183134168Spjd } 184134168Spjdtoomany: 185134124Spjd endgrent(); 186134124Spjd return (ngroups); 187134124Spjd} 188134124Spjd 189134124Spjd/* 190134124Spjd * Convert network-name to hostname 191134124Spjd */ 192134168Spjdint 193134168Spjdnetname2host(netname, hostname, hostlen) 194134168Spjd char netname[MAXNETNAMELEN + 1]; 195134168Spjd char *hostname; 196134168Spjd int hostlen; 197134168Spjd{ 198134168Spjd int err; 199133808Spjd char valbuf[1024]; 200133808Spjd char *val; 201133808Spjd char *val2; 202133808Spjd int vallen; 203133808Spjd char *domain; 204133808Spjd 205133808Spjd if (getnetid(netname, valbuf)) { 206133808Spjd val = valbuf; 207133808Spjd if ((*val == '0') && (val[1] == ':')) { 208133808Spjd (void) strncpy(hostname, val + 2, hostlen); 209133808Spjd return (1); 210133808Spjd } 211133808Spjd } 212133808Spjd val = strchr(netname, '.'); 213133808Spjd if (val == NULL) 214133808Spjd return (0); 215133808Spjd if (strncmp(netname, OPSYS, (val - netname))) 216133808Spjd return (0); 217133808Spjd val++; 218133808Spjd val2 = strchr(val, '@'); 219133808Spjd if (val2 == NULL) 220133808Spjd return (0); 221133808Spjd vallen = val2 - val; 222133808Spjd if (vallen > (hostlen - 1)) 223133808Spjd vallen = hostlen - 1; 224133808Spjd (void) strncpy(hostname, val, vallen); 225133808Spjd hostname[vallen] = 0; 226133808Spjd 227133808Spjd err = __rpc_get_default_domain(&domain); /* change to rpc */ 228133808Spjd if (err) 229133808Spjd return (0); 230133808Spjd 231133808Spjd if (strcmp(val2 + 1, domain)) 232133808Spjd return (0); /* wrong domain */ 233133808Spjd else 234133808Spjd return (1); 235133808Spjd} 236133808Spjd 237133808Spjd/* 238133808Spjd * reads the file /etc/netid looking for a + to optionally go to the 239133808Spjd * network information service. 240133808Spjd */ 241133808Spjdint 242133808Spjdgetnetid(key, ret) 243133808Spjd char *key, *ret; 244133808Spjd{ 245133808Spjd char buf[1024]; /* big enough */ 246133808Spjd char *res; 247133808Spjd char *mkey; 248133808Spjd char *mval; 249133808Spjd FILE *fd; 250133808Spjd#ifdef YP 251133808Spjd char *domain; 252133808Spjd int err; 253133808Spjd char *lookup; 254133808Spjd int len; 255133808Spjd#endif 256133808Spjd 257133808Spjd fd = fopen(NETIDFILE, "r"); 258133808Spjd if (fd == NULL) { 259133808Spjd#ifdef YP 260133808Spjd res = "+"; 261133808Spjd goto getnetidyp; 262133808Spjd#else 263133808Spjd return (0); 264133808Spjd#endif 265133808Spjd } 266133808Spjd for (;;) { 267133808Spjd if (fd == NULL) 268133808Spjd return (0); /* getnetidyp brings us here */ 269133808Spjd res = fgets(buf, sizeof(buf), fd); 270133808Spjd if (res == NULL) { 271133808Spjd fclose(fd); 272133808Spjd return (0); 273133808Spjd } 274133808Spjd if (res[0] == '#') 275133808Spjd continue; 276133808Spjd else if (res[0] == '+') { 277133808Spjd#ifdef YP 278133808Spjd getnetidyp: 279133808Spjd err = yp_get_default_domain(&domain); 280133808Spjd if (err) { 281133808Spjd continue; 282133808Spjd } 283133808Spjd lookup = NULL; 284133808Spjd err = yp_match(domain, NETID, key, 285133808Spjd strlen(key), &lookup, &len); 286133808Spjd if (err) { 287133808Spjd#ifdef DEBUG 288133808Spjd fprintf(stderr, "match failed error %d\n", err); 289133808Spjd#endif 290133808Spjd continue; 291133808Spjd } 292133808Spjd lookup[len] = 0; 293133808Spjd strcpy(ret, lookup); 294133808Spjd free(lookup); 295133808Spjd if (fd != NULL) 296133808Spjd fclose(fd); 297133808Spjd return (2); 298133808Spjd#else /* YP */ 299133808Spjd#ifdef DEBUG 300133808Spjd fprintf(stderr, 301133808Spjd"Bad record in %s '+' -- NIS not supported in this library copy\n", 302133808Spjd NETIDFILE); 303133808Spjd#endif 304133808Spjd continue; 305133808Spjd#endif /* YP */ 306133808Spjd } else { 307133808Spjd mkey = strsep(&res, "\t "); 308133808Spjd if (mkey == NULL) { 309133808Spjd fprintf(stderr, 310133808Spjd "Bad record in %s -- %s", NETIDFILE, buf); 311133808Spjd continue; 312133808Spjd } 313133808Spjd do { 314133808Spjd mval = strsep(&res, " \t#\n"); 315133808Spjd } while (mval != NULL && !*mval); 316133808Spjd if (mval == NULL) { 317133808Spjd fprintf(stderr, 318133808Spjd "Bad record in %s val problem - %s", NETIDFILE, buf); 319133808Spjd continue; 320133808Spjd } 321133808Spjd if (strcmp(mkey, key) == 0) { 322133808Spjd strcpy(ret, mval); 323133808Spjd fclose(fd); 324133808Spjd return (1); 325133808Spjd 326133808Spjd } 327133808Spjd } 328133808Spjd } 329133808Spjd} 330133808Spjd