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
_nss_ldap_proj2str(ldap_backend_ptr be,nss_XbyY_args_t * argp)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
getbyname(ldap_backend_ptr be,void * a)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
getbyprojid(ldap_backend_ptr be,void * a)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 *
_nss_ldap_project_constr(const char * dummy1,const char * dummy2,const char * dummy3)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