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 <project.h>
29 #include "ldap_common.h"
30 
31 /* Project attributes filters */
32 #define	_PROJ_NAME	"SolarisProjectName"
33 #define	_PROJ_PROJID	"SolarisProjectID"
34 #define	_PROJ_DESCR	"description"
35 #define	_PROJ_USERS	"memberUid"
36 #define	_PROJ_GROUPS	"memberGid"
37 #define	_PROJ_ATTR	"SolarisProjectAttr"
38 
39 #define	_F_GETPROJNAME	"(&(objectClass=SolarisProject)(SolarisProjectName=%s))"
40 #define	_F_GETPROJID	"(&(objectClass=SolarisProject)(SolarisProjectID=%ld))"
41 
42 static const char *project_attrs[] = {
43 	_PROJ_NAME,
44 	_PROJ_PROJID,
45 	_PROJ_DESCR,
46 	_PROJ_USERS,
47 	_PROJ_GROUPS,
48 	_PROJ_ATTR,
49 	(char *)NULL
50 };
51 
52 /*
53  * _nss_ldap_proj2str is the data marshalling method for the project getXbyY
54  * (getprojbyname, getprojbyid, getprojent) backend processes. This method
55  * is called after a successful ldap search has been performed. This method
56  * will parse the ldap search values into the file format.
57  * e.g.
58  *
59  * system:0:System:::
60  *
61  * beatles:100:The Beatles:john,paul,george,ringo::task.max-lwps=
62  * 	(privileged,100,signal=SIGTERM),(privileged,110,deny)
63  *
64  * (All in one line)
65  */
66 static int
67 _nss_ldap_proj2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
68 {
69 	int nss_result, buflen;
70 	unsigned long len = 0;
71 	char *buffer, *comment, *user_str, *group_str, *attr_str;
72 	ns_ldap_result_t *result = be->result;
73 	char **name, **id, **descr, **users, **groups, **attr;
74 
75 	if (result == NULL)
76 		return (NSS_STR_PARSE_PARSE);
77 	buflen = argp->buf.buflen;
78 
79 	nss_result = NSS_STR_PARSE_SUCCESS;
80 	(void) memset(argp->buf.buffer, 0, buflen);
81 
82 	name = __ns_ldap_getAttr(result->entry, _PROJ_NAME);
83 	if (name == NULL || name[0] == NULL || (strlen(name[0]) < 1)) {
84 		nss_result = NSS_STR_PARSE_PARSE;
85 		goto result_proj2str;
86 	}
87 	id = __ns_ldap_getAttr(result->entry, _PROJ_PROJID);
88 	if (id == NULL || id[0] == NULL || (strlen(id[0]) < 1)) {
89 		nss_result = NSS_STR_PARSE_PARSE;
90 		goto result_proj2str;
91 	}
92 	descr = __ns_ldap_getAttr(result->entry, _PROJ_DESCR);
93 	if (descr == NULL || descr[0] == NULL || (strlen(descr[0]) < 1))
94 		comment = _NO_VALUE;
95 
96 	else
97 		comment = descr[0];
98 
99 	users = __ns_ldap_getAttr(result->entry, _PROJ_USERS);
100 	if (users == NULL || users[0] == NULL || (strlen(users[0]) < 1))
101 		user_str = _NO_VALUE;
102 
103 	else
104 		user_str = users[0];
105 
106 	groups = __ns_ldap_getAttr(result->entry, _PROJ_GROUPS);
107 	if (groups == NULL || groups[0] == NULL || (strlen(groups[0]) < 1))
108 		group_str = _NO_VALUE;
109 
110 	else
111 		group_str = groups[0];
112 
113 	attr = __ns_ldap_getAttr(result->entry, _PROJ_ATTR);
114 	if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1))
115 		attr_str = _NO_VALUE;
116 
117 	else
118 		attr_str = attr[0];
119 
120 	/* 6 = 5 ':' + 1 '\0' */
121 	len = strlen(name[0]) + strlen(id[0]) + strlen(comment) +
122 		strlen(user_str) + strlen(group_str) + strlen(attr_str) + 6;
123 	if (len >= buflen) {
124 		nss_result = NSS_STR_PARSE_ERANGE;
125 		goto result_proj2str;
126 	}
127 	if (argp->buf.result != NULL) {
128 		if ((be->buffer = calloc(1, len)) == NULL) {
129 			nss_result = NSS_STR_PARSE_PARSE;
130 			goto result_proj2str;
131 		}
132 		buffer = be->buffer;
133 		/* The front end marshaller does not need trailing nulls */
134 		be->buflen = len - 1;
135 	} else
136 		buffer = argp->buf.buffer;
137 
138 	(void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s", name[0], id[0],
139 			comment, user_str, group_str, attr_str);
140 
141 result_proj2str:
142 	(void) __ns_ldap_freeResult(&be->result);
143 	return ((int)nss_result);
144 }
145 
146 
147 /*
148  * getbyname gets a project entry by name. This function constructs an ldap
149  * search filter using the name invocation parameter and the getprojname search
150  * filter defined. Once the filter is constructed, we search for a matching
151  * entry and marshal the data results into struct project for the frontend
152  * process. The function _nss_ldap_proj2ent performs the data marshaling.
153  */
154 static nss_status_t
155 getbyname(ldap_backend_ptr be, void *a)
156 {
157 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
158 	char searchfilter[SEARCHFILTERLEN];
159 
160 	if (snprintf(searchfilter, SEARCHFILTERLEN,
161 		_F_GETPROJNAME, argp->key.name) < 0)
162 		return (NSS_NOTFOUND);
163 	return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL,
164 			NULL, NULL));
165 }
166 
167 
168 /*
169  * getbyprojid gets a project entry by number. This function constructs an ldap
170  * search filter using the name invocation parameter and the getprojid search
171  * filter defined. Once the filter is constructed, we search for a matching
172  * entry and marshal the data results into struct project for the frontend
173  * process. The function _nss_ldap_proj2ent performs the data marshaling.
174  */
175 static nss_status_t
176 getbyprojid(ldap_backend_ptr be, void *a)
177 {
178 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
179 	char searchfilter[SEARCHFILTERLEN];
180 
181 	if (snprintf(searchfilter, SEARCHFILTERLEN,
182 		_F_GETPROJID, (long)argp->key.projid) < 0)
183 		return (NSS_NOTFOUND);
184 	return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL,
185 			NULL, NULL));
186 }
187 
188 static ldap_backend_op_t project_ops[] = {
189 	_nss_ldap_destr,
190 	_nss_ldap_endent,
191 	_nss_ldap_setent,
192 	_nss_ldap_getent,
193 	getbyname,
194 	getbyprojid
195 };
196 
197 
198 /*ARGSUSED0*/
199 nss_backend_t *
200 _nss_ldap_project_constr(const char *dummy1, const char *dummy2,
201     const char *dummy3)
202 {
203 	return (_nss_ldap_constr(project_ops,
204 	    sizeof (project_ops) / sizeof (project_ops[0]),
205 	    _PROJECT, project_attrs, _nss_ldap_proj2str));
206 }
207