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