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 26 #include <sys/types.h> 27 #include <project.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include "files_common.h" 31 32 static uint_t 33 hash_projname(nss_XbyY_args_t *argp, int keyhash, const char *line, 34 int linelen) { 35 36 const char *name; 37 int namelen, i; 38 uint_t hash = 0; 39 40 if (keyhash) { 41 name = argp->key.name; 42 namelen = strlen(name); 43 } else { 44 name = line; 45 namelen = 0; 46 while (linelen-- && *line++ != ':') 47 namelen++; 48 } 49 50 for (i = 0; i < namelen; i++) 51 hash = hash * 15 + name[i]; 52 return (hash); 53 } 54 55 static uint_t 56 hash_projid(nss_XbyY_args_t *argp, int keyhash, const char *line, 57 int linelen) { 58 59 uint_t id; 60 const char *linep, *limit, *end; 61 62 linep = line; 63 limit = line + linelen; 64 65 if (keyhash) 66 return ((uint_t)argp->key.projid); 67 68 /* skip projname */ 69 while (linep < limit && *linep++ != ':'); 70 if (linep == limit) 71 return (0); 72 73 /* projid */ 74 end = linep; 75 id = (uint_t)strtol(linep, (char **)&end, 10); 76 if (linep == end) 77 return (0); 78 79 return (id); 80 } 81 82 static files_hash_func hash_proj[2] = { 83 hash_projname, 84 hash_projid 85 }; 86 87 static files_hash_t hashinfo = { 88 DEFAULTMUTEX, 89 sizeof (struct project), 90 NSS_BUFLEN_PROJECT, 91 2, 92 hash_proj 93 }; 94 95 static int 96 check_projid(nss_XbyY_args_t *argp, const char *line, int linelen) { 97 projid_t projid; 98 const char *linep, *limit, *end; 99 100 linep = line; 101 limit = line + linelen; 102 103 /* skip projname */ 104 while (linep < limit && *linep++ != ':'); 105 106 /* empty projname not allowed */ 107 if (linep == limit || linep == line + 1) 108 return (0); 109 110 /* projid */ 111 end = linep; 112 projid = (projid_t)strtol(linep, (char **)&end, 10); 113 114 /* empty projid is not valid */ 115 if (linep == end) 116 return (0); 117 118 return (projid == argp->key.projid); 119 } 120 121 static nss_status_t 122 getbyname(files_backend_ptr_t be, void *a) { 123 return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, 124 _nss_files_check_name_colon)); 125 } 126 127 static nss_status_t 128 getbyprojid(files_backend_ptr_t be, void *a) { 129 return (_nss_files_XY_hash(be, a, 0, &hashinfo, 1, check_projid)); 130 } 131 132 static files_backend_op_t project_ops[] = { 133 _nss_files_destr, 134 _nss_files_endent, 135 _nss_files_setent, 136 _nss_files_getent_rigid, 137 getbyname, 138 getbyprojid 139 }; 140 141 /*ARGSUSED*/ 142 nss_backend_t * 143 _nss_files_project_constr(dummy1, dummy2, dummy3) 144 const char *dummy1, *dummy2, *dummy3; 145 { 146 return (_nss_files_constr(project_ops, 147 sizeof (project_ops) / sizeof (project_ops[0]), 148 PROJF_PATH, 149 NSS_LINELEN_PROJECT, 150 &hashinfo)); 151 } 152