1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * nis/getpwnam.c -- "nis" backend for nsswitch "passwd" database 26 */ 27 28 #include <pwd.h> 29 #include "nis_common.h" 30 31 static nss_status_t 32 getbyname(be, a) 33 nis_backend_ptr_t be; 34 void *a; 35 { 36 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 37 38 return (_nss_nis_lookup(be, argp, 0, 39 "passwd.byname", argp->key.name, 0)); 40 } 41 42 static nss_status_t 43 getbyuid(be, a) 44 nis_backend_ptr_t be; 45 void *a; 46 { 47 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 48 char uidstr[12]; /* More than enough */ 49 50 if (argp->key.uid > MAXUID) 51 return (NSS_NOTFOUND); 52 (void) snprintf(uidstr, 12, "%u", argp->key.uid); 53 return (_nss_nis_lookup(be, argp, 0, "passwd.byuid", uidstr, 0)); 54 } 55 56 /* 57 * Validates passwd entry replacing uid/gid > MAXUID by ID_NOBODY. 58 */ 59 int 60 validate_passwd_ids(char **linepp, int *linelenp, int allocbuf) 61 { 62 char *linep, *limit, *uidp, *gidp, *newline; 63 uid_t uid; 64 gid_t gid; 65 ulong_t uidl, gidl; 66 int olduidlen, oldgidlen, idlen; 67 int linelen = *linelenp, newlinelen; 68 69 linep = *linepp; 70 limit = linep + linelen; 71 72 /* +/- entries valid for compat source only */ 73 if (linelen == 0 || *linep == '+' || *linep == '-') 74 return (NSS_STR_PARSE_SUCCESS); 75 76 while (linep < limit && *linep++ != ':') /* skip username */ 77 continue; 78 while (linep < limit && *linep++ != ':') /* skip password */ 79 continue; 80 if (linep == limit) 81 return (NSS_STR_PARSE_PARSE); 82 83 uidp = linep; 84 uidl = strtoul(uidp, (char **)&linep, 10); /* grab uid */ 85 olduidlen = linep - uidp; 86 if (++linep >= limit || olduidlen == 0) 87 return (NSS_STR_PARSE_PARSE); 88 89 gidp = linep; 90 gidl = strtoul(gidp, (char **)&linep, 10); /* grab gid */ 91 oldgidlen = linep - gidp; 92 if (linep >= limit || oldgidlen == 0) 93 return (NSS_STR_PARSE_PARSE); 94 95 if (uidl <= MAXUID && gidl <= MAXUID) 96 return (NSS_STR_PARSE_SUCCESS); 97 uid = (uidl > MAXUID) ? UID_NOBODY : (uid_t)uidl; 98 gid = (gidl > MAXUID) ? GID_NOBODY : (gid_t)gidl; 99 100 /* Check if we have enough space in the buffer */ 101 idlen = snprintf(NULL, 0, "%u:%u", uid, gid); 102 newlinelen = linelen + idlen - olduidlen - oldgidlen - 1; 103 if (newlinelen > linelen) { 104 /* need a larger buffer */ 105 if (!allocbuf || (newline = malloc(newlinelen + 1)) == NULL) 106 return (NSS_STR_PARSE_ERANGE); 107 /* Replace ephemeral ids by ID_NOBODY in the new buffer */ 108 *(uidp - 1) = '\0'; 109 (void) snprintf(newline, newlinelen + 1, "%s:%u:%u%s", 110 *linepp, uid, gid, linep); 111 free(*linepp); 112 *linepp = newline; 113 *linelenp = newlinelen; 114 return (NSS_STR_PARSE_SUCCESS); 115 } 116 117 /* Replace ephemeral ids by ID_NOBODY in the same buffer */ 118 (void) bcopy(linep, uidp + idlen, limit - linep + 1); 119 (void) snprintf(uidp, idlen + 1, "%u:%u", uid, gid); 120 *(uidp + idlen) = ':'; /* restore : that was overwritten by snprintf */ 121 *linelenp = newlinelen; 122 return (NSS_STR_PARSE_SUCCESS); 123 } 124 125 static nis_backend_op_t passwd_ops[] = { 126 _nss_nis_destr, 127 _nss_nis_endent, 128 _nss_nis_setent, 129 _nss_nis_getent_rigid, 130 getbyname, 131 getbyuid 132 }; 133 134 /*ARGSUSED*/ 135 nss_backend_t * 136 _nss_nis_passwd_constr(dummy1, dummy2, dummy3) 137 const char *dummy1, *dummy2, dummy3; 138 { 139 return (_nss_nis_constr(passwd_ops, 140 sizeof (passwd_ops) / sizeof (passwd_ops[0]), 141 "passwd.byname")); 142 } 143