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