xref: /illumos-gate/usr/src/lib/nsswitch/ldap/common/getprojent.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2008 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			i;
70 	int			nss_result;
71 	int			buflen = 0, len;
72 	int			firsttime;
73 	char			*buffer, *comment, *attr_str;
74 	ns_ldap_result_t	*result = be->result;
75 	char			**name, **id, **descr, **attr;
76 	ns_ldap_attr_t		*users, *groups;
77 
78 	if (result == NULL)
79 		return (NSS_STR_PARSE_PARSE);
80 	buflen = argp->buf.buflen;
81 
82 	if (argp->buf.result != NULL) {
83 		/* In all cases it must be deallocated by caller */
84 		if ((be->buffer = calloc(1, buflen)) == NULL) {
85 			nss_result = NSS_STR_PARSE_PARSE;
86 			goto result_proj2str;
87 		}
88 		buffer = be->buffer;
89 	} else
90 		buffer = argp->buf.buffer;
91 
92 	nss_result = NSS_STR_PARSE_SUCCESS;
93 	(void) memset(buffer, 0, buflen);
94 
95 	name = __ns_ldap_getAttr(result->entry, _PROJ_NAME);
96 	if (name == NULL || name[0] == NULL || (strlen(name[0]) < 1)) {
97 		nss_result = NSS_STR_PARSE_PARSE;
98 		goto result_proj2str;
99 	}
100 	id = __ns_ldap_getAttr(result->entry, _PROJ_PROJID);
101 	if (id == NULL || id[0] == NULL || (strlen(id[0]) < 1)) {
102 		nss_result = NSS_STR_PARSE_PARSE;
103 		goto result_proj2str;
104 	}
105 	descr = __ns_ldap_getAttr(result->entry, _PROJ_DESCR);
106 	if (descr == NULL || descr[0] == NULL || (strlen(descr[0]) < 1))
107 		comment = _NO_VALUE;
108 	else
109 		comment = descr[0];
110 	len = snprintf(buffer, buflen, "%s:%s:%s:", name[0], id[0],
111 	    comment);
112 	TEST_AND_ADJUST(len, buffer, buflen, result_proj2str);
113 
114 	users = __ns_ldap_getAttrStruct(result->entry, _PROJ_USERS);
115 	if (!(users == NULL || users->attrvalue == NULL)) {
116 		firsttime = 1;
117 		for (i = 0; i < users->value_count; i++) {
118 			if (users->attrvalue[i] == NULL) {
119 				nss_result = NSS_STR_PARSE_PARSE;
120 				goto result_proj2str;
121 			}
122 			if (firsttime) {
123 				len = snprintf(buffer, buflen, "%s",
124 				    users->attrvalue[i]);
125 				firsttime = 0;
126 			} else {
127 				len = snprintf(buffer, buflen, ",%s",
128 				    users->attrvalue[i]);
129 			}
130 			TEST_AND_ADJUST(len, buffer, buflen, result_proj2str);
131 		}
132 	}
133 	len = snprintf(buffer, buflen, ":");
134 	TEST_AND_ADJUST(len, buffer, buflen, result_proj2str);
135 
136 	groups = __ns_ldap_getAttrStruct(result->entry, _PROJ_GROUPS);
137 	if (!(groups == NULL || groups->attrvalue == NULL)) {
138 		firsttime = 1;
139 		for (i = 0; i < groups->value_count; i++) {
140 			if (groups->attrvalue[i] == NULL) {
141 				nss_result = NSS_STR_PARSE_PARSE;
142 				goto result_proj2str;
143 			}
144 			if (firsttime) {
145 				len = snprintf(buffer, buflen, "%s",
146 				    groups->attrvalue[i]);
147 				firsttime = 0;
148 			} else {
149 				len = snprintf(buffer, buflen, ",%s",
150 				    groups->attrvalue[i]);
151 			}
152 			TEST_AND_ADJUST(len, buffer, buflen, result_proj2str);
153 		}
154 	}
155 
156 	attr = __ns_ldap_getAttr(result->entry, _PROJ_ATTR);
157 	if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1))
158 		attr_str = _NO_VALUE;
159 
160 	else
161 		attr_str = attr[0];
162 	len = snprintf(buffer, buflen, ":%s", attr_str);
163 	TEST_AND_ADJUST(len, buffer, buflen, result_proj2str);
164 
165 	/* The front end marshaller doesn't need the trailing nulls */
166 	if (argp->buf.result != NULL)
167 		be->buflen = strlen(be->buffer);
168 result_proj2str:
169 	(void) __ns_ldap_freeResult(&be->result);
170 	return ((int)nss_result);
171 }
172 
173 
174 /*
175  * getbyname gets a project entry by name. This function constructs an ldap
176  * search filter using the name invocation parameter and the getprojname search
177  * filter defined. Once the filter is constructed, we search for a matching
178  * entry and marshal the data results into struct project for the frontend
179  * process. The function _nss_ldap_proj2ent performs the data marshaling.
180  */
181 static nss_status_t
182 getbyname(ldap_backend_ptr be, void *a)
183 {
184 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
185 	char searchfilter[SEARCHFILTERLEN];
186 
187 	if (snprintf(searchfilter, SEARCHFILTERLEN,
188 	    _F_GETPROJNAME, argp->key.name) < 0)
189 		return (NSS_NOTFOUND);
190 	return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL, NULL,
191 	    NULL));
192 }
193 
194 
195 /*
196  * getbyprojid gets a project entry by number. This function constructs an ldap
197  * search filter using the name invocation parameter and the getprojid search
198  * filter defined. Once the filter is constructed, we search for a matching
199  * entry and marshal the data results into struct project for the frontend
200  * process. The function _nss_ldap_proj2ent performs the data marshaling.
201  */
202 static nss_status_t
203 getbyprojid(ldap_backend_ptr be, void *a)
204 {
205 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
206 	char searchfilter[SEARCHFILTERLEN];
207 
208 	if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETPROJID,
209 	    (long)argp->key.projid) < 0)
210 		return (NSS_NOTFOUND);
211 	return (_nss_ldap_lookup(be, argp, _PROJECT, searchfilter, NULL, NULL,
212 	    NULL));
213 }
214 
215 static ldap_backend_op_t project_ops[] = {
216 	_nss_ldap_destr,
217 	_nss_ldap_endent,
218 	_nss_ldap_setent,
219 	_nss_ldap_getent,
220 	getbyname,
221 	getbyprojid
222 };
223 
224 
225 /*ARGSUSED0*/
226 nss_backend_t *
227 _nss_ldap_project_constr(const char *dummy1, const char *dummy2,
228     const char *dummy3)
229 {
230 	return (_nss_ldap_constr(project_ops,
231 	    sizeof (project_ops) / sizeof (project_ops[0]),
232 	    _PROJECT, project_attrs, _nss_ldap_proj2str));
233 }
234