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