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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * files/getpwnam.c -- "files" backend for nsswitch "passwd" database 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <pwd.h> 31 #include <shadow.h> 32 #include <unistd.h> /* for PF_PATH */ 33 #include "files_common.h" 34 #include <strings.h> 35 #include <stdlib.h> 36 37 static uint_t 38 hash_pwname(nss_XbyY_args_t *argp, int keyhash, const char *line, 39 int linelen) 40 { 41 const char *name; 42 int namelen, i; 43 uint_t hash = 0; 44 45 if (keyhash) { 46 name = argp->key.name; 47 namelen = strlen(name); 48 } else { 49 name = line; 50 namelen = 0; 51 while (linelen-- && *line++ != ':') 52 namelen++; 53 } 54 55 for (i = 0; i < namelen; i++) 56 hash = hash * 15 + name[i]; 57 return (hash); 58 } 59 60 static uint_t 61 hash_pwuid(nss_XbyY_args_t *argp, int keyhash, const char *line, 62 int linelen) 63 { 64 uint_t id; 65 const char *linep, *limit, *end; 66 67 linep = line; 68 limit = line + linelen; 69 70 if (keyhash) 71 return ((uint_t)argp->key.uid); 72 73 /* skip username */ 74 while (linep < limit && *linep++ != ':'); 75 /* skip password */ 76 while (linep < limit && *linep++ != ':'); 77 if (linep == limit) 78 return (UID_NOBODY); 79 80 /* uid */ 81 end = linep; 82 id = (uint_t)strtol(linep, (char **)&end, 10); 83 84 /* empty uid */ 85 if (linep == end) 86 return (UID_NOBODY); 87 88 return (id); 89 } 90 91 static files_hash_func hash_pw[2] = { hash_pwname, hash_pwuid }; 92 93 static files_hash_t hashinfo = { 94 DEFAULTMUTEX, 95 sizeof (struct passwd), 96 NSS_BUFLEN_PASSWD, 97 2, 98 hash_pw 99 }; 100 101 static int 102 check_pwname(nss_XbyY_args_t *argp, const char *line, int linelen) 103 { 104 const char *linep, *limit; 105 const char *keyp = argp->key.name; 106 107 linep = line; 108 limit = line + linelen; 109 110 /* +/- entries valid for compat source only */ 111 if (linelen == 0 || *line == '+' || *line == '-') 112 return (0); 113 while (*keyp && linep < limit && *keyp == *linep) { 114 keyp++; 115 linep++; 116 } 117 return (linep < limit && *keyp == '\0' && *linep == ':'); 118 } 119 120 static nss_status_t 121 getbyname(be, a) 122 files_backend_ptr_t be; 123 void *a; 124 { 125 return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_pwname)); 126 } 127 128 static int 129 check_pwuid(nss_XbyY_args_t *argp, const char *line, int linelen) 130 { 131 const char *linep, *limit, *end; 132 uid_t pw_uid; 133 134 linep = line; 135 limit = line + linelen; 136 137 /* +/- entries valid for compat source only */ 138 if (linelen == 0 || *line == '+' || *line == '-') 139 return (0); 140 141 /* skip username */ 142 while (linep < limit && *linep++ != ':'); 143 /* skip password */ 144 while (linep < limit && *linep++ != ':'); 145 if (linep == limit) 146 return (0); 147 148 /* uid */ 149 end = linep; 150 pw_uid = (uid_t)strtol(linep, (char **)&end, 10); 151 152 /* empty uid is not valid */ 153 if (linep == end) 154 return (0); 155 156 return (pw_uid == argp->key.uid); 157 } 158 159 static nss_status_t 160 getbyuid(be, a) 161 files_backend_ptr_t be; 162 void *a; 163 { 164 return (_nss_files_XY_hash(be, a, 0, &hashinfo, 1, check_pwuid)); 165 } 166 167 static files_backend_op_t passwd_ops[] = { 168 _nss_files_destr, 169 _nss_files_endent, 170 _nss_files_setent, 171 _nss_files_getent_rigid, 172 getbyname, 173 getbyuid 174 }; 175 176 /*ARGSUSED*/ 177 nss_backend_t * 178 _nss_files_passwd_constr(dummy1, dummy2, dummy3) 179 const char *dummy1, *dummy2, *dummy3; 180 { 181 return (_nss_files_constr(passwd_ops, 182 sizeof (passwd_ops) / sizeof (passwd_ops[0]), 183 PF_PATH, 184 NSS_LINELEN_PASSWD, 185 &hashinfo)); 186 } 187