1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2009, Sun Microsystems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * - Neither the name of Sun Microsystems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #if defined(LIBC_SCCS) && !defined(lint) 32 static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro"; 33 #endif 34 /* 35 * netname utility routines convert from unix names to network names and 36 * vice-versa This module is operating system dependent! What we define here 37 * will work with any unix system that has adopted the sun NIS domain 38 * architecture. 39 */ 40 #include "namespace.h" 41 #include <sys/param.h> 42 #include <rpc/rpc.h> 43 #include <rpc/rpc_com.h> 44 #ifdef YP 45 #include <rpcsvc/yp_prot.h> 46 #include <rpcsvc/ypclnt.h> 47 #endif 48 #include <ctype.h> 49 #include <stdio.h> 50 #include <grp.h> 51 #include <pwd.h> 52 #include <string.h> 53 #include <stdlib.h> 54 #include <unistd.h> 55 #include "un-namespace.h" 56 57 static char *OPSYS = "unix"; 58 #ifdef YP 59 static char *NETID = "netid.byname"; 60 #endif 61 static char *NETIDFILE = "/etc/netid"; 62 63 static int getnetid( char *, char * ); 64 static int _getgroups( char *, gid_t [NGRPS] ); 65 66 /* 67 * Convert network-name into unix credential 68 */ 69 int 70 netname2user(char netname[MAXNETNAMELEN + 1], uid_t *uidp, gid_t *gidp, 71 int *gidlenp, gid_t *gidlist) 72 { 73 char *p; 74 int gidlen; 75 uid_t uid; 76 long luid; 77 struct passwd *pwd; 78 char val[1024]; 79 char *val1, *val2; 80 char *domain; 81 int vallen; 82 int err; 83 84 if (getnetid(netname, val)) { 85 char *res = val; 86 87 p = strsep(&res, ":"); 88 if (p == NULL) 89 return (0); 90 *uidp = (uid_t) atol(p); 91 p = strsep(&res, "\n,"); 92 if (p == NULL) { 93 return (0); 94 } 95 *gidp = (gid_t) atol(p); 96 for (gidlen = 0; gidlen < NGRPS; gidlen++) { 97 p = strsep(&res, "\n,"); 98 if (p == NULL) 99 break; 100 gidlist[gidlen] = (gid_t) atol(p); 101 } 102 *gidlenp = gidlen; 103 104 return (1); 105 } 106 val1 = strchr(netname, '.'); 107 if (val1 == NULL) 108 return (0); 109 if (strncmp(netname, OPSYS, (val1-netname))) 110 return (0); 111 val1++; 112 val2 = strchr(val1, '@'); 113 if (val2 == NULL) 114 return (0); 115 vallen = val2 - val1; 116 if (vallen > (1024 - 1)) 117 vallen = 1024 - 1; 118 (void) strncpy(val, val1, 1024); 119 val[vallen] = 0; 120 121 err = __rpc_get_default_domain(&domain); /* change to rpc */ 122 if (err) 123 return (0); 124 125 if (strcmp(val2 + 1, domain)) 126 return (0); /* wrong domain */ 127 128 if (sscanf(val, "%ld", &luid) != 1) 129 return (0); 130 uid = luid; 131 132 /* use initgroups method */ 133 pwd = getpwuid(uid); 134 if (pwd == NULL) 135 return (0); 136 *uidp = pwd->pw_uid; 137 *gidp = pwd->pw_gid; 138 *gidlenp = _getgroups(pwd->pw_name, gidlist); 139 return (1); 140 } 141 142 /* 143 * initgroups 144 */ 145 146 static int 147 _getgroups(char *uname, gid_t groups[NGRPS]) 148 { 149 gid_t ngroups = 0; 150 struct group *grp; 151 int i; 152 int j; 153 int filter; 154 155 setgrent(); 156 while ((grp = getgrent())) { 157 for (i = 0; grp->gr_mem[i]; i++) 158 if (!strcmp(grp->gr_mem[i], uname)) { 159 if (ngroups == NGRPS) { 160 #ifdef DEBUG 161 fprintf(stderr, 162 "initgroups: %s is in too many groups\n", uname); 163 #endif 164 goto toomany; 165 } 166 /* filter out duplicate group entries */ 167 filter = 0; 168 for (j = 0; j < ngroups; j++) 169 if (groups[j] == grp->gr_gid) { 170 filter++; 171 break; 172 } 173 if (!filter) 174 groups[ngroups++] = grp->gr_gid; 175 } 176 } 177 toomany: 178 endgrent(); 179 return (ngroups); 180 } 181 182 /* 183 * Convert network-name to hostname 184 */ 185 int 186 netname2host(char netname[MAXNETNAMELEN + 1], char *hostname, int hostlen) 187 { 188 int err; 189 char valbuf[1024]; 190 char *val; 191 char *val2; 192 int vallen; 193 char *domain; 194 195 if (getnetid(netname, valbuf)) { 196 val = valbuf; 197 if ((*val == '0') && (val[1] == ':')) { 198 (void) strncpy(hostname, val + 2, hostlen); 199 return (1); 200 } 201 } 202 val = strchr(netname, '.'); 203 if (val == NULL) 204 return (0); 205 if (strncmp(netname, OPSYS, (val - netname))) 206 return (0); 207 val++; 208 val2 = strchr(val, '@'); 209 if (val2 == NULL) 210 return (0); 211 vallen = val2 - val; 212 if (vallen > (hostlen - 1)) 213 vallen = hostlen - 1; 214 (void) strncpy(hostname, val, vallen); 215 hostname[vallen] = 0; 216 217 err = __rpc_get_default_domain(&domain); /* change to rpc */ 218 if (err) 219 return (0); 220 221 if (strcmp(val2 + 1, domain)) 222 return (0); /* wrong domain */ 223 else 224 return (1); 225 } 226 227 /* 228 * reads the file /etc/netid looking for a + to optionally go to the 229 * network information service. 230 */ 231 int 232 getnetid(char *key, char *ret) 233 { 234 char buf[1024]; /* big enough */ 235 char *res; 236 char *mkey; 237 char *mval; 238 FILE *fd; 239 #ifdef YP 240 char *domain; 241 int err; 242 char *lookup; 243 int len; 244 #endif 245 int rv; 246 247 rv = 0; 248 249 fd = fopen(NETIDFILE, "r"); 250 if (fd == NULL) { 251 #ifdef YP 252 res = "+"; 253 goto getnetidyp; 254 #else 255 return (0); 256 #endif 257 } 258 while (fd != NULL) { 259 res = fgets(buf, sizeof(buf), fd); 260 if (res == NULL) { 261 rv = 0; 262 goto done; 263 } 264 if (res[0] == '#') 265 continue; 266 else if (res[0] == '+') { 267 #ifdef YP 268 getnetidyp: 269 err = yp_get_default_domain(&domain); 270 if (err) { 271 continue; 272 } 273 lookup = NULL; 274 err = yp_match(domain, NETID, key, 275 strlen(key), &lookup, &len); 276 if (err) { 277 #ifdef DEBUG 278 fprintf(stderr, "match failed error %d\n", err); 279 #endif 280 continue; 281 } 282 lookup[len] = 0; 283 strcpy(ret, lookup); 284 free(lookup); 285 rv = 2; 286 goto done; 287 #else /* YP */ 288 #ifdef DEBUG 289 fprintf(stderr, 290 "Bad record in %s '+' -- NIS not supported in this library copy\n", 291 NETIDFILE); 292 #endif 293 continue; 294 #endif /* YP */ 295 } else { 296 mkey = strsep(&res, "\t "); 297 if (mkey == NULL) { 298 fprintf(stderr, 299 "Bad record in %s -- %s", NETIDFILE, buf); 300 continue; 301 } 302 do { 303 mval = strsep(&res, " \t#\n"); 304 } while (mval != NULL && !*mval); 305 if (mval == NULL) { 306 fprintf(stderr, 307 "Bad record in %s val problem - %s", NETIDFILE, buf); 308 continue; 309 } 310 if (strcmp(mkey, key) == 0) { 311 strcpy(ret, mval); 312 rv = 1; 313 goto done; 314 } 315 } 316 } 317 318 done: 319 if (fd != NULL) 320 fclose(fd); 321 return (rv); 322 } 323