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
hash_projname(nss_XbyY_args_t * argp,int keyhash,const char * line,int linelen)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
hash_projid(nss_XbyY_args_t * argp,int keyhash,const char * line,int linelen)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
check_projid(nss_XbyY_args_t * argp,const char * line,int linelen)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
getbyname(files_backend_ptr_t be,void * a)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
getbyprojid(files_backend_ptr_t be,void * a)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 *
_nss_files_project_constr(dummy1,dummy2,dummy3)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