1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 27*7c478bd9Sstevel@tonic-gate /* 28*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 29*7c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 30*7c478bd9Sstevel@tonic-gate * California. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * ==== hack-attack: possibly MT-safe but definitely not MT-hot. 34*7c478bd9Sstevel@tonic-gate * ==== turn this into a real switch frontend and backends 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * Well, at least the API doesn't involve pointers-to-static. 37*7c478bd9Sstevel@tonic-gate */ 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * netname utility routines convert from netnames to unix names (uid, gid) 43*7c478bd9Sstevel@tonic-gate * 44*7c478bd9Sstevel@tonic-gate * This module is operating system dependent! 45*7c478bd9Sstevel@tonic-gate * What we define here will work with any unix system that has adopted 46*7c478bd9Sstevel@tonic-gate * the Sun NIS domain architecture. 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #undef NIS 50*7c478bd9Sstevel@tonic-gate #include "mt.h" 51*7c478bd9Sstevel@tonic-gate #include "rpc_mt.h" 52*7c478bd9Sstevel@tonic-gate #include <stdio.h> 53*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 55*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h> 56*7c478bd9Sstevel@tonic-gate #include <ctype.h> 57*7c478bd9Sstevel@tonic-gate #include <grp.h> 58*7c478bd9Sstevel@tonic-gate #include <pwd.h> 59*7c478bd9Sstevel@tonic-gate #include <string.h> 60*7c478bd9Sstevel@tonic-gate #include <syslog.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 62*7c478bd9Sstevel@tonic-gate #include <nsswitch.h> 63*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 64*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h> 65*7c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 66*7c478bd9Sstevel@tonic-gate #include "nsl_stdio_prv.h" 67*7c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h> 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static const char OPSYS[] = "unix"; 70*7c478bd9Sstevel@tonic-gate static const char NETIDFILE[] = "/etc/netid"; 71*7c478bd9Sstevel@tonic-gate static const char NETID[] = "netid.byname"; 72*7c478bd9Sstevel@tonic-gate static const char PKTABLE[] = "cred.org_dir"; 73*7c478bd9Sstevel@tonic-gate #define PKTABLE_LEN 12 74*7c478bd9Sstevel@tonic-gate #define OPSYS_LEN 4 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #ifndef NGROUPS 77*7c478bd9Sstevel@tonic-gate #define NGROUPS 16 78*7c478bd9Sstevel@tonic-gate #endif 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate extern int _getgroupsbymember(const char *, gid_t[], int, int); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate * the value for NOBODY_UID is set by the SVID. The following define also 84*7c478bd9Sstevel@tonic-gate * appears in netname.c 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate #define NOBODY_UID 60001 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate /* 90*7c478bd9Sstevel@tonic-gate * default publickey policy: 91*7c478bd9Sstevel@tonic-gate * publickey: nis [NOTFOUND = return] files 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* NSW_NOTSUCCESS NSW_NOTFOUND NSW_UNAVAIL NSW_TRYAGAIN */ 96*7c478bd9Sstevel@tonic-gate #define DEF_ACTION {__NSW_RETURN, __NSW_RETURN, __NSW_CONTINUE, __NSW_CONTINUE} 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate static struct __nsw_lookup lookup_files = {"files", DEF_ACTION, NULL, NULL}, 99*7c478bd9Sstevel@tonic-gate lookup_nis = {"nis", DEF_ACTION, NULL, &lookup_files}; 100*7c478bd9Sstevel@tonic-gate static struct __nsw_switchconfig publickey_default = 101*7c478bd9Sstevel@tonic-gate {0, "publickey", 2, &lookup_nis}; 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate static mutex_t serialize_netname_r = DEFAULTMUTEX; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate struct netid_userdata { 106*7c478bd9Sstevel@tonic-gate uid_t *uidp; 107*7c478bd9Sstevel@tonic-gate gid_t *gidp; 108*7c478bd9Sstevel@tonic-gate int *gidlenp; 109*7c478bd9Sstevel@tonic-gate gid_t *gidlist; 110*7c478bd9Sstevel@tonic-gate }; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate static int 113*7c478bd9Sstevel@tonic-gate parse_uid(s, argp) 114*7c478bd9Sstevel@tonic-gate char *s; 115*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate uid_t u; 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid, 0); 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate if (!s || !isdigit(*s)) { 122*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 123*7c478bd9Sstevel@tonic-gate "netname2user: expecting uid '%s'", s); 124*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid, 1); 125*7c478bd9Sstevel@tonic-gate return (__NSW_NOTFOUND); /* xxx need a better error */ 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* Fetch the uid */ 129*7c478bd9Sstevel@tonic-gate u = (uid_t)(atoi(s)); 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if (u == 0) { 132*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2user: should not have uid 0"); 133*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid, 1); 134*7c478bd9Sstevel@tonic-gate return (__NSW_NOTFOUND); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate *(argp->uidp) = u; 137*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid, 1); 138*7c478bd9Sstevel@tonic-gate return (__NSW_SUCCESS); 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /* parse a comma separated gid list */ 143*7c478bd9Sstevel@tonic-gate static int 144*7c478bd9Sstevel@tonic-gate parse_gidlist(p, argp) 145*7c478bd9Sstevel@tonic-gate char *p; 146*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate int len; 149*7c478bd9Sstevel@tonic-gate gid_t g; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate trace1(TR_parse_gidlist, 0); 152*7c478bd9Sstevel@tonic-gate if (! p || (! isdigit(*p))) { 153*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 154*7c478bd9Sstevel@tonic-gate "netname2user: missing group id list in '%s'.", 155*7c478bd9Sstevel@tonic-gate p); 156*7c478bd9Sstevel@tonic-gate trace1(TR_parse_gidlist, 1); 157*7c478bd9Sstevel@tonic-gate return (__NSW_NOTFOUND); 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate g = (gid_t)(atoi(p)); 161*7c478bd9Sstevel@tonic-gate *(argp->gidp) = g; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate len = 0; 164*7c478bd9Sstevel@tonic-gate while (p = strchr(p, ',')) 165*7c478bd9Sstevel@tonic-gate argp->gidlist[len++] = (gid_t)atoi(++p); 166*7c478bd9Sstevel@tonic-gate *(argp->gidlenp) = len; 167*7c478bd9Sstevel@tonic-gate trace1(TR_parse_gidlist, 1); 168*7c478bd9Sstevel@tonic-gate return (__NSW_SUCCESS); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * parse_netid_str() 174*7c478bd9Sstevel@tonic-gate * 175*7c478bd9Sstevel@tonic-gate * Parse uid and group information from the passed string. 176*7c478bd9Sstevel@tonic-gate * 177*7c478bd9Sstevel@tonic-gate * The format of the string passed is 178*7c478bd9Sstevel@tonic-gate * uid:gid,grp,grp, ... 179*7c478bd9Sstevel@tonic-gate * 180*7c478bd9Sstevel@tonic-gate */ 181*7c478bd9Sstevel@tonic-gate static int 182*7c478bd9Sstevel@tonic-gate parse_netid_str(s, argp) 183*7c478bd9Sstevel@tonic-gate char *s; 184*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 185*7c478bd9Sstevel@tonic-gate { 186*7c478bd9Sstevel@tonic-gate char *p; 187*7c478bd9Sstevel@tonic-gate int err; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate trace1(TR_parse_netid_str, 0); 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* get uid */ 192*7c478bd9Sstevel@tonic-gate err = parse_uid(s, argp); 193*7c478bd9Sstevel@tonic-gate if (err != __NSW_SUCCESS) { 194*7c478bd9Sstevel@tonic-gate trace1(TR_parse_netid_str, 1); 195*7c478bd9Sstevel@tonic-gate return (err); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* Now get the group list */ 200*7c478bd9Sstevel@tonic-gate p = strchr(s, ':'); 201*7c478bd9Sstevel@tonic-gate if (!p) { 202*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 203*7c478bd9Sstevel@tonic-gate "netname2user: missing group id list in '%s'", 204*7c478bd9Sstevel@tonic-gate s); 205*7c478bd9Sstevel@tonic-gate trace1(TR_parse_netid_str, 1); 206*7c478bd9Sstevel@tonic-gate return (__NSW_NOTFOUND); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate ++p; /* skip ':' */ 209*7c478bd9Sstevel@tonic-gate err = parse_gidlist(p, argp); 210*7c478bd9Sstevel@tonic-gate trace1(TR_parse_netid_str, 1); 211*7c478bd9Sstevel@tonic-gate return (err); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate static int 215*7c478bd9Sstevel@tonic-gate parse_uid_gidlist(ustr, gstr, argp) 216*7c478bd9Sstevel@tonic-gate char *ustr; 217*7c478bd9Sstevel@tonic-gate char *gstr; 218*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate int err; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid_gidlist, 0); 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* get uid */ 225*7c478bd9Sstevel@tonic-gate err = parse_uid(ustr, argp); 226*7c478bd9Sstevel@tonic-gate if (err != __NSW_SUCCESS) { 227*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid_gidlist, 1); 228*7c478bd9Sstevel@tonic-gate return (err); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* Now get the group list */ 232*7c478bd9Sstevel@tonic-gate err = parse_gidlist(gstr, argp); 233*7c478bd9Sstevel@tonic-gate trace1(TR_parse_uid_gidlist, 1); 234*7c478bd9Sstevel@tonic-gate return (err); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate /* 239*7c478bd9Sstevel@tonic-gate * netname2user_files() 240*7c478bd9Sstevel@tonic-gate * 241*7c478bd9Sstevel@tonic-gate * This routine fetches the netid information from the "files" nameservice. 242*7c478bd9Sstevel@tonic-gate * ie /etc/netid. 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate static int 245*7c478bd9Sstevel@tonic-gate netname2user_files(err, netname, argp) 246*7c478bd9Sstevel@tonic-gate int *err; 247*7c478bd9Sstevel@tonic-gate char *netname; 248*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 249*7c478bd9Sstevel@tonic-gate { 250*7c478bd9Sstevel@tonic-gate char buf[512]; /* one line from the file */ 251*7c478bd9Sstevel@tonic-gate char *name; 252*7c478bd9Sstevel@tonic-gate char *value; 253*7c478bd9Sstevel@tonic-gate char *res; 254*7c478bd9Sstevel@tonic-gate __NSL_FILE *fd; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_files, 0); 257*7c478bd9Sstevel@tonic-gate fd = __nsl_fopen(NETIDFILE, "r"); 258*7c478bd9Sstevel@tonic-gate if (fd == (__NSL_FILE *)0) { 259*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 260*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_files, 1); 261*7c478bd9Sstevel@tonic-gate return (0); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate /* 264*7c478bd9Sstevel@tonic-gate * for each line in the file parse it appropriately 265*7c478bd9Sstevel@tonic-gate * file format is : 266*7c478bd9Sstevel@tonic-gate * netid uid:grp,grp,grp # for users 267*7c478bd9Sstevel@tonic-gate * netid 0:hostname # for hosts 268*7c478bd9Sstevel@tonic-gate */ 269*7c478bd9Sstevel@tonic-gate while (! __nsl_feof(fd)) { 270*7c478bd9Sstevel@tonic-gate res = __nsl_fgets(buf, 512, fd); 271*7c478bd9Sstevel@tonic-gate if (res == NULL) 272*7c478bd9Sstevel@tonic-gate break; 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate /* Skip comments and blank lines */ 275*7c478bd9Sstevel@tonic-gate if ((*res == '#') || (*res == '\n')) 276*7c478bd9Sstevel@tonic-gate continue; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate name = &(buf[0]); 279*7c478bd9Sstevel@tonic-gate while (isspace(*name)) 280*7c478bd9Sstevel@tonic-gate name++; 281*7c478bd9Sstevel@tonic-gate if (*name == '\0') /* blank line continue */ 282*7c478bd9Sstevel@tonic-gate continue; 283*7c478bd9Sstevel@tonic-gate value = name; /* will contain the value eventually */ 284*7c478bd9Sstevel@tonic-gate while (! isspace(*value)) 285*7c478bd9Sstevel@tonic-gate value++; 286*7c478bd9Sstevel@tonic-gate if (*value == '\0') { 287*7c478bd9Sstevel@tonic-gate syslog(LOG_WARNING, 288*7c478bd9Sstevel@tonic-gate "netname2user: badly formatted line in %s.", 289*7c478bd9Sstevel@tonic-gate NETIDFILE); 290*7c478bd9Sstevel@tonic-gate continue; 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate *value++ = '\0'; /* nul terminate the name */ 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate if (strcasecmp(name, netname) == 0) { 295*7c478bd9Sstevel@tonic-gate __nsl_fclose(fd); 296*7c478bd9Sstevel@tonic-gate while (isspace(*value)) 297*7c478bd9Sstevel@tonic-gate value++; 298*7c478bd9Sstevel@tonic-gate *err = parse_netid_str(value, argp); 299*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_files, 1); 300*7c478bd9Sstevel@tonic-gate return (*err == __NSW_SUCCESS); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate __nsl_fclose(fd); 304*7c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 305*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_files, 1); 306*7c478bd9Sstevel@tonic-gate return (0); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* 310*7c478bd9Sstevel@tonic-gate * netname2user_nis() 311*7c478bd9Sstevel@tonic-gate * 312*7c478bd9Sstevel@tonic-gate * This function reads the netid from the NIS (YP) nameservice. 313*7c478bd9Sstevel@tonic-gate */ 314*7c478bd9Sstevel@tonic-gate static int 315*7c478bd9Sstevel@tonic-gate netname2user_nis(err, netname, argp) 316*7c478bd9Sstevel@tonic-gate int *err; 317*7c478bd9Sstevel@tonic-gate char *netname; 318*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 319*7c478bd9Sstevel@tonic-gate { 320*7c478bd9Sstevel@tonic-gate char *domain; 321*7c478bd9Sstevel@tonic-gate int yperr; 322*7c478bd9Sstevel@tonic-gate char *lookup; 323*7c478bd9Sstevel@tonic-gate int len; 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nis, 0); 326*7c478bd9Sstevel@tonic-gate domain = strchr(netname, '@'); 327*7c478bd9Sstevel@tonic-gate if (! domain) { 328*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 329*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nis, 1); 330*7c478bd9Sstevel@tonic-gate return (0); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate /* Point past the '@' character */ 334*7c478bd9Sstevel@tonic-gate domain++; 335*7c478bd9Sstevel@tonic-gate lookup = NULL; 336*7c478bd9Sstevel@tonic-gate yperr = yp_match(domain, (char *)NETID, netname, strlen(netname), 337*7c478bd9Sstevel@tonic-gate &lookup, &len); 338*7c478bd9Sstevel@tonic-gate switch (yperr) { 339*7c478bd9Sstevel@tonic-gate case 0: 340*7c478bd9Sstevel@tonic-gate break; /* the successful case */ 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate default : 343*7c478bd9Sstevel@tonic-gate /* 344*7c478bd9Sstevel@tonic-gate * XXX not sure about yp_match semantics. 345*7c478bd9Sstevel@tonic-gate * should err be set to NOTFOUND here? 346*7c478bd9Sstevel@tonic-gate */ 347*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 348*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nis, 1); 349*7c478bd9Sstevel@tonic-gate return (0); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate if (lookup) { 352*7c478bd9Sstevel@tonic-gate lookup[len] = '\0'; 353*7c478bd9Sstevel@tonic-gate *err = parse_netid_str(lookup, argp); 354*7c478bd9Sstevel@tonic-gate free(lookup); 355*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nis, 1); 356*7c478bd9Sstevel@tonic-gate return (*err == __NSW_SUCCESS); 357*7c478bd9Sstevel@tonic-gate } else { 358*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nis, 1); 359*7c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 360*7c478bd9Sstevel@tonic-gate return (0); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate /* 365*7c478bd9Sstevel@tonic-gate * Obtain user information (uid, gidlist) from nisplus. 366*7c478bd9Sstevel@tonic-gate * What we're trying to do here is to map a netname into 367*7c478bd9Sstevel@tonic-gate * local unix information (uid, gids), relevant in 368*7c478bd9Sstevel@tonic-gate * the *local* domain. 369*7c478bd9Sstevel@tonic-gate * 370*7c478bd9Sstevel@tonic-gate * cname auth_type auth_name public private 371*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------- 372*7c478bd9Sstevel@tonic-gate * nisname DES netname pubkey prikey 373*7c478bd9Sstevel@tonic-gate * nisname LOCAL uid gidlist 374*7c478bd9Sstevel@tonic-gate * 375*7c478bd9Sstevel@tonic-gate * 1. Find out which 'home' domain to look for user's DES entry. 376*7c478bd9Sstevel@tonic-gate * This is gotten from the domain part of the netname. 377*7c478bd9Sstevel@tonic-gate * 2. Get the nisplus principal name from the DES entry in the cred 378*7c478bd9Sstevel@tonic-gate * table of user's home domain. 379*7c478bd9Sstevel@tonic-gate * 3. Use the nisplus principal name and search in the cred table of 380*7c478bd9Sstevel@tonic-gate * the *local* directory for the LOCAL entry. 381*7c478bd9Sstevel@tonic-gate * 382*7c478bd9Sstevel@tonic-gate * Note that we need this translation of netname to <uid,gidlist> to be 383*7c478bd9Sstevel@tonic-gate * secure, so we *must* use authenticated connections. 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate static int 386*7c478bd9Sstevel@tonic-gate netname2user_nisplus(err, netname, argp) 387*7c478bd9Sstevel@tonic-gate int *err; 388*7c478bd9Sstevel@tonic-gate char *netname; 389*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 390*7c478bd9Sstevel@tonic-gate { 391*7c478bd9Sstevel@tonic-gate char *domain; 392*7c478bd9Sstevel@tonic-gate nis_result *res; 393*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; /* search criteria + table name */ 394*7c478bd9Sstevel@tonic-gate char principal[NIS_MAXNAMELEN+1]; 395*7c478bd9Sstevel@tonic-gate int len; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 0); 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate /* 1. Get home domain of user. */ 401*7c478bd9Sstevel@tonic-gate domain = strchr(netname, '@'); 402*7c478bd9Sstevel@tonic-gate if (! domain) { 403*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 404*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 405*7c478bd9Sstevel@tonic-gate return (0); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate domain++; /* skip '@' */ 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate /* 2. Get user's nisplus principal name. */ 411*7c478bd9Sstevel@tonic-gate if ((strlen(netname)+strlen(domain)+PKTABLE_LEN+32) > 412*7c478bd9Sstevel@tonic-gate (size_t)NIS_MAXNAMELEN) { 413*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 414*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 415*7c478bd9Sstevel@tonic-gate return (0); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate sprintf(sname, "[auth_name=\"%s\",auth_type=DES],%s.%s", 418*7c478bd9Sstevel@tonic-gate netname, PKTABLE, domain); 419*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname) - 1] != '.') 420*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate /* must use authenticated call here */ 423*7c478bd9Sstevel@tonic-gate /* XXX but we cant, for now. XXX */ 424*7c478bd9Sstevel@tonic-gate res = nis_list(sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, 425*7c478bd9Sstevel@tonic-gate NULL, NULL); 426*7c478bd9Sstevel@tonic-gate switch (res->status) { 427*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 428*7c478bd9Sstevel@tonic-gate case NIS_S_SUCCESS: 429*7c478bd9Sstevel@tonic-gate break; /* go and do something useful */ 430*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 431*7c478bd9Sstevel@tonic-gate case NIS_PARTIAL: 432*7c478bd9Sstevel@tonic-gate case NIS_NOSUCHNAME: 433*7c478bd9Sstevel@tonic-gate case NIS_NOSUCHTABLE: 434*7c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 435*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 436*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 437*7c478bd9Sstevel@tonic-gate return (0); 438*7c478bd9Sstevel@tonic-gate case NIS_S_NOTFOUND: 439*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 440*7c478bd9Sstevel@tonic-gate *err = __NSW_TRYAGAIN; 441*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 442*7c478bd9Sstevel@tonic-gate "netname2user: (nis+ lookup): %s\n", 443*7c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 444*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 445*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 446*7c478bd9Sstevel@tonic-gate return (0); 447*7c478bd9Sstevel@tonic-gate default: 448*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 449*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2user: (nis+ lookup): %s\n", 450*7c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 451*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 452*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 453*7c478bd9Sstevel@tonic-gate return (0); 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate if (res->objects.objects_len > 1) { 457*7c478bd9Sstevel@tonic-gate /* 458*7c478bd9Sstevel@tonic-gate * A netname belonging to more than one principal? 459*7c478bd9Sstevel@tonic-gate * Something wrong with cred table. should be unique. 460*7c478bd9Sstevel@tonic-gate * Warn user and continue. 461*7c478bd9Sstevel@tonic-gate */ 462*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, 463*7c478bd9Sstevel@tonic-gate "netname2user: DES entry for %s in \ 464*7c478bd9Sstevel@tonic-gate directory %s not unique", 465*7c478bd9Sstevel@tonic-gate netname, domain); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate len = ENTRY_LEN(res->objects.objects_val, 0); 469*7c478bd9Sstevel@tonic-gate strncpy(principal, ENTRY_VAL(res->objects.objects_val, 0), len); 470*7c478bd9Sstevel@tonic-gate principal[len] = '\0'; 471*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate if (principal[0] == '\0') { 474*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 475*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 476*7c478bd9Sstevel@tonic-gate return (0); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate /* 480*7c478bd9Sstevel@tonic-gate * 3. Use principal name to look up uid/gid information in 481*7c478bd9Sstevel@tonic-gate * LOCAL entry in **local** cred table. 482*7c478bd9Sstevel@tonic-gate */ 483*7c478bd9Sstevel@tonic-gate domain = nis_local_directory(); 484*7c478bd9Sstevel@tonic-gate if ((strlen(principal)+strlen(domain)+PKTABLE_LEN+30) > 485*7c478bd9Sstevel@tonic-gate (size_t)NIS_MAXNAMELEN) { 486*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 487*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2user: principal name '%s' too long", 488*7c478bd9Sstevel@tonic-gate principal); 489*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 490*7c478bd9Sstevel@tonic-gate return (0); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate sprintf(sname, "[cname=\"%s\",auth_type=LOCAL],%s.%s", 493*7c478bd9Sstevel@tonic-gate principal, PKTABLE, domain); 494*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname) - 1] != '.') 495*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate /* must use authenticated call here */ 498*7c478bd9Sstevel@tonic-gate /* XXX but we cant, for now. XXX */ 499*7c478bd9Sstevel@tonic-gate res = nis_list(sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, 500*7c478bd9Sstevel@tonic-gate NULL, NULL); 501*7c478bd9Sstevel@tonic-gate switch (res->status) { 502*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 503*7c478bd9Sstevel@tonic-gate case NIS_PARTIAL: 504*7c478bd9Sstevel@tonic-gate case NIS_NOSUCHNAME: 505*7c478bd9Sstevel@tonic-gate case NIS_NOSUCHTABLE: 506*7c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 507*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 508*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 509*7c478bd9Sstevel@tonic-gate return (0); 510*7c478bd9Sstevel@tonic-gate case NIS_S_NOTFOUND: 511*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 512*7c478bd9Sstevel@tonic-gate *err = __NSW_TRYAGAIN; 513*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 514*7c478bd9Sstevel@tonic-gate "netname2user: (nis+ lookup): %s\n", 515*7c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 516*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 517*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 518*7c478bd9Sstevel@tonic-gate return (0); 519*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 520*7c478bd9Sstevel@tonic-gate case NIS_S_SUCCESS: 521*7c478bd9Sstevel@tonic-gate break; /* go and do something useful */ 522*7c478bd9Sstevel@tonic-gate default: 523*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 524*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2user: (nis+ lookup): %s\n", 525*7c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 526*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 527*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 528*7c478bd9Sstevel@tonic-gate return (0); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate if (res->objects.objects_len > 1) { 532*7c478bd9Sstevel@tonic-gate /* 533*7c478bd9Sstevel@tonic-gate * A principal can have more than one LOCAL entry? 534*7c478bd9Sstevel@tonic-gate * Something wrong with cred table. 535*7c478bd9Sstevel@tonic-gate * Warn user and continue. 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, 538*7c478bd9Sstevel@tonic-gate "netname2user: LOCAL entry for %s in\ 539*7c478bd9Sstevel@tonic-gate directory %s not unique", 540*7c478bd9Sstevel@tonic-gate netname, domain); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate /* nisname LOCAL uid grp,grp,grp */ 543*7c478bd9Sstevel@tonic-gate *err = parse_uid_gidlist(ENTRY_VAL(res->objects.objects_val, 2), 544*7c478bd9Sstevel@tonic-gate /* uid */ 545*7c478bd9Sstevel@tonic-gate ENTRY_VAL(res->objects.objects_val, 3), /* gids */ 546*7c478bd9Sstevel@tonic-gate argp); 547*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 548*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user_nisplus, 1); 549*7c478bd9Sstevel@tonic-gate return (*err == __NSW_SUCCESS); 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate /* 553*7c478bd9Sstevel@tonic-gate * Build the uid and gid from the netname for users in LDAP. 554*7c478bd9Sstevel@tonic-gate * There is no netid container in LDAP. For this we build 555*7c478bd9Sstevel@tonic-gate * the netname to user data dynamically from the passwd and 556*7c478bd9Sstevel@tonic-gate * group data. This works only for users in a single domain. 557*7c478bd9Sstevel@tonic-gate * This function is an interim solution until we support a 558*7c478bd9Sstevel@tonic-gate * netid container in LDAP which enables us to do netname2user 559*7c478bd9Sstevel@tonic-gate * resolution for multiple domains. 560*7c478bd9Sstevel@tonic-gate */ 561*7c478bd9Sstevel@tonic-gate static int 562*7c478bd9Sstevel@tonic-gate netname2user_ldap(err, netname, argp) 563*7c478bd9Sstevel@tonic-gate int *err; 564*7c478bd9Sstevel@tonic-gate char *netname; 565*7c478bd9Sstevel@tonic-gate struct netid_userdata *argp; 566*7c478bd9Sstevel@tonic-gate { 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate char buf[NSS_LINELEN_PASSWD]; 569*7c478bd9Sstevel@tonic-gate char *p1, *p2, *lasts; 570*7c478bd9Sstevel@tonic-gate struct passwd pw; 571*7c478bd9Sstevel@tonic-gate uid_t uidnu; 572*7c478bd9Sstevel@tonic-gate int ngroups = 0; 573*7c478bd9Sstevel@tonic-gate int count; 574*7c478bd9Sstevel@tonic-gate char pwbuf[NSS_LINELEN_PASSWD]; 575*7c478bd9Sstevel@tonic-gate gid_t groups[NGROUPS_MAX]; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate if (strlcpy(buf, netname, NSS_LINELEN_PASSWD) >= NSS_LINELEN_PASSWD) { 578*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 579*7c478bd9Sstevel@tonic-gate return (0); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate /* get the uid from the netname */ 583*7c478bd9Sstevel@tonic-gate if ((p1 = strtok_r(buf, ".", &lasts)) == NULL) { 584*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 585*7c478bd9Sstevel@tonic-gate return (0); 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate if ((p2 = strtok_r(NULL, "@", &lasts)) == NULL) { 588*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 589*7c478bd9Sstevel@tonic-gate return (0); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate uidnu = atoi(p2); 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate /* 594*7c478bd9Sstevel@tonic-gate * check out the primary group and crosscheck the uid 595*7c478bd9Sstevel@tonic-gate * with the passwd data 596*7c478bd9Sstevel@tonic-gate */ 597*7c478bd9Sstevel@tonic-gate if ((getpwuid_r(uidnu, &pw, pwbuf, sizeof (pwbuf))) == NULL) { 598*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 599*7c478bd9Sstevel@tonic-gate return (0); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate *(argp->uidp) = pw.pw_uid; 603*7c478bd9Sstevel@tonic-gate *(argp->gidp) = pw.pw_gid; 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate /* search through all groups for membership */ 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate groups[0] = pw.pw_gid; 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate ngroups = _getgroupsbymember(pw.pw_name, groups, NGROUPS_MAX, 610*7c478bd9Sstevel@tonic-gate (pw.pw_gid >= 0) ? 1 : 0); 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate if (ngroups < 0) { 613*7c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 614*7c478bd9Sstevel@tonic-gate return (0); 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate *(argp->gidlenp) = ngroups; 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate for (count = 0; count < ngroups; count++) { 620*7c478bd9Sstevel@tonic-gate (argp->gidlist[count]) = groups[count]; 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate *err = __NSW_SUCCESS; 624*7c478bd9Sstevel@tonic-gate return (1); 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate /* 629*7c478bd9Sstevel@tonic-gate * Convert network-name into unix credential 630*7c478bd9Sstevel@tonic-gate */ 631*7c478bd9Sstevel@tonic-gate int 632*7c478bd9Sstevel@tonic-gate netname2user(netname, uidp, gidp, gidlenp, gidlist) 633*7c478bd9Sstevel@tonic-gate const char netname[MAXNETNAMELEN + 1]; 634*7c478bd9Sstevel@tonic-gate uid_t *uidp; 635*7c478bd9Sstevel@tonic-gate gid_t *gidp; 636*7c478bd9Sstevel@tonic-gate int *gidlenp; 637*7c478bd9Sstevel@tonic-gate gid_t *gidlist; 638*7c478bd9Sstevel@tonic-gate { 639*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *conf; 640*7c478bd9Sstevel@tonic-gate struct __nsw_lookup *look; 641*7c478bd9Sstevel@tonic-gate enum __nsw_parse_err perr; 642*7c478bd9Sstevel@tonic-gate int needfree = 1, res; 643*7c478bd9Sstevel@tonic-gate struct netid_userdata argp; 644*7c478bd9Sstevel@tonic-gate int err; 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user, 0); 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate /* 649*7c478bd9Sstevel@tonic-gate * Take care of the special case of nobody. Compare the netname 650*7c478bd9Sstevel@tonic-gate * to the string "nobody". If they are equal, return the SVID 651*7c478bd9Sstevel@tonic-gate * standard value for nobody. 652*7c478bd9Sstevel@tonic-gate */ 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate if (strcmp(netname, "nobody") == 0) { 655*7c478bd9Sstevel@tonic-gate *uidp = NOBODY_UID; 656*7c478bd9Sstevel@tonic-gate *gidp = NOBODY_UID; 657*7c478bd9Sstevel@tonic-gate *gidlenp = 0; 658*7c478bd9Sstevel@tonic-gate return (1); 659*7c478bd9Sstevel@tonic-gate } 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate /* 662*7c478bd9Sstevel@tonic-gate * First we do some generic sanity checks on the name we were 663*7c478bd9Sstevel@tonic-gate * passed. This lets us assume they are correct in the backends. 664*7c478bd9Sstevel@tonic-gate * 665*7c478bd9Sstevel@tonic-gate * NOTE: this code only recognizes names of the form : 666*7c478bd9Sstevel@tonic-gate * unix.UID@domainname 667*7c478bd9Sstevel@tonic-gate */ 668*7c478bd9Sstevel@tonic-gate if (strncmp(netname, OPSYS, OPSYS_LEN) != 0) { 669*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user, 1); 670*7c478bd9Sstevel@tonic-gate return (0); 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate if (! isdigit(netname[OPSYS_LEN+1])) { /* check for uid string */ 673*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user, 1); 674*7c478bd9Sstevel@tonic-gate return (0); 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate argp.uidp = uidp; 678*7c478bd9Sstevel@tonic-gate argp.gidp = gidp; 679*7c478bd9Sstevel@tonic-gate argp.gidlenp = gidlenp; 680*7c478bd9Sstevel@tonic-gate argp.gidlist = gidlist; 681*7c478bd9Sstevel@tonic-gate mutex_lock(&serialize_netname_r); 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate conf = __nsw_getconfig("publickey", &perr); 684*7c478bd9Sstevel@tonic-gate if (! conf) { 685*7c478bd9Sstevel@tonic-gate conf = &publickey_default; 686*7c478bd9Sstevel@tonic-gate needfree = 0; 687*7c478bd9Sstevel@tonic-gate } else 688*7c478bd9Sstevel@tonic-gate needfree = 1; /* free the config structure */ 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate for (look = conf->lookups; look; look = look->next) { 691*7c478bd9Sstevel@tonic-gate if (strcmp(look->service_name, "nisplus") == 0) 692*7c478bd9Sstevel@tonic-gate res = netname2user_nisplus(&err, 693*7c478bd9Sstevel@tonic-gate (char *)netname, &argp); 694*7c478bd9Sstevel@tonic-gate else if (strcmp(look->service_name, "nis") == 0) 695*7c478bd9Sstevel@tonic-gate res = netname2user_nis(&err, (char *)netname, &argp); 696*7c478bd9Sstevel@tonic-gate else if (strcmp(look->service_name, "files") == 0) 697*7c478bd9Sstevel@tonic-gate res = netname2user_files(&err, (char *)netname, &argp); 698*7c478bd9Sstevel@tonic-gate else if (strcmp(look->service_name, "ldap") == 0) 699*7c478bd9Sstevel@tonic-gate res = netname2user_ldap(&err, (char *)netname, &argp); 700*7c478bd9Sstevel@tonic-gate else { 701*7c478bd9Sstevel@tonic-gate syslog(LOG_INFO, 702*7c478bd9Sstevel@tonic-gate "netname2user: unknown nameservice for publickey info '%s'\n", 703*7c478bd9Sstevel@tonic-gate look->service_name); 704*7c478bd9Sstevel@tonic-gate err = __NSW_UNAVAIL; 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate switch (look->actions[err]) { 707*7c478bd9Sstevel@tonic-gate case __NSW_CONTINUE : 708*7c478bd9Sstevel@tonic-gate break; 709*7c478bd9Sstevel@tonic-gate case __NSW_RETURN : 710*7c478bd9Sstevel@tonic-gate if (needfree) 711*7c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 712*7c478bd9Sstevel@tonic-gate mutex_unlock(&serialize_netname_r); 713*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user, 1); 714*7c478bd9Sstevel@tonic-gate return (res); 715*7c478bd9Sstevel@tonic-gate default : 716*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 717*7c478bd9Sstevel@tonic-gate "netname2user: Unknown action for nameservice '%s'", 718*7c478bd9Sstevel@tonic-gate look->service_name); 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate if (needfree) 722*7c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 723*7c478bd9Sstevel@tonic-gate mutex_unlock(&serialize_netname_r); 724*7c478bd9Sstevel@tonic-gate trace1(TR_netname2user, 1); 725*7c478bd9Sstevel@tonic-gate return (0); 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate 728*7c478bd9Sstevel@tonic-gate /* 729*7c478bd9Sstevel@tonic-gate * Convert network-name to hostname (fully qualified) 730*7c478bd9Sstevel@tonic-gate * NOTE: this code only recognizes names of the form : 731*7c478bd9Sstevel@tonic-gate * unix.HOST@domainname 732*7c478bd9Sstevel@tonic-gate * 733*7c478bd9Sstevel@tonic-gate * This is very simple. Since the netname is of the form: 734*7c478bd9Sstevel@tonic-gate * unix.host@domainname 735*7c478bd9Sstevel@tonic-gate * We just construct the hostname using information from the domainname. 736*7c478bd9Sstevel@tonic-gate */ 737*7c478bd9Sstevel@tonic-gate int 738*7c478bd9Sstevel@tonic-gate netname2host(netname, hostname, hostlen) 739*7c478bd9Sstevel@tonic-gate const char netname[MAXNETNAMELEN + 1]; 740*7c478bd9Sstevel@tonic-gate char *hostname; 741*7c478bd9Sstevel@tonic-gate int hostlen; 742*7c478bd9Sstevel@tonic-gate { 743*7c478bd9Sstevel@tonic-gate char *p, *domainname; 744*7c478bd9Sstevel@tonic-gate int len, dlen; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate trace1(TR_netname2host, 0); 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate if (!netname) { 749*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2host: null netname"); 750*7c478bd9Sstevel@tonic-gate goto bad_exit; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate if (strncmp(netname, OPSYS, OPSYS_LEN) != 0) 754*7c478bd9Sstevel@tonic-gate goto bad_netname; 755*7c478bd9Sstevel@tonic-gate p = (char *)netname + OPSYS_LEN; /* skip OPSYS part */ 756*7c478bd9Sstevel@tonic-gate if (*p != '.') 757*7c478bd9Sstevel@tonic-gate goto bad_netname; 758*7c478bd9Sstevel@tonic-gate ++p; /* skip '.' */ 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate domainname = strchr(p, '@'); /* get domain name */ 761*7c478bd9Sstevel@tonic-gate if (domainname == 0) 762*7c478bd9Sstevel@tonic-gate goto bad_netname; 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate len = domainname - p; /* host sits between '.' and '@' */ 765*7c478bd9Sstevel@tonic-gate domainname++; /* skip '@' sign */ 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate if (len <= 0) 768*7c478bd9Sstevel@tonic-gate goto bad_netname; 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate if (hostlen < len) { 771*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 772*7c478bd9Sstevel@tonic-gate "netname2host: insufficient space for hostname"); 773*7c478bd9Sstevel@tonic-gate goto bad_exit; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate if (isdigit(*p)) /* don't want uid here */ 777*7c478bd9Sstevel@tonic-gate goto bad_netname; 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate if (*p == '\0') /* check for null hostname */ 780*7c478bd9Sstevel@tonic-gate goto bad_netname; 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate strncpy(hostname, p, len); 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate /* make into fully qualified hostname by concatenating domain part */ 785*7c478bd9Sstevel@tonic-gate dlen = strlen(domainname); 786*7c478bd9Sstevel@tonic-gate if (hostlen < (len + dlen + 2)) { 787*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 788*7c478bd9Sstevel@tonic-gate "netname2host: insufficient space for hostname"); 789*7c478bd9Sstevel@tonic-gate goto bad_exit; 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate hostname[len] = '.'; 793*7c478bd9Sstevel@tonic-gate strncpy(hostname+len+1, domainname, dlen); 794*7c478bd9Sstevel@tonic-gate hostname[len+dlen+1] = '\0'; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate trace1(TR_netname2host, 1); 797*7c478bd9Sstevel@tonic-gate return (1); 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate bad_netname: 801*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netname2host: invalid host netname %s", netname); 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate bad_exit: 804*7c478bd9Sstevel@tonic-gate hostname[0] = '\0'; 805*7c478bd9Sstevel@tonic-gate trace1(TR_netname2host, 1); 806*7c478bd9Sstevel@tonic-gate return (0); 807*7c478bd9Sstevel@tonic-gate } 808