17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*61961e0fSrobinson */ 22*61961e0fSrobinson 23*61961e0fSrobinson /* 24*61961e0fSrobinson * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 317c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 327c478bd9Sstevel@tonic-gate * California. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * ==== hack-attack: possibly MT-safe but definitely not MT-hot. 367c478bd9Sstevel@tonic-gate * ==== turn this into a real switch frontend and backends 377c478bd9Sstevel@tonic-gate * 387c478bd9Sstevel@tonic-gate * Well, at least the API doesn't involve pointers-to-static. 397c478bd9Sstevel@tonic-gate */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* 447c478bd9Sstevel@tonic-gate * netname utility routines (getnetname, user2netname, host2netname). 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * Convert from unix names (uid, gid) to network wide names. 477c478bd9Sstevel@tonic-gate * This module is operating system dependent! 487c478bd9Sstevel@tonic-gate * What we define here will work with any unix system that has adopted 497c478bd9Sstevel@tonic-gate * the Sun NIS domain architecture. 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #undef NIS 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include "mt.h" 557c478bd9Sstevel@tonic-gate #include "rpc_mt.h" 567c478bd9Sstevel@tonic-gate #include <stdio.h> 577c478bd9Sstevel@tonic-gate #include <stdlib.h> 587c478bd9Sstevel@tonic-gate #include <unistd.h> 597c478bd9Sstevel@tonic-gate #include <sys/types.h> 607c478bd9Sstevel@tonic-gate #include <ctype.h> 617c478bd9Sstevel@tonic-gate #include <string.h> 627c478bd9Sstevel@tonic-gate #include <syslog.h> 637c478bd9Sstevel@tonic-gate #include <sys/param.h> 647c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 657c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h> 667c478bd9Sstevel@tonic-gate #include <rpcsvc/nis_dhext.h> 677c478bd9Sstevel@tonic-gate #include <nsswitch.h> 687c478bd9Sstevel@tonic-gate #include <syslog.h> 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #ifndef MAXHOSTNAMELEN 717c478bd9Sstevel@tonic-gate #define MAXHOSTNAMELEN 256 727c478bd9Sstevel@tonic-gate #endif 737c478bd9Sstevel@tonic-gate #ifndef NGROUPS 747c478bd9Sstevel@tonic-gate #define NGROUPS 16 757c478bd9Sstevel@tonic-gate #endif 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * the value for NOBODY_UID is set by the SVID. The following define also 797c478bd9Sstevel@tonic-gate * appears in netnamer.c 807c478bd9Sstevel@tonic-gate */ 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate #define NOBODY_UID 60001 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate extern int __nis_principal(); 857c478bd9Sstevel@tonic-gate extern int getdomainname(); 867c478bd9Sstevel@tonic-gate extern int key_call(); 877c478bd9Sstevel@tonic-gate #define OPSYS_LEN 4 887c478bd9Sstevel@tonic-gate #define PKTABLE_LEN 12 897c478bd9Sstevel@tonic-gate static const char *OPSYS = "unix"; 907c478bd9Sstevel@tonic-gate static const char *PKTABLE = "cred.org_dir"; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate /* 947c478bd9Sstevel@tonic-gate * default publickey policy: 957c478bd9Sstevel@tonic-gate * publickey: nis [NOTFOUND = return] files 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* NSW_NOTSUCCESS NSW_NOTFOUND NSW_UNAVAIL NSW_TRYAGAIN */ 1007c478bd9Sstevel@tonic-gate #define DEF_ACTION {__NSW_RETURN, __NSW_RETURN, __NSW_CONTINUE, __NSW_CONTINUE} 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate static struct __nsw_lookup lookup_files = {"files", DEF_ACTION, NULL, NULL}, 1037c478bd9Sstevel@tonic-gate lookup_nis = {"nis", DEF_ACTION, NULL, &lookup_files}; 1047c478bd9Sstevel@tonic-gate static struct __nsw_switchconfig publickey_default = 1057c478bd9Sstevel@tonic-gate {0, "publickey", 2, &lookup_nis}; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate static mutex_t serialize_netname = DEFAULTMUTEX; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * Convert unix cred to network-name using nisplus 1117c478bd9Sstevel@tonic-gate * nisplus cred table has the following format: 1127c478bd9Sstevel@tonic-gate * 1137c478bd9Sstevel@tonic-gate * cname auth_type auth_name public private 1147c478bd9Sstevel@tonic-gate * ---------------------------------------------------------- 1157c478bd9Sstevel@tonic-gate * nisname DES netname pubkey private_key 1167c478bd9Sstevel@tonic-gate * nisname LOCAL uid gidlist 1177c478bd9Sstevel@tonic-gate * 1187c478bd9Sstevel@tonic-gate * Obtain netname given <uid,domain>. 1197c478bd9Sstevel@tonic-gate * 0. If domain is NULL (indicating local domain), first try to get 1207c478bd9Sstevel@tonic-gate * netname from keyserv (keylogin sets this). 1217c478bd9Sstevel@tonic-gate * 1. Get the nisplus principal name from the LOCAL entry of the cred 1227c478bd9Sstevel@tonic-gate * table in the specified domain (the local domain if domain is NULL). 1237c478bd9Sstevel@tonic-gate * 2. Using the principal name, lookup the DES entry and extract netname. 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate static int 127*61961e0fSrobinson user2netname_nisplus(int *err, char netname[MAXNETNAMELEN + 1], uid_t uid, 128*61961e0fSrobinson char *domain) 1297c478bd9Sstevel@tonic-gate { 1307c478bd9Sstevel@tonic-gate key_netstres kres; 1317c478bd9Sstevel@tonic-gate nis_result *nres; 1327c478bd9Sstevel@tonic-gate int len; 1337c478bd9Sstevel@tonic-gate uid_t my_uid; 1347c478bd9Sstevel@tonic-gate char principal[NIS_MAXNAMELEN+1]; 1357c478bd9Sstevel@tonic-gate char buf[NIS_MAXNAMELEN+1]; 1367c478bd9Sstevel@tonic-gate int status; 1377c478bd9Sstevel@tonic-gate mechanism_t **mechs; 1387c478bd9Sstevel@tonic-gate char auth_type[MECH_MAXATNAME+1]; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate my_uid = geteuid(); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate if (my_uid == uid && domain == NULL) { 1437c478bd9Sstevel@tonic-gate /* 1447c478bd9Sstevel@tonic-gate * Look up the keyserv interface routines to see if 1457c478bd9Sstevel@tonic-gate * netname is stored there. 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate kres.key_netstres_u.knet.st_netname = NULL; 148*61961e0fSrobinson if (key_call((rpcproc_t)KEY_NET_GET, xdr_void, NULL, 1497c478bd9Sstevel@tonic-gate xdr_key_netstres, (char *)&kres) && 1507c478bd9Sstevel@tonic-gate kres.status == KEY_SUCCESS) { 1517c478bd9Sstevel@tonic-gate len = strlen(kres.key_netstres_u.knet.st_netname); 1527c478bd9Sstevel@tonic-gate (void) strncpy(netname, 1537c478bd9Sstevel@tonic-gate kres.key_netstres_u.knet.st_netname, 1547c478bd9Sstevel@tonic-gate len +1); 1557c478bd9Sstevel@tonic-gate free(kres.key_netstres_u.knet.st_netname); 1567c478bd9Sstevel@tonic-gate *err = __NSW_SUCCESS; 1577c478bd9Sstevel@tonic-gate return (1); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * 1. Determine user's nis+ principal name. 1647c478bd9Sstevel@tonic-gate * 1657c478bd9Sstevel@tonic-gate * If domain is specified, we want to look up the uid in the 1667c478bd9Sstevel@tonic-gate * specified domain to determine the user's principal name. 1677c478bd9Sstevel@tonic-gate * Otherwise, get principal name from local directory. 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate if (domain == NULL) 1707c478bd9Sstevel@tonic-gate domain = nis_local_directory(); 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * Don't use nis_local_principal here because we want to 1737c478bd9Sstevel@tonic-gate * catch the TRYAGAIN case so that we handle it properly. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate status = __nis_principal(principal, uid, domain); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (status != NIS_SUCCESS && status != NIS_S_SUCCESS) { 1787c478bd9Sstevel@tonic-gate switch (status) { 1797c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 1807c478bd9Sstevel@tonic-gate case NIS_PARTIAL: 1817c478bd9Sstevel@tonic-gate case NIS_NOSUCHNAME: 1827c478bd9Sstevel@tonic-gate case NIS_NOSUCHTABLE: 1837c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 1847c478bd9Sstevel@tonic-gate break; 1857c478bd9Sstevel@tonic-gate case NIS_S_NOTFOUND: 1867c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 1877c478bd9Sstevel@tonic-gate *err = __NSW_TRYAGAIN; 1887c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 1897c478bd9Sstevel@tonic-gate "user2netname: (nis+ lookup): %s\n", 1907c478bd9Sstevel@tonic-gate nis_sperrno(status)); 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate default: 1937c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 1947c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 1957c478bd9Sstevel@tonic-gate "user2netname: (nis+ lookup): %s\n", 1967c478bd9Sstevel@tonic-gate nis_sperrno(status)); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate return (0); 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* 2037c478bd9Sstevel@tonic-gate * 2. use nis+ principal name to get netname by getting a PK entry. 2047c478bd9Sstevel@tonic-gate * 2057c478bd9Sstevel@tonic-gate * (Use NOAUTH to prevent recursion.) 2067c478bd9Sstevel@tonic-gate */ 2077c478bd9Sstevel@tonic-gate domain = nis_domain_of(principal); 2087c478bd9Sstevel@tonic-gate if ((strlen(principal)+strlen(domain)+PKTABLE_LEN+ 28) > 2097c478bd9Sstevel@tonic-gate (size_t)NIS_MAXNAMELEN) { 2107c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 2117c478bd9Sstevel@tonic-gate return (0); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate if (mechs = __nis_get_mechanisms(FALSE)) { 2157c478bd9Sstevel@tonic-gate mechanism_t **mpp; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* 2187c478bd9Sstevel@tonic-gate * Loop thru mechanism types till we find one in the 2197c478bd9Sstevel@tonic-gate * cred table for this user. 2207c478bd9Sstevel@tonic-gate */ 2217c478bd9Sstevel@tonic-gate for (mpp = mechs; *mpp; mpp++) { 2227c478bd9Sstevel@tonic-gate mechanism_t *mp = *mpp; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (AUTH_DES_COMPAT_CHK(mp)) { 2257c478bd9Sstevel@tonic-gate __nis_release_mechanisms(mechs); 2267c478bd9Sstevel@tonic-gate goto try_auth_des; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate if (!VALID_MECH_ENTRY(mp)) 2297c478bd9Sstevel@tonic-gate continue; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (!__nis_mechalias2authtype(mp->alias, auth_type, 2327c478bd9Sstevel@tonic-gate sizeof (auth_type))) 2337c478bd9Sstevel@tonic-gate continue; 2347c478bd9Sstevel@tonic-gate 235*61961e0fSrobinson (void) snprintf(buf, sizeof (buf), 2367c478bd9Sstevel@tonic-gate "[cname=\"%s\",auth_type=\"%s\"],%s.%s", 2377c478bd9Sstevel@tonic-gate principal, auth_type, PKTABLE, domain); 2387c478bd9Sstevel@tonic-gate if (buf[strlen(buf)-1] != '.') 2397c478bd9Sstevel@tonic-gate (void) strcat(buf, "."); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate nres = nis_list(buf, 2427c478bd9Sstevel@tonic-gate USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, 2437c478bd9Sstevel@tonic-gate NULL, NULL); 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* 2467c478bd9Sstevel@tonic-gate * If the entry is not found, let's try the next one, 2477c478bd9Sstevel@tonic-gate * else it's success or a serious enough NIS+ err 2487c478bd9Sstevel@tonic-gate * to bail on. 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate if (nres->status != NIS_NOTFOUND) 2517c478bd9Sstevel@tonic-gate break; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate } else { 2547c478bd9Sstevel@tonic-gate try_auth_des: 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * No valid mechs exist or the AUTH_DES compat entry was 2577c478bd9Sstevel@tonic-gate * found in the security cf. 2587c478bd9Sstevel@tonic-gate */ 259*61961e0fSrobinson (void) snprintf(buf, sizeof (buf), 260*61961e0fSrobinson "[cname=\"%s\",auth_type=DES],%s.%s", 2617c478bd9Sstevel@tonic-gate principal, PKTABLE, domain); 2627c478bd9Sstevel@tonic-gate if (buf[strlen(buf)-1] != '.') 2637c478bd9Sstevel@tonic-gate (void) strcat(buf, "."); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate nres = nis_list(buf, 2667c478bd9Sstevel@tonic-gate USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, 2677c478bd9Sstevel@tonic-gate NULL, NULL); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate switch (nres->status) { 2717c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 2727c478bd9Sstevel@tonic-gate case NIS_S_SUCCESS: 2737c478bd9Sstevel@tonic-gate break; /* go and do something useful */ 2747c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 2757c478bd9Sstevel@tonic-gate case NIS_PARTIAL: 2767c478bd9Sstevel@tonic-gate case NIS_NOSUCHNAME: 2777c478bd9Sstevel@tonic-gate case NIS_NOSUCHTABLE: 2787c478bd9Sstevel@tonic-gate *err = __NSW_NOTFOUND; 2797c478bd9Sstevel@tonic-gate nis_freeresult(nres); 2807c478bd9Sstevel@tonic-gate return (0); 2817c478bd9Sstevel@tonic-gate case NIS_S_NOTFOUND: 2827c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 2837c478bd9Sstevel@tonic-gate *err = __NSW_TRYAGAIN; 2847c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 2857c478bd9Sstevel@tonic-gate "user2netname: (nis+ lookup): %s\n", 2867c478bd9Sstevel@tonic-gate nis_sperrno(nres->status)); 2877c478bd9Sstevel@tonic-gate nis_freeresult(nres); 2887c478bd9Sstevel@tonic-gate return (0); 2897c478bd9Sstevel@tonic-gate default: 2907c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 2917c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "user2netname: (nis+ lookup): %s\n", 2927c478bd9Sstevel@tonic-gate nis_sperrno(nres->status)); 2937c478bd9Sstevel@tonic-gate nis_freeresult(nres); 2947c478bd9Sstevel@tonic-gate return (0); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate if (nres->objects.objects_len > 1) { 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * Principal with more than one entry for this mech type? 3007c478bd9Sstevel@tonic-gate * Something wrong with cred table. Should be unique. 3017c478bd9Sstevel@tonic-gate * Warn user and continue. 3027c478bd9Sstevel@tonic-gate */ 3037c478bd9Sstevel@tonic-gate syslog(LOG_ALERT, 3047c478bd9Sstevel@tonic-gate "user2netname: %s entry for %s not unique", 3057c478bd9Sstevel@tonic-gate auth_type, principal); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate len = ENTRY_LEN(nres->objects.objects_val, 2); 3097c478bd9Sstevel@tonic-gate if (len > MAXNETNAMELEN) { 3107c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 3117c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "user2netname: netname of '%s' too long", 3127c478bd9Sstevel@tonic-gate principal); 3137c478bd9Sstevel@tonic-gate nis_freeresult(nres); 3147c478bd9Sstevel@tonic-gate return (0); 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate (void) strncpy(netname, ENTRY_VAL(nres->objects.objects_val, 2), len); 3177c478bd9Sstevel@tonic-gate netname[len] = '\0'; 3187c478bd9Sstevel@tonic-gate nis_freeresult(nres); 3197c478bd9Sstevel@tonic-gate *err = __NSW_SUCCESS; 3207c478bd9Sstevel@tonic-gate return (1); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate #define MAXIPRINT (11) /* max length of printed integer */ 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * Convert unix cred to network-name by concatenating the 3277c478bd9Sstevel@tonic-gate * 3 pieces of information <opsys type> <uid> <domain>. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate static int 331*61961e0fSrobinson user2netname_nis(int *err, char netname[MAXNETNAMELEN + 1], uid_t uid, 332*61961e0fSrobinson char *domain) 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate int i; 3357c478bd9Sstevel@tonic-gate char *dfltdom; 3367c478bd9Sstevel@tonic-gate if (domain == NULL) { 3377c478bd9Sstevel@tonic-gate if (__rpc_get_default_domain(&dfltdom) != 0) { 3387c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 3397c478bd9Sstevel@tonic-gate return (0); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate domain = dfltdom; 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate if ((strlen(domain) + OPSYS_LEN + 3 + MAXIPRINT) > 3447c478bd9Sstevel@tonic-gate (size_t)MAXNETNAMELEN) { 3457c478bd9Sstevel@tonic-gate *err = __NSW_UNAVAIL; 3467c478bd9Sstevel@tonic-gate return (0); 3477c478bd9Sstevel@tonic-gate } 348*61961e0fSrobinson (void) snprintf(netname, MAXNETNAMELEN + 1, 349*61961e0fSrobinson "%s.%d@%s", OPSYS, (int)uid, domain); 3507c478bd9Sstevel@tonic-gate i = strlen(netname); 3517c478bd9Sstevel@tonic-gate if (netname[i-1] == '.') 3527c478bd9Sstevel@tonic-gate netname[i-1] = '\0'; 3537c478bd9Sstevel@tonic-gate *err = __NSW_SUCCESS; 3547c478bd9Sstevel@tonic-gate return (1); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * Figure out my fully qualified network name 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate int 361*61961e0fSrobinson getnetname(char name[MAXNETNAMELEN + 1]) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate uid_t uid; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate uid = geteuid(); 3667c478bd9Sstevel@tonic-gate if (uid == 0) 367*61961e0fSrobinson return (host2netname(name, NULL, NULL)); 368*61961e0fSrobinson return (user2netname(name, uid, NULL)); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate /* 3737c478bd9Sstevel@tonic-gate * Figure out the fully qualified network name for the given uid. 3747c478bd9Sstevel@tonic-gate * This is a private interface. 3757c478bd9Sstevel@tonic-gate */ 3767c478bd9Sstevel@tonic-gate int 377*61961e0fSrobinson __getnetnamebyuid(char name[MAXNETNAMELEN + 1], uid_t uid) 3787c478bd9Sstevel@tonic-gate { 3797c478bd9Sstevel@tonic-gate if (uid == 0) 380*61961e0fSrobinson return (host2netname(name, NULL, NULL)); 381*61961e0fSrobinson return (user2netname(name, uid, NULL)); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate /* 3857c478bd9Sstevel@tonic-gate * Convert unix cred to network-name 3867c478bd9Sstevel@tonic-gate * 3877c478bd9Sstevel@tonic-gate * It uses the publickey policy in the /etc/nsswitch.conf file 3887c478bd9Sstevel@tonic-gate * (Unless the netname is "nobody", which is special cased). 3897c478bd9Sstevel@tonic-gate * If there is no publickey policy in /etc/nsswitch.conf, 3907c478bd9Sstevel@tonic-gate * the default publickey policy is used, which is 3917c478bd9Sstevel@tonic-gate * publickey: nis [NOTFOUND=return] files 3927c478bd9Sstevel@tonic-gate * Note that for the non-nisplus case, there is no failover 3937c478bd9Sstevel@tonic-gate * so only the first entry would be relevant for those cases. 3947c478bd9Sstevel@tonic-gate */ 3957c478bd9Sstevel@tonic-gate int 396*61961e0fSrobinson user2netname(char netname[MAXNETNAMELEN + 1], const uid_t uid, 397*61961e0fSrobinson const char *domain) 3987c478bd9Sstevel@tonic-gate { 3997c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *conf; 4007c478bd9Sstevel@tonic-gate struct __nsw_lookup *look; 4017c478bd9Sstevel@tonic-gate int needfree = 1, res = 0; 4027c478bd9Sstevel@tonic-gate enum __nsw_parse_err perr; 4037c478bd9Sstevel@tonic-gate int err; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * Take care of the special case of "nobody". If the uid is 4077c478bd9Sstevel@tonic-gate * the value assigned by the SVID for nobody, return the string 4087c478bd9Sstevel@tonic-gate * "nobody". 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate if (uid == NOBODY_UID) { 4127c478bd9Sstevel@tonic-gate (void) strcpy(netname, "nobody"); 4137c478bd9Sstevel@tonic-gate return (1); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate netname[0] = '\0'; /* make null first (no need for memset) */ 4177c478bd9Sstevel@tonic-gate 418*61961e0fSrobinson (void) mutex_lock(&serialize_netname); 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate conf = __nsw_getconfig("publickey", &perr); 4217c478bd9Sstevel@tonic-gate if (!conf) { 4227c478bd9Sstevel@tonic-gate conf = &publickey_default; 4237c478bd9Sstevel@tonic-gate needfree = 0; 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate for (look = conf->lookups; look; look = look->next) { 4277c478bd9Sstevel@tonic-gate if (strcmp(look->service_name, "nisplus") == 0) 4287c478bd9Sstevel@tonic-gate res = user2netname_nisplus(&err, 4297c478bd9Sstevel@tonic-gate netname, uid, (char *)domain); 4307c478bd9Sstevel@tonic-gate /* ldap, nis, and files all do the same thing. */ 4317c478bd9Sstevel@tonic-gate else if (strcmp(look->service_name, "ldap") == 0 || 4327c478bd9Sstevel@tonic-gate strcmp(look->service_name, "nis") == 0 || 4337c478bd9Sstevel@tonic-gate strcmp(look->service_name, "files") == 0) 4347c478bd9Sstevel@tonic-gate res = user2netname_nis(&err, 4357c478bd9Sstevel@tonic-gate netname, uid, (char *)domain); 4367c478bd9Sstevel@tonic-gate else { 4377c478bd9Sstevel@tonic-gate syslog(LOG_INFO, 4387c478bd9Sstevel@tonic-gate "user2netname: unknown nameservice \ 4397c478bd9Sstevel@tonic-gate for publickey info '%s'\n", 4407c478bd9Sstevel@tonic-gate look->service_name); 4417c478bd9Sstevel@tonic-gate err = __NSW_UNAVAIL; 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate switch (look->actions[err]) { 4447c478bd9Sstevel@tonic-gate case __NSW_CONTINUE : 4457c478bd9Sstevel@tonic-gate break; 4467c478bd9Sstevel@tonic-gate case __NSW_RETURN : 4477c478bd9Sstevel@tonic-gate if (needfree) 4487c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 449*61961e0fSrobinson (void) mutex_unlock(&serialize_netname); 4507c478bd9Sstevel@tonic-gate return (res); 4517c478bd9Sstevel@tonic-gate default : 4527c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 4537c478bd9Sstevel@tonic-gate "user2netname: Unknown action for nameservice '%s'", 4547c478bd9Sstevel@tonic-gate look->service_name); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate if (needfree) 4587c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 459*61961e0fSrobinson (void) mutex_unlock(&serialize_netname); 4607c478bd9Sstevel@tonic-gate return (0); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate /* 4657c478bd9Sstevel@tonic-gate * Convert host to network-name 4667c478bd9Sstevel@tonic-gate * This routine returns following netnames given the host and domain 4677c478bd9Sstevel@tonic-gate * arguments defined below: (domainname=y.z) 4687c478bd9Sstevel@tonic-gate * Arguments 4697c478bd9Sstevel@tonic-gate * host domain netname 4707c478bd9Sstevel@tonic-gate * ---- ------ ------- 4717c478bd9Sstevel@tonic-gate * - - unix.m@y.z (hostname=m) 4727c478bd9Sstevel@tonic-gate * - a.b unix.m@a.b (hostname=m) 4737c478bd9Sstevel@tonic-gate * - - unix.m@y.z (hostname=m.w.x) 4747c478bd9Sstevel@tonic-gate * - a.b unix.m@a.b (hostname=m.w.x) 4757c478bd9Sstevel@tonic-gate * h - unix.h@y.z 4767c478bd9Sstevel@tonic-gate * h a.b unix.h@a.b 4777c478bd9Sstevel@tonic-gate * h.w.x - unix.h@w.x 4787c478bd9Sstevel@tonic-gate * h.w.x a.b unix.h@a.b 4797c478bd9Sstevel@tonic-gate */ 4807c478bd9Sstevel@tonic-gate int 481*61961e0fSrobinson host2netname(char netname[MAXNETNAMELEN + 1], const char *host, 482*61961e0fSrobinson const char *domain) 4837c478bd9Sstevel@tonic-gate { 4847c478bd9Sstevel@tonic-gate char *p; 4857c478bd9Sstevel@tonic-gate char hostname[MAXHOSTNAMELEN + 1]; 4867c478bd9Sstevel@tonic-gate char domainname[MAXHOSTNAMELEN + 1]; 4877c478bd9Sstevel@tonic-gate char *dot_in_host; 4887c478bd9Sstevel@tonic-gate int i; 4897c478bd9Sstevel@tonic-gate size_t len; 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate netname[0] = '\0'; /* make null first (no need for memset) */ 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate if (host == NULL) { 4947c478bd9Sstevel@tonic-gate (void) strncpy(hostname, nis_local_host(), sizeof (hostname)); 4957c478bd9Sstevel@tonic-gate p = (char *)strchr(hostname, '.'); 4967c478bd9Sstevel@tonic-gate if (p) { 4977c478bd9Sstevel@tonic-gate *p++ = '\0'; 4987c478bd9Sstevel@tonic-gate /* if no domain passed, use tail of nis_local_host() */ 4997c478bd9Sstevel@tonic-gate if (domain == NULL) { 5007c478bd9Sstevel@tonic-gate domain = p; 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate } else { 5047c478bd9Sstevel@tonic-gate len = strlen(host); 5057c478bd9Sstevel@tonic-gate if (len >= sizeof (hostname)) { 5067c478bd9Sstevel@tonic-gate return (0); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate (void) strcpy(hostname, host); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate dot_in_host = (char *)strchr(hostname, '.'); 5127c478bd9Sstevel@tonic-gate if (domain == NULL) { 5137c478bd9Sstevel@tonic-gate p = dot_in_host; 5147c478bd9Sstevel@tonic-gate if (p) { 5157c478bd9Sstevel@tonic-gate p = (char *)nis_domain_of(hostname); 5167c478bd9Sstevel@tonic-gate len = strlen(p); 5177c478bd9Sstevel@tonic-gate if (len >= sizeof (domainname)) { 5187c478bd9Sstevel@tonic-gate return (0); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate (void) strcpy(domainname, p); 5217c478bd9Sstevel@tonic-gate } else { 5227c478bd9Sstevel@tonic-gate domainname[0] = NULL; 5237c478bd9Sstevel@tonic-gate if (getdomainname(domainname, MAXHOSTNAMELEN) < 0) 5247c478bd9Sstevel@tonic-gate return (0); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate } else { 5277c478bd9Sstevel@tonic-gate len = strlen(domain); 5287c478bd9Sstevel@tonic-gate if (len >= sizeof (domainname)) { 5297c478bd9Sstevel@tonic-gate return (0); 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate (void) strcpy(domainname, domain); 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate i = strlen(domainname); 5357c478bd9Sstevel@tonic-gate if (i == 0) 5367c478bd9Sstevel@tonic-gate /* No domainname */ 5377c478bd9Sstevel@tonic-gate return (0); 5387c478bd9Sstevel@tonic-gate if (domainname[i - 1] == '.') 5397c478bd9Sstevel@tonic-gate domainname[i - 1] = 0; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (dot_in_host) { /* strip off rest of name */ 5427c478bd9Sstevel@tonic-gate *dot_in_host = '\0'; 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate if ((strlen(domainname) + strlen(hostname) + OPSYS_LEN + 3) 5467c478bd9Sstevel@tonic-gate > (size_t)MAXNETNAMELEN) { 5477c478bd9Sstevel@tonic-gate return (0); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 550*61961e0fSrobinson (void) snprintf(netname, MAXNETNAMELEN + 1, 551*61961e0fSrobinson "%s.%s@%s", OPSYS, hostname, domainname); 5527c478bd9Sstevel@tonic-gate return (1); 5537c478bd9Sstevel@tonic-gate } 554