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